-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started
bunx create-ultimate myapp && cd myapp && x dev
Nothing to install first. No Docker daemon, no .env scavenger hunt, no service to provision.
✓ postgres embedded, migrated, seeded 420ms
✓ nats in-process 2ms
✓ storage ./.x/storage (S3 API) 1ms
✓ roles web sync worker scheduler replicator (one process, isolated)
✓ site/ 12 routes static 0kb js
✓ app/ 3 routes stream
✓ mcp ws://localhost:9229
http://localhost:3000 → landing page (site/)
http://localhost:3000/app → dashboard (app/)
http://localhost:3000/_x → dev dashboard
ready in 1.1s
| Thing | Where | Detail |
|---|---|---|
| Embedded Postgres | .x/pg |
downloaded once, migrated, seeded; no local install |
| In-process NATS | same process | identical API to JetStream in prod |
| S3 | ./.x/storage |
real S3 API surface via Bun.s3
|
/_x inbox |
captured, never sent | |
| Redis (cache tier 3) | in-process map | same interface as Bun.redis
|
| MCP dev server | ws://localhost:9229 |
routes, schema, policies, tests, logs, read-only SQL |
/_x dev panel |
http://localhost:3000/_x |
routes, schema, queries, live, jobs, cache, mail, errors, traces, AI, env, boundaries |
| Landing page | apps/web/site/ |
static, 0kb JS, real meta + JSON-LD |
| Dashboard | apps/web/app/ |
stream, auth'd |
| Admin app | apps/admin/ |
already exposes MCP over your actions |
| Green gate | x verify |
17 steps, in this order: typecheck, lint, boundaries, filesize, package-shape, errors, unit, contract, live, job, e2e, eval, drift, contract-diff, budgets, manifest, roadmap |
x dev runs every role in one process with isolation simulated, not skipped: separate ALS contexts, a real Postgres queue, real logical replication, a real SIGTERM drain on x dev restart. Nothing in the framework branches on if (dev) — only the drivers differ.
x g action publish-post
export const publishPost = action({
input: t.object({ postId: t.uuid, notify: t.boolean.default(true) }),
output: PostView,
policy: can('post:publish', ({ input, actor }) => ownsPost(actor, input.postId)),
cache: { invalidates: [tag.post, tag.feed] },
mcp: { expose: true, description: 'Publish a draft post' },
async handle({ input, ctx }) {
const post = await ctx.posts.publish(input.postId);
if (input.notify) await notifySubscribers.enqueue({ postId: post.id });
return post;
},
});That one declaration emits six artifacts — HTTP route, OpenAPI operation, typed client function, job handle, MCP tool, test scaffold. See Actions.
app/ may import api/ types only. The typed client is derived from those types; there is no codegen step to remember and no fetch.
// apps/web/shared/client.ts
import { createClient } from '@ultimat3/action';
import type * as actions from '../api/posts/actions';
export const api = createClient<typeof actions>({ baseUrl: '/' });// apps/web/app/posts/ui/publish-button.tsx
import { api } from '../../../shared/client';
import { t as translate } from '@ultimat3/i18n';
import type { PostView } from '@myapp/domain';
export function PublishButton(props: { post: PostView }) {
const publish = async (): Promise<void> => {
await api.publishPost({ postId: props.post.id, notify: true });
};
return (
<button type="button" onClick={publish}>
{translate('post.publish')}
</button>
);
}Rename postId in the action and this file fails typecheck. One rename, N errors, all real work.
Point any MCP client at the dev socket printed by x dev.
claude mcp add ultimate --transport ws ws://localhost:9229
The agent now sees publishPost as a tool with JSON Schema from input, the description from mcp.description, and the action's own policy as its authorization — unwrapped, identical to the HTTP path. A denial is the same code in all three encodings:
{ "code": "X_FORBIDDEN", "cause": "actor user_2 lacks post:publish on post_9",
"fix": "grant post:publish to the actor's role, or call as the post owner",
"docs": "https://ultimate.dev/errors/X_FORBIDDEN" }Introspection an agent should use instead of grepping:
| Want | Command | MCP tool |
|---|---|---|
| every action + schemas | x actions list --json |
actions.list |
| one action in detail | x actions describe publishPost --json |
actions.list |
| is this protected | x policy explain publishPost --json |
policies.list |
| the whole app as data | x manifest --json |
manifest.get |
what an X_* code means |
x errors explain X_FORBIDDEN |
errors.explain |
One command. Green means shippable.
$ x verify
✓ typecheck ✓ lint ✓ boundaries ✓ filesize ✓ package-shape ✓ errors
✓ unit ✓ contract ✓ live ✓ job ✓ e2e ✓ eval
✗ drift
X_DB_DRIFT: schema differs from migrations
cause: table "posts" has column "publish_at" not present in any migration
fix: x db gen "add publish_at"
x verify --json emits the same content machine-readably. CI runs exactly x verify — a check that lives only in CI is a check you cannot run.
| Page | Read it for |
|---|---|
| Installation | prerequisites, x new flags, typed env, MCP client setup |
| Project layout | the generated tree, surfaces, the site/ → app/ boundary |
| The eight primitives | the whole conceptual surface, in eight lines |
| Actions | every field, all six projections, introspection |
| Entities and migrations | schema, drift, branch DBs |
| Policies and authz | one authz system, tenancy, denials |
| Queries and live queries | reads, live: true
|
| Jobs and workflows | durable steps, idempotency |
| Routes and render modes |
static / isr / ssr / stream / spa
|
| Testing | six test types, DB-clone parallelism |
| CLI reference | every command, every --json
|
| Error codes | code → cause → fix |
| Troubleshooting | first-run failures |
v1.0.0 As of 2026-08. Stable API — semver from here (Upgrading). 27 @ultimat3/* packages plus the unscoped create-ultimate — 28 in all — publish at 1.0.0 in lockstep. Milestones 0–10 are ✅; milestone 11 is 🚧, open on its two-platform deploy proof. Realtime tiers 1–2 are v1, tier 3 (local-first) is v2. No realtime benchmark is published — the 50k-socket forced-restart number is still unmeasured, so topology is not frozen. Status markers come from docs/idea/14-roadmap.md. See FAQ.
Ultimate — v1.1.0 As of 2026-08. Stable API, semver from here. MIT licensed.
Repository · Issues · Changelog · llms.txt
Edits to these pages are synced from wiki/ in the repository — change the file there, not the wiki, or the next sync overwrites it.
Start
Tutorials
- 1 · First app
- 2 · First feature
- 3 · Auth and admin
- 4 · Jobs and realtime
- 5 · Deploy free
- 6 · Growing up
Primitives
- The eight primitives
- Actions
- Entities and migrations
- Policies and authz
- Queries and live queries
- Jobs and workflows
- Scheduled tasks
- Routes and render modes
Capabilities
Cross-cutting
Reference