The kernel

Everything your next product stands on

A platform, not a pile of examples: a kernel of infrastructure seams and system modules that gives every feature tenancy, permissions, an audit trail, realtime, background work, and an AI assistant — before you write your first module.

Five things you don't have to build

  • Multi-tenant by construction

    Organization scoping lives in the procedure ladder, the cache keys, the object keys, and the job queue — not in per-feature if statements.

  • Architecture enforced by machines

    The layering, module isolation, and vendor fences are lint rules and tests. Conventions fail CI, not code review.

  • AI-native, twice

    The product ships an assistant whose tools are your endpoints. The workflow ships isolated stacks and deterministic checks for AI coding agents.

  • Writes that account for themselves

    Every mutation runs in a transaction, writes its audit rows, and publishes its events — one protocol no endpoint can skip.

  • One runtime

    Bun is the package manager, the dev server, the worker, and the test runner. There is no Node in the loop.

Modules plug in. The kernel provides.

A module is one directory holding a domain's tables, contracts, endpoints, screens, jobs, and events. It registers into a handful of typed registries and imports nothing but the kernel.

  • A verb grid, not boilerplate

    Create, update, archive, delete, live lists — every endpoint shape derives its schemas, method, errors, and OpenAPI metadata from your resource schema.

  • One declaration, three surfaces

    The same procedure serves the typed client, the public REST API, and the AI assistant — permission check, transaction, audit, and events included.

  • No module imports another

    Domains cooperate through the typed event bus, the kernel, or the app shell. The rule has no exceptions, and the linter enforces it.

procedures/project-create-one.ts
export const projectCreateOneProcedure = defineCreateOneProcedure({
  base: organizationPermissionProcedure("project.manage"),
  resource: { type: "project", event: "project.created", schema: ProjectSchema },
  openapi: { path: "/projects", summary: "Create a project" },
  tool: { description: "Create a project in one of the user's…" },
  values: ProjectValuesSchema,
  handler: async ({ deps, context, input }) => projectCreateOne(deps, {
    organizationId: context.organization.id,
    values: input.values,
  }),
});

A real endpoint from the reference project module — permission gate, REST path, and assistant tool in one declaration.

Identity & tenancy

The B2B basics, with the edge cases handled.

  • Passwordless sign-in

    Email one-time codes on Better Auth, stored hashed, with the vendor's raw endpoints closed in favor of audited procedures.

  • Organizations & invitations

    URL-scoped tenancy, hashed invitation tokens, member caps, and ownership transfer with a last-owner guard.

  • Roles where nothing is free

    A member holds exactly the union of their roles. Modules declare permissions; organizations compose them into roles in a built-in screen.

  • Sessions you can see

    A device list with per-session revoke and sign-out-everywhere-else — every revocation on the record.

  • API keys

    Hashed machine credentials with expiry, rate limits, and quotas. The secret is shown exactly once.

  • A platform admin tier

    A deployment-level admin area with a global audit view and a push console — invisible to regular users.

API & data

Typed end to end — from the database row to the React component to public REST.

  • One typed API

    oRPC and valibot carry types from Postgres to useQuery. During SSR the server calls itself in-process — no HTTP hop.

  • OpenAPI when you want it

    A procedure joins the documented REST surface by declaring a path — with generated reference docs and try-it authentication.

  • Lists that scale

    Keyset cursor pagination with typed, injection-safe filters — identical across every module.

  • The mutation protocol

    Transaction, audit rows, and domain events are one protocol inside the mutation engine — they cannot drift apart.

  • Postgres conventions

    Time-sortable UUIDv7 keys, archive-versus-delete semantics, race-safe unique indexes, and checked-in migrations.

  • Fail-fast configuration

    Each module declares its environment as a schema; boot validates every slice and reports everything missing at once.

Realtime & background work

Live screens and durable jobs with no extra infrastructure.

  • Live queries

    Declare a procedure as live and the screen updates over SSE on every relevant change. No websocket server, no polling.

  • Streams that survive the tab

    Long-running work publishes chunks with a replayable head — close the tab mid-answer and reattach later.

  • Jobs in your own Postgres

    pg-boss queues with retries, backoff, cron, and per-tenant fairness — enqueued inside the same transaction as your rows.

  • A second process, wired safely

    The worker asserts at boot that every declared job has a handler, and shuts down in a fixed, graceful order.

  • Wake plus reconcile

    Events wake jobs for latency; cron sweeps re-derive the outcome, so a missed event delays work instead of losing it.

  • Tabs that let go

    Backgrounded tabs release their live connections after a grace period — realtime that scales past a demo.

Platform services

The features every product needs eventually, already wired.

  • Files & uploads

    Direct-to-storage uploads with server-side verification, WebP thumbnails, tenant-prefixed keys, and a reaper for orphans.

  • The notification inbox

    Everything a person is told lands as a row here; email and push are mirrors the row's own type asks for. A per-type matrix switches the mirrors, never the record.

  • Transactional email

    react-email templates with a themed component kit, localized copy, and a local preview server.

  • Web push

    VAPID notifications with device management, dead-subscription pruning, and an admin broadcast console.

  • A forensic audit trail

    Actor, request, IP, session — and whether a human or the assistant made the change — recorded inside the mutation's transaction.

  • Search modules extend

    Each module registers its searchable resources into one command palette — reusing its own endpoints, so its own permissions answer every query.

  • Audit entries modules author

    A module declares how each of its events reads in the log, keyed to its own event types — an unknown key is a compile error.

  • Compiled i18n

    Paraglide compiles messages for server and client alike — English and Croatian ship with full parity.

  • An installable PWA

    Manifest, icons, a push-capable service worker, and a new-version toast tied to the deployed commit.

The AI assistant

Not a chatbot bolted on — a surface your modules teach.

  • Built like production

    Turns run as background jobs with resumable streams — answers keep arriving after the tab closes.

  • Your endpoints are its tools

    One tool block on a procedure exposes it to the model through the full middleware chain — same permissions, same audit trail.

  • Answers as UI

    Modules bind tool output to prepared views, so the assistant renders tables and cards instead of prose.

  • Gated by construction

    A tool without a permission rung cannot exist, admin surfaces refuse tools outright, and assistant-made changes are labeled in the audit trail.

Built for AI-agent development

The second product: a development harness agents cannot drift in.

  • The import graph is law

    Layering, module isolation, and vendor SDK fences are lint rules — every restriction with a message explaining why.

  • Tests for what lint can't see

    Structure tests catch stray files, missing barrels, and unregistered modules; the env test catches unvalidated configuration.

  • Hermetic E2E & visual regression

    One command builds the production images, boots the full stack in Docker, and pixel-diffs the screens.

  • Parallel agent stacks

    Every git worktree gets its own origin, database, cache, and object store — agents never share cookies or data.

  • Local HTTPS with h2

    A one-command mkcert proxy gives every instance a port-free https origin and removes the SSE connection cap.

  • A checked-in agent contract

    CLAUDE.md carries the non-negotiables, the settled decisions, and the exact checks CI runs.

On the roadmap

Tracked in the open and shipped in phases — the next layers of the platform.

  • Billing & usage limits
  • Feature flags
  • Schedulers
  • PDF & Excel exports
  • Usage analytics
  • WebSocket transport

Build your first module today

Sign in, open the reference modules, and ship a vertical slice with tenancy, audit, realtime, and an assistant already underneath it.

Get started