diff --git a/docs/usuba.md b/docs/usuba.md
new file mode 100644
index 000000000..dc9a0ca63
--- /dev/null
+++ b/docs/usuba.md
@@ -0,0 +1,41 @@
+## Local Usuba Setup
+
+Install some environment dependencies:
+
+```sh
+cargo install wit-deps-cli wasm-tools
+rustup target add wasm32-wasi wasm32-unknown-unknown
+
+npm install -g @bytecodealliance/jco
+npm install -g @bytecodealliance/componentize-js
+
+pip install componentize-py
+```
+
+On a Mac, also do this also:
+
+```sh
+brew install wget gsed
+```
+
+Set up an NPM project (using whatever stack) in `/typescript/packages` and add `@commontools/runtime` to your dependencies:
+
+```sh
+mkdir -p ./typescript/packages/my-project
+cd ./typescript/packages/my-project
+
+# Actually, better to copy a package.json from another package
+echo '{"type": "module"}' > ./package.json
+npm install --save @commontools/runtime
+```
+
+Get a web server going and note the `PORT` it is running on.
+
+In another terminal, get `usuba` running:
+
+```sh
+cd ./rust/usuba
+UPSTREAM=localhost:$PORT cargo run --bin usuba
+```
+
+Open your browser to http://localhost:8080. You should see whatever you would expect to see from the first web server you started.
diff --git a/rust/usuba/src/bake/javascript.rs b/rust/usuba/src/bake/javascript.rs
index 70decac21..01d70c70c 100644
--- a/rust/usuba/src/bake/javascript.rs
+++ b/rust/usuba/src/bake/javascript.rs
@@ -61,6 +61,14 @@ impl Bake for JavaScriptBaker {
debug!(?workspace, "Populated temporary input files");
+ Command::new("cp")
+ .arg("-r")
+ .arg(format!("{}", workspace.path().display()))
+ .arg("/tmp/failed")
+ .spawn()?
+ .wait()
+ .await?;
+
let mut command = Command::new("jco");
command
diff --git a/typescript/common/.gitignore b/typescript/common/.gitignore
new file mode 100644
index 000000000..1aa628036
--- /dev/null
+++ b/typescript/common/.gitignore
@@ -0,0 +1 @@
+deps
\ No newline at end of file
diff --git a/typescript/common/data/.gitignore b/typescript/common/data/.gitignore
new file mode 100644
index 000000000..e8310385c
--- /dev/null
+++ b/typescript/common/data/.gitignore
@@ -0,0 +1 @@
+src
\ No newline at end of file
diff --git a/typescript/common/data/package.json b/typescript/common/data/package.json
new file mode 100644
index 000000000..2964cf027
--- /dev/null
+++ b/typescript/common/data/package.json
@@ -0,0 +1,119 @@
+{
+ "name": "@commontools/data",
+ "author": "The Common Authors",
+ "version": "0.0.1",
+ "description": "",
+ "license": "UNLICENSED",
+ "private": true,
+ "type": "module",
+ "files": [
+ "./lib/**/*"
+ ],
+ "exports": {
+ ".": {
+ "types": "./lib/index.d.ts",
+ "default": "./lib/index.js"
+ },
+ "./interfaces/common-data-types.js": {
+ "types": "./lib/interfaces/common-data-types.js"
+ }
+ },
+ "scripts": {
+ "build": "wireit",
+ "clean": "wireit",
+ "update:wit": "wireit",
+ "lint:wit": "wireit",
+ "build:wit": "wireit"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/commontoolsinc/labs.git"
+ },
+ "bugs": {
+ "url": "https://github.com/commontoolsinc/labs/issues"
+ },
+ "homepage": "https://github.com/commontoolsinc/labs#readme",
+ "dependencies": {},
+ "devDependencies": {
+ "@bytecodealliance/jco": "^1.2.4",
+ "typescript": "^5.2.2",
+ "wireit": "^0.14.4"
+ },
+ "wireit": {
+ "install:wit": {
+ "command": "wit-deps",
+ "files": [
+ "./wit/deps.*"
+ ],
+ "output": [
+ "./wit/deps/**/*"
+ ]
+ },
+ "lint:wit": {
+ "dependencies": [
+ "install:wit"
+ ],
+ "command": "wasm-tools component wit ./wit",
+ "files": [
+ "./wit/**/*"
+ ]
+ },
+ "update:wit": {
+ "command": "wit-deps update",
+ "files": [
+ "./wit/deps.toml"
+ ],
+ "output": [
+ "./wit/deps.lock",
+ "./wit/deps/**/*"
+ ]
+ },
+ "build:jco": {
+ "dependencies": [
+ "install:wit",
+ "lint:wit"
+ ],
+ "command": "jco types -o ./lib --name index ./wit",
+ "files": [
+ "./wit/**/*"
+ ],
+ "output": [
+ "./lib/**/*"
+ ]
+ },
+ "build:wit:index": {
+ "dependencies": [
+ "build:jco"
+ ],
+ "command": "cat ./wit/*.wit | ./scripts/generate-wit-module.sh > ./lib/index.js",
+ "files": [
+ "./scripts/generate-wit-module.sh",
+ "./wit/*.wit"
+ ]
+ },
+ "build:wit:types": {
+ "dependencies": [
+ "build:jco"
+ ],
+ "command": "echo 'export const wit: string;' >> ./lib/index.d.ts",
+ "files": [
+ "./lib/index.d.ts"
+ ]
+ },
+ "build:wit": {
+ "dependencies": [
+ "build:wit:index",
+ "build:wit:types"
+ ]
+ },
+ "build": {
+ "dependencies": [
+ "build:jco",
+ "build:wit"
+ ]
+ },
+ "clean": {
+ "command": "rm -rf ./src ./lib ./.wireit"
+ }
+ }
+}
\ No newline at end of file
diff --git a/typescript/common/data/scripts b/typescript/common/data/scripts
new file mode 120000
index 000000000..e62fc5c53
--- /dev/null
+++ b/typescript/common/data/scripts
@@ -0,0 +1 @@
+../module/scripts
\ No newline at end of file
diff --git a/typescript/common/data/tsconfig.json b/typescript/common/data/tsconfig.json
new file mode 100644
index 000000000..d40c067b9
--- /dev/null
+++ b/typescript/common/data/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "lib": ["es2022", "DOM", "DOM.Iterable"],
+ "outDir": "./lib",
+ "rootDir": "./src",
+ },
+ "include": [
+ "src/**/*",
+ ]
+}
diff --git a/typescript/common/data/wit/data.wit b/typescript/common/data/wit/data.wit
new file mode 100644
index 000000000..9ea0cd565
--- /dev/null
+++ b/typescript/common/data/wit/data.wit
@@ -0,0 +1,33 @@
+package common:data@0.0.1;
+
+interface types {
+ resource reference {
+ // Dereference a reference to a value
+ // This call is fallible (for example, if the dereference is not allowed)
+ // The value may be none (for example, if it is strictly opaque)
+ deref: func() -> result