Installation
One command scaffolds a new ayjnt project. The prerequisites are Bun, a Cloudflare account, and about three minutes.
Prerequisites
Bun 1.1 or newer
ayjnt is Bun-first: the CLI is a Bun script, bundling uses Bun.build, and several core APIs (Bun.file, Bun.Glob, Bun.write) run under the hood.
Install from bun.com/install:
curl -fsSL https://bun.com/install | bashVerify:
bun --version # 1.1.0 or laternpm install ayjnt),
but bunx ayjnt and the CLI itself assume Bun is on the PATH. The library exports work fine under any runtime
that understands ESM.
Cloudflare account with Workers enabled
You'll need a free Cloudflare account to deploy. Local dev works
without signing in; wrangler deploy will prompt you to wrangler login the first time. Durable Objects require a
paid Workers plan (or the Workers Free plan's limited DO beta —
check the
Cloudflare DO docs
for the current policy).
Scaffold a project
bunx ayjnt new my-app # minimal template: one agent, no UI
bunx ayjnt new my-app --with-ui # with a React UI (counter example)
The minimal template gives you a single ChatAgent
that accepts POST requests and stores messages in DO state. The
with-ui template adds app.tsx next to the agent and
wires up a live-syncing React counter.
What got created
my-app/
├── agents/
│ └── chat/agent.ts # (or counter/ with --with-ui)
├── package.json # scripts: dev, build, deploy, migrate
├── tsconfig.json # paths set up for @ayjnt/env and @ayjnt/*
└── .gitignoreInstall dependencies
cd my-app && bun install
This pulls ayjnt, the Cloudflare agents SDK, wrangler, and (for the with-ui
template) react and react-dom.
Run locally
bun run dev
This does an initial codegen pass, writes .ayjnt/dist/wrangler.jsonc and .ayjnt/dist/entry.ts, then spawns wrangler dev pointed at the generated config. You'll
see:
✓ ayjnt: 1 agent(s) → .ayjnt/dist/wrangler.jsonc
⎔ Listening on http://localhost:8787From another terminal:
curl -X POST http://localhost:8787/chat/room-1 \
-H "content-type: application/json" \
-d '{"text":"hello"}'
# → { "ok": true, "count": 1 }
curl http://localhost:8787/chat/room-1
# → { "instance": "room-1", "messages": [...] }
Every path segment after /chat/ is a separate Durable
Object with its own state. /chat/room-1 and /chat/room-2 are independent.
Deploy
bun run deploy ayjnt deploy runs a preflight: your git tree must be
clean, in sync with origin/<branch>, and
migrations.json must not be staged for changes. If those pass, it
shells out to wrangler deploy pointed at the generated
config. First deploy will prompt you to wrangler login.
ayjnt build does the same codegen without
pushing. Inspect .ayjnt/dist/entry.ts and wrangler.jsonc to see exactly what wrangler will upload.
Adding ayjnt to an existing project
If you already have a Bun project and want to add ayjnt:
-
bun add agents wrangler— the SDK and the deploy CLI, both peer-ish deps. -
bun add -d ayjnt— ayjnt itself (dev dep; its CLI is what you'll invoke). -
Add scripts to
package.json:{ "scripts": { "dev": "ayjnt dev", "build": "ayjnt build", "deploy": "ayjnt deploy", "migrate": "ayjnt migrate" } } -
Create
agents/<your-agent>/agent.tswith a default-exported class extendingAgent. -
Update your
tsconfig.jsonso@ayjnt/envand@ayjnt/*resolve (see Co-located UI for the exact paths config). - Run
bun run dev.
ayjnt new exists to automate exactly this setup. Doing
it by hand is supported but rarely worth it.