Everything you need to ship your next SaaS
Authentication, organizations, internationalization, and a type-safe stack — wired up and ready, so you can focus on your product instead of the plumbing.
Everything you need, nothing you don't
A curated foundation with the tools every SaaS needs on day one.
Authentication built in
One-time codes out of the box, with verification and suspension flows already handled.
Organizations & roles
Multi-tenant from day one, with invitations and role-based access control.
Ready for the world
Type-safe internationalization with compile-time checked messages in every locale.
End-to-end type safety
A fully typed API layer from server to client — refactor without fear.
Modern UI kit
Accessible components styled with Tailwind CSS, dark mode included.
Transactional emails
Polished email templates for sign-in, invitations, and product updates.
An AI assistant, built in
A chat assistant that calls your permission-checked endpoints as tools — tenant-scoped, streaming, with every action on the record.
Background jobs & live data
Durable jobs in your own Postgres and screens that update live over SSE — no extra queue, no websocket server.
An audit trail for free
Every write records who did what, from where — inside the same transaction. Compliance is a property, not a feature.
A kernel underneath, modules on top
Your product is a set of vertical-slice modules. The kernel underneath provides what every feature needs — tenancy, permissions, audit, jobs, realtime, files, and an AI assistant.
One direction of dependency
The app imports modules, modules import the kernel, and nothing imports back. The linter enforces it.
Declare, don't wire
A procedure declares its permission, its REST path, and its assistant tool in one place — the kernel derives the rest.
Guardrails that fail CI
Import fences, structure tests, and boot-time checks catch architectural drift before anyone reviews a line.
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,
}),
});From clone to production
Three steps between you and your first deployment.
- 1
Clone and configure
Grab the repository, set your environment variables, and start the dev server with a single command.
- 2
Make it yours
Rename the brand, adjust the theme, and start building the features only you can build.
- 3
Ship it
Deploy anywhere containers run — production images and compose files are included.