@impetik/xeer
v0.2.33
Published
Xeer: a framework for building and shipping full-stack apps. Typed server, reactive client, database, auth, tests, one-command deploy.
Maintainers
Readme
Xeer
A framework for building and shipping full-stack apps.
Xeer gives you a typed server, a reactive client, a database, authentication, and a test runner that already know about each other — then puts the whole thing on a real URL with one command. No bundler to configure, no database to provision, no CI to write.
📖 Documentation: docs.xeer.run
npx @impetik/xeer new my-app
cd my-app && npm install
npx xeer dev # local server, instant feedback
npx xeer test # the suite that ships with your app
npx xeer deploy # a real URL on a global edge networkQuickstart
1. Create an app
npx @impetik/xeer new my-app
cd my-app
npm installNothing to install first. npm install then puts Xeer in the project, so npx xeer <command> resolves
the local copy, and npm run dev / npm test work for anyone who clones the repository.
Keep the scope. A bare
npx xeerlooks for a package literally namedxeer, which is not this one, andnpx xis an unrelated package entirely. Want it on yourPATH?npm install --global @impetik/xeer, then drop thenpxfrom everything below.
xeer new writes a complete working notes app: a manifest, a typed server, a client, styles, and
a passing test suite. --template notes|todo|blog|personal-site starts from another bundled starter, a
per-user task list, a blog that is public to read and private to write, or a static personal site with no
database at all. --ui <preact|react> picks the renderer, Preact by default; the scaffolded sources are
the same either way. What differs is the manifest, the paths table in tsconfig.json that tells your
editor which renderer those sources mean, and one line of the README. Every template checks, tests, and
builds clean under either provider, and none scaffolds sign-in UI. Any other exact --template value
is looked up in the public catalog. Xeer verifies the downloaded archive before it writes the target;
catalog templates own their renderer, so they do not accept --ui.
The live catalog has four Xeer applications (atelier, orario, piazza, tavola) and two
SvelteKit landing pages (lumen-studio, northstar-saas). A catalog result reports its
projectKind, optional framework, platformVersion, and artifactVersion. It does not report
ui, because the template owns its renderer.
--framework sveltekit|astro is the other axis, and writes the other kind of project this CLI runs:
a SvelteKit or Astro app on the Cloudflare adapter, declaring xeer.config.json instead of
xeer.app.json. Run npm install in it first — the framework commands delegate to its own package
scripts, and Xeer reads the lockfile your install writes, so pnpm, yarn, and bun work the same
way. Neither --template nor --ui applies there. To adopt a project you already have, run
xeer init in it instead. The SvelteKit scaffold uses the SvelteKit 3 RC on Vite 8 and includes a
remote query the starter page can refresh from the browser; the Astro scaffold is a server-output
Astro 7 site with a Container API test.
--template emdash is the bundled EmDash CMS blog: the Astro framework project with EmDash on D1
and R2, written offline and declaring integration: "emdash" so deployment computes the site URL
and xeer bootstrap opens the owner-only setup wizard. It takes no --ui.
2. Run it
npx xeer devYour client and server run together locally, with a real database and a verified identity for every request — no account, no network, no sign-in screen. Client edits hot-reload; server edits recompile behind a health check.
Add "budgets": { "liveConnections": 100 } to xeer.app.json, then open two windows: add a note in
one and it appears in the other immediately. Pushing a write to other people's clients is opt-in,
because a held-open stream keeps your app resident for as long as a tab is open.
3. Test it
npx xeer testBuilds the app, boots it with fresh isolated state, type-checks every tests/**/*.ts module, and
runs the registered tests as alice, bob, carol, or guest. These are four distinct
application identities, so ownership is asserted rather than assumed.
4. Deploy it
npx xeer auth login # opens a browser, prints a confirmation code
npx xeer deploy # prints your app's URLOr ship to a side-by-side URL first, then promote the exact bundle you looked at:
npx xeer deploy --environment preview
npx xeer promote --receipt review_… # deploy prints the complete idThe programming model
An app is a manifest that declares what it has, a server of typed functions, and a client that reads them and re-renders when they change.
xeer.app.json declares the shape of everything:
{
"format": "xeer.application-source.v0",
"name": "notes",
"entrypoints": { "client": "src/client.tsx", "server": "src/server.ts" },
"database": {
"tables": {
"notes": {
"fields": {
"text": { "type": "string", "maxLength": 500 },
"ownerId": { "type": "string", "maxLength": 128 }
},
"indexes": { "by_owner": ["ownerId"] }
}
}
},
"capabilities": ["database"]
}A capability is a power the app opts into by name, alongside a config block for it — database for
the typed database above, storage for a per-app object store reached as ctx.storage. Declaring one
without the other is an error in both directions, and an undeclared capability simply does not exist in
your app: there is nothing bound and nothing to reach for.
→ docs.xeer.run/guides/capabilities
src/server.ts — ctx.db is typed from that manifest, and ctx.auth is the verified identity of the
caller, never something the browser asserted:
import { defineServer, mutation, query } from '@impetik/xeer/server';
export default defineServer({
queries: {
'notes.list': query({
input: {},
handler: (ctx) => ctx.db.table('notes').find({ where: { ownerId: ctx.auth.appUserId } }),
}),
},
mutations: {
'notes.create': mutation({
input: { text: 'string' },
handler: (ctx, input) => ctx.db.table('notes').insert({
text: input.text,
ownerId: ctx.auth.appUserId,
}),
}),
},
});src/client.tsx — useQuery knows the operation's input and output types from the server above. It
also knows which tables the query read, so a write to one of them re-renders this component. Nobody
wired that up:
import { useMutation, useQuery, useState } from '@impetik/xeer/client';
export default function App() {
const notes = useQuery('notes.list', {});
const createNote = useMutation('notes.create');
const [text, setText] = useState('');
return (
<main>
<input value={text} onInput={(event) => setText(event.currentTarget.value)} />
<button onClick={() => void createNote({ text }).then(() => setText(''))}>Add</button>
{notes.loading && <p>Loading…</p>}
<ul>{(notes.data ?? []).map((note) => <li key={note.id}>{note.text}</li>)}</ul>
</main>
);
}What comes with it
- Live updates in one manifest line. Queries record what they read, mutations report what they wrote,
and open clients refetch only what changed. Declare
budgets.liveConnectionsto push those refreshes to other people's clients. → docs.xeer.run/guides/live-updates - A database and an object store, declared not provisioned. No connection string, no bucket name, no credential — and local development gets both for real. → docs.xeer.run/guides/capabilities
- Identity before the first request. Every visitor gets a verified, stable identity with no sign-in screen — and authorization is declared in the data layer, so a table owned-per-user stays that way for every read and write. → docs.xeer.run/guides/auth
- A test runner in the box. No framework to choose, no harness to build. → docs.xeer.run/guides/testing
- Preview, promote, roll back. Content-addressed builds, so shipping exactly what you reviewed is mechanical. → docs.xeer.run/guides/deploy
- Secrets that stay secret. Client code cannot import server code, and the compiler enforces it. → docs.xeer.run/guides/env
- Machine-readable end to end.
--jsonon every command, stable diagnostic codes with suggested repairs, and an MCP server. → docs.xeer.run/guides/agents
Requirements
- Node.js
>=22.12.0. The CLI checks at startup and prints a clear error otherwise. - A Xeer account to deploy. Xeer is in closed beta, so accounts are currently by invitation.
Bundled starters and local commands need no account or network. Catalog-backed
xeer newreadstemplates.xeer.run;xeer dev,xeer test,xeer build, andxeer previewrun entirely on your machine. See docs.xeer.run/faq.
Package name: this is published as
@impetik/xeerbecause npm's anti-typosquatting check rejected the unscoped namexeer. The installed command is still justxeer.
Commands
xeer new [directory] [--template <id>] scaffold an offline starter, the emdash blog, or a catalog id
xeer new [directory] --framework <f> scaffold a framework project instead (sveltekit, astro)
xeer init [directory] initialize an existing SvelteKit or Astro project
xeer check [directory] validate the manifest and analyse the source
xeer dev [directory] run locally, with instant feedback
xeer tunnel <port|loopback-url> expose a loopback HTTP server through the relay
xeer test [directory] run the application's own test suite
xeer build [directory] produce a content-addressed artifact
xeer preview [directory] run that exact artifact locally
xeer doctor [directory] diagnose this machine
xeer diagnostics XE#### explain one diagnostic code
xeer agent setup | context install adapters or inspect a project contract
xeer docs search <query> search the documentation bundled with this version
xeer auth login | status | logout sign in to deploy
xeer auth as <alice|bob|carol> | clear pick the local development persona
xeer token create | ls | revoke manage non-interactive service credentials
xeer deploy [--environment preview] ship it
xeer promote --receipt review_… make the reviewed preview version live
xeer rollback <artifactId> put a previous version back
xeer deployments deployment history
xeer disable | enable | delete take an app offline, or destroy it
xeer link point this checkout at an app you own
xeer domains add | ls | status | remove manage custom hostnames
xeer env set | ls | rm | pull environment values and secrets
xeer inspect | state | logs read a running app (--environment preview selects that slot)
xeer state reset reset one local state store with confirmation
xeer export | import move state in and out (deployed export selects an environment)
xeer db tables | schema | exec inspect or query a running local database
xeer actions print the versioned action and safety catalogueEvery command accepts --json, which emits a structured envelope (or, for the long-running commands, a
stream of newline-delimited events) suitable for driving Xeer from a program rather than a terminal.
xeer actions --json enumerates every canonical CLI and MCP action, including actions deliberately
hidden from human help, with effects, safety properties, prerequisites, path policy, and MCP exclusion
reasons.
Full reference, option by option: docs.xeer.run/reference/cli.
Troubleshooting
xeer: command not foundafter a global install — check that your npm global bin directory is onPATH(npm config get prefix, then look in<prefix>/bin), or usenpx --package=@impetik/xeer -- xeerinstead.npx xeer …doesn't work — the package is@impetik/xeer, notxeer. Usenpx --package=@impetik/xeer -- xeerorpnpm dlx @impetik/xeer.- Unsupported Node.js version — install Node.js
>=22.12.0;xeer doctorreports what you have. Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)on Windows after a command finishes — a Node.js bug in process exit (nodejs/node#56645), fixed in Node.js 24.20.0. The command's work completed; the crash only replaces its exit code. Upgrade to Node.js 24.20.0 or newer.xeer devorxeer buildcannot find its runtime — npm 11 and newer block native install scripts by default. Runnpm approve-scripts esbuild workerdin your project, or install globally withnpm install -g --allow-scripts=workerd,esbuild @impetik/xeer.xeer doctornames the dependency that failed to resolve.- Anything with an
XE####code — look it up at docs.xeer.run/reference/diagnostics, or runxeer <command> --jsonfor the machine-readable form with a file, a span, and a suggested repair.
Links
- Documentation — docs.xeer.run
- Quickstart — docs.xeer.run/quickstart
- FAQ — docs.xeer.run/faq
- Source and issues — github.com/impetik/xeer
License
MIT
