# AOZUMI Fold

Fold is an npm package and CLI (`@aozumi/fold`) for building a small full-stack TypeScript app and publishing it to `https://<name>.aozumi.site` in about a second, with no account.

A fold is one directory: `server/` (database schema, queries, mutations, actions, HTTP endpoints), `client/` (Preact and Tailwind), and `shared/` (pure TypeScript used by both). The CLI scaffolds it, runs it locally, and deploys it.

## Build an app with an agent

This section is for an AI agent that was told something like "I want to build a habit tracker using docs.aozumi.dev/fold". Follow these steps in order.

### 1. Create the fold

```sh
npx @aozumi/fold new habit-tracker
cd habit-tracker
```

Use a short lowercase name. It becomes the directory name, the app title, and the first choice for the subdomain. `new` writes a working todo starter, `AGENTS.md`, `CLAUDE.md`, a favicon, and a git repository with one commit. Do not run `npm install`. Fold apps have no dependencies to install.

### 2. Read AGENTS.md

Read `AGENTS.md` in the new directory before you change any file. It lists the rules the build enforces. The starter in `server/index.ts` and `client/index.tsx` shows every pattern you need: a table with an index, a per-user query, a mutation, an endpoint, guest auth, Google sign-in, and client routes.

### 3. Write the app

- `server/index.ts`: export `default fold({ name, schema, queries, mutations, actions, endpoints })`. Import only from `@aozumi/fold/server` and relative files. See [Fold API](/fold/fold-api/) and [Database](/fold/database/).
- `client/index.tsx`: export a component named `App`. Use `createClient<typeof app>()` for typed hooks. Import from `@aozumi/fold/client`, `preact`, `preact/hooks`, and relative files. See [Client](/fold/client/).
- `shared/`: plain TypeScript helpers, such as validation, used by both sides. No DOM, no Node, no env.
- Style with complete Tailwind class names in JSX. Do not add CSS files or a build step.
- If several people share the same data (a household list, a poll, a team board), follow [Sharing data by link](/fold/sharing/). Data filtered by `userId` is private to one browser.

Replace the todo starter. Keep the parts you need (auth gate, router) and delete the rest.

### 4. Run it locally and check it

Start the dev server in a terminal that can stay open:

```sh
npx @aozumi/fold dev
```

It prints `fold running at http://localhost:3000` and rebuilds when files change. Open the URL it prints and use the app. If another program already uses that port, `dev` warns and prints a `http://127.0.0.1:<port>` address instead; use that one, or pick another `--port`. From a second terminal:

```sh
npx @aozumi/fold logs --port 3000
npx @aozumi/fold db dump --port 3000
```

Fix every build error and runtime error before you deploy. Local data resets when the dev server restarts.

### 5. Check the anonymous rules

The dev server allows things an anonymous deploy rejects, such as `fetch` in server code. Check before deploying:

```sh
npx @aozumi/fold build --target anonymous
```

If it prints `Build failed`, fix each listed problem. See [Limits](/fold/limits/).

### 6. Deploy

```sh
npx @aozumi/fold deploy --json
```

The JSON has `url` (the live app), `claimUrl` (the claim link), `expiresAt`, and `limits`. Without `--json`, the CLI prints `App:`, `Expires:`, and a `Claim:` command; `npx @aozumi/fold claim --json` prints the claim link later.

To update the app, run `npx @aozumi/fold deploy` again from the same directory. The URL and the data stay the same, and the expiry moves to 7 days from that deploy. The CLI keeps the deploy ID and claim token in `.fold/deploy.json`. Do not delete that file and do not commit it (`.fold/` is in the starter `.gitignore`).

### 7. Check the live URL

Open `url` and test what the user asked for. Call your endpoints with `curl`. App pages answer only requests that accept HTML, so check a page path with `curl -H 'Accept: text/html' <url>`; a plain `curl` of a page path gets 404. Hosted logs, `inspect`, and `db` commands are coming soon, so check behavior through the app itself. If a request fails, the response body is JSON with an `error` message.

### 8. Hand it to the user

Give the user:

- the live URL,
- the claim link, sent only to the user,
- the expiry date, and that each redeploy extends it by 7 days.

The claim link contains a secret token. Anyone who has it can replace the app. Do not post it in public places, commit it, or put it in the app. Claiming a fold into an AOZUMI account is coming soon; today the claim page shows the app URL and its expiry.

### Rules that matter most

Allowed in an anonymous fold:

- Tables, indexes, queries, mutations, actions, and HTTP endpoints.
- Live queries: open pages update when data changes.
- Guest sessions (automatic) and Google sign-in.
- Client routing, Tailwind classes, a favicon.

Rejected or not available in an anonymous fold:

- `fetch` anywhere in `server/` or `shared/` code. Outbound fetch needs a claimed deploy, which is coming soon.
- Values in `.env.fold.server`. Server env needs a claimed deploy. In an anonymous deploy `ctx.env` is empty.
- `while` loops, `for (;;)` loops, `setTimeout`, `setInterval`, `eval`, `new Function`, dynamic `import()`, `globalThis`, `process`, and `node:` imports in server and shared code.
- npm packages and Node built-ins anywhere in the app.
- Legacy database calls: `where()`, `orderBy()`, `limit()`, `all()`.
- File storage (`client.storage`) when hosted. It works only in local dev for now.
- A deploy over 1 MB, more than 1 MB of stored data, more than 10,000 requests or 1,000 mutations per day.

Unclaimed folds stop serving 7 days after their last deploy.

## Pages

- [Fold API](/fold/fold-api/): `fold()`, schema, queries, mutations, actions, endpoints, `ctx`.
- [Database](/fold/database/): `insert`, `get`, `update`, `delete`, `withIndex`, ranges, `order`, `take`, `first`, `collect`, `count`, `paginate`, dashboard counts.
- [Schema changes](/fold/database-migration/): what a redeploy does to existing data.
- [Sharing data by link](/fold/sharing/): lists, polls and boards that several people open with one unguessable link.
- [Auth](/fold/auth/): guests, `requireIdentity`, Google sign-in, per-app user IDs.
- [Storage](/fold/storage/): the upload API, local only for now.
- [Client](/fold/client/): `createClient`, hooks, live updates, routing.
- [Limits](/fold/limits/): every anonymous limit, its error, and the fix.
- [CLI](/fold/cli/): commands that work today and commands that are coming soon.
- [Reference](/fold/reference/): every export of every package entry point.

## Try it

Give an agent a prompt like this:

```txt
I want to build a shared grocery list my roommates can use from their phones, using docs.aozumi.dev/fold.
```

Other prompts that fit Fold well:

```txt
I want to build a reading log where I sign in with Google and track books, using docs.aozumi.dev/fold.
I want to build a team standup board with one card per person per day, using docs.aozumi.dev/fold.
```

The agent creates the fold, builds and tests it locally, deploys it, and sends you the live URL and a private claim link.
