advanced

a type-only model

Importing lexicons.ts pulls the schema library and all your field definitions into the bundle, because validation needs them. To avoid that, use model: record type names only, with the types coming from a pure import type that has no impact on your bundle.

import type lexicons from './lexicons.ts'
import { defineCollection, model } from 'airspace'

const lex = model<typeof lexicons>('dev.roe')
export const notes = defineCollection(lex.note)

The trade-off is that nothing is validated on the client, scopesFor cannot see your blob fields, so you will need to add blob:*/* yourself, and singletons will be enforced in types only. The rest of these docs assume validation is on.

workers and other edge runtimes

airspace, airspace/lexicon, airspace/live and the plugins bundle for Cloudflare Workers, Deno and the browser, with no Node built-ins in the graph. Handle lookups import node:dns dynamically, falling back to DNS over HTTPS elsewhere.

airspace/oauth will not bundle: @atproto/oauth-client-node needs node:crypto, node:net and node:dns. Run the OAuth handshake on Node, or use @atproto/oauth-client-browser and pass the resulting session to createAirspace.

bundle size

Minified and gzipped, measured by pnpm size. Lazy chunks load only when spaces, blobs.upload() or passwordSession() are used.

Importairspace onlywith runtime deps
airspace9.2 kB (+5.5 kB lazy)36.2 kB (+10.5 kB lazy)
airspace/lexicon3.3 kB22.7 kB
airspace/live0.7 kB0.7 kB
airspace/oauth0.7 kB0.7 kB
airspace/plugins/markdown0.3 kB0.3 kB
airspace/plugins/timestamps0.2 kB0.2 kB