Resources that are clients
KV, D1, R2, queues, Durable Objects, Workflows, AI, Vectorize and more,
each a class you yield* for a typed, Effect-returning client.
A D1 database, and a Worker that reads it. That’s a whole app:
class Book extends D1.Database<Book>()('book', { migrations: ['CREATE TABLE entries (id INTEGER PRIMARY KEY, name TEXT, message TEXT, at TEXT)'],}) {}
const fetch = Effect.gen(function* () { const book = yield* Book; // a typed D1 client const entries = yield* book.all('SELECT name, message FROM entries ORDER BY id DESC'); return Response.json(entries);}).pipe(Effect.orDie);
export default Worker.make('guestbook', { fetch }).bind(Book);Book is two things at once: the client your code uses, and the
declaration of the database it needs. Forget the .bind(Book) and
nothing deploys half-wired. You’re stopped before you ship:
$ infra check app.tserror used-undeclared guestbook.ts:14:16 the Worker uses Book, which it doesn't bind fix: bind it: .bind(…, Book)Your editor says the same, as you type: it’s a type error.
And when it’s right, one command makes the database, applies its migrations, uploads the Worker and checks it answers:
$ infra ship app.ts 2.01s ✓ created D1 database guestbook-book 2.47s ✓ applied migration 1 to D1 database guestbook-book 3.68s ✓ created Worker guestbook-guestbook, live 8.16s ✓ smoke test passed: 3 × GET /, answered by the new Worker 8.51s ✓ shipped guestbook-guestbook: https://guestbook-guestbook.you.workers.devResources that are clients
KV, D1, R2, queues, Durable Objects, Workflows, AI, Vectorize and more,
each a class you yield* for a typed, Effect-returning client.
Wiring the compiler checks
A Worker must bind what its code uses. Calls between Workers are typed at both ends. Mistakes show up in your editor, not in production.
Deploys that undo themselves
infra ship provisions, migrates, rolls out 10% → 50% → 100% behind
smoke tests, and puts everything back if any step fails, or you press
Ctrl-C.
Tests without mocks
Every resource has an in-memory stand-in, D1 runs on SQLite, and
infra dev runs your whole app in workerd, wired as it deploys.