Skip to content

What's included

Everything the kit already does, so you don’t build it twice. Each line links to the page that explains it, or names the file when the code is the explanation.

What Read more
Email and password, with a verified address required Auth
Sign-in links by email, valid for 5 minutes Auth
Google and GitHub, each on once you add its two values Sign-in providers
The same address through Google or GitHub joins the existing account Sign-in providers
Forgot and reset password; a reset ends every other session Auth
A new verification link whenever someone unverified tries to sign in, and a “Send it again” button apps/web/src/routes/check-email.tsx
People are returned to the page they wanted after signing in Security
Profile: change name, email (confirmed in both inboxes) and password Auth
“Sign out of my other devices” when changing a password apps/web/src/features/account/password-form.tsx
Devices: every session with its browser and system, and sign out of the others apps/web/src/features/account/sessions-list.tsx
Connect or disconnect Google and GitHub, never the last way in apps/web/src/features/account/sign-in-methods.tsx
People who never set a password can ask for a link to set one apps/web/src/features/account/password-form.tsx
Delete account, with the password or the typed address Auth
A welcome email, once per person Auth
Limits on sign-in attempts in production Auth
What Read more
Personal accounts or teams, chosen with one setting, with no data to migrate later Workspaces
Isolation between workspaces: guards for who gets in, queries for what comes back Workspaces
Owner, admin and member roles Workspaces
Invitations by email, valid for 7 days, with accept and decline screens Workspaces
Seat limits per plan; a pending invitation holds a seat Workspaces
A workspace switcher that reopens the last workspace you used apps/web/src/features/workspaces
Members page: invite, change roles, remove, leave, cancel invitations apps/web/src/routes/_authenticated/w.$slug/settings/members.tsx
Workspace settings: rename, change the address, delete by typing its name apps/web/src/routes/_authenticated/w.$slug/settings/workspace.tsx
API keys for programs: a role each, an expiry, a rate limit, shown once Auth
Deleting a workspace cancels its subscription first Billing
What Read more
Plans written once in code; the API, billing page, pricing page and provider follow Charge for a feature
Stripe, or Polar as merchant of record handling sales tax and VAT, chosen with one setting Polar
billing:sync creates and updates products and prices in Stripe or Polar, and says whether it is in test or live mode Stripe
No price ids in your environment: prices are found by a key such as pro_month Stripe
Monthly and yearly prices, flat or per seat Charge for a feature
Usage-based billing: an allowance a month on each plan, then a price per unit, metered at Stripe or Polar Charge for usage
Checkout, with promotion codes accepted Billing
The provider’s customer portal for cards, invoices, plan changes and cancelling Stripe
Webhooks that are verified, safe to receive twice and safe out of order Billing
A failed payment keeps the plan while the provider retries, then drops to free Billing
Per-seat bills follow the team as people join and leave, prorated Billing
A receipt email for every payment, with a link to the invoice Billing
@RequireFeature() in the API and <RequireFeature> on screen, with an upgrade prompt Charge for a feature
The billing page waits for the payment to confirm, then says so apps/web/src/routes/_authenticated/w.$slug/settings/billing.tsx
Everything works without a payment provider’s key: every workspace is on the free plan Billing
billing:listen forwards webhooks to your machine without stripe login Stripe
What Read more
Eight emails: verify, welcome, sign-in link, reset password, change email, invitation, receipt, contact message apps/api/src/mail/templates
Each sent as HTML and as plain text, from one layout with your colour Send email
A live preview of every template Send email
Sent through the queue: retried for about 2 hours when your provider is down Email provider
Sent only if the change is saved, and only once Send email
Any SMTP provider; a local inbox that catches everything while you develop Email provider
What Read more
BullMQ on Redis, fed from an outbox in Postgres Background jobs
Payloads checked against a schema when queued and again when run Background jobs
Queue inside a transaction, once per key, or for later Background jobs
Retries that wait longer each time, from 15 seconds up to an hour Background jobs
A job whose worker died is picked up again by BullMQ within a minute Background jobs
Schedules written as cron, run once however many workers there are Background jobs
Finished jobs cleaned up nightly: done after 7 days, failed after 30 apps/api/src/jobs/jobs.cleanup.ts
Workers in the API or in their own service, any number of them Background jobs
Jobs in progress finish before a worker stops Health checks
What Read more
Workspace, member, invitation and billing changes recorded from the start Record activity
Recorded in the same transaction as the change Record activity
A page that reads as sentences, for admins and owners, as a paid feature Record activity
What support did while signed in as a customer is marked “by support” Admin panel
The name and address of whoever did it are kept after their account is gone apps/api/src/db/schema
What Read more
Sign-ups this week, subscriptions per plan, failed payments Admin panel
Everyone who signed up, with search, last visit and plan Admin panel
Every workspace with its owner, plan and subscription Admin panel
Sign in as a customer for up to an hour, with a banner and a Stop button Admin panel
Suspend someone and lift it again Admin panel
@AdminOnly() for routes of your own Admin panel
What Read more
An assistant chat that streams, with a Stop button AI features
Any model through Vercel AI Gateway, changed with one variable AI features
A paid feature, scoped to the workspace AI features
Limits on what is sent and how long the answer is AI features
Off until you add a key, so development and CI need none AI features
Streamed answers are not held back by the proxy in production apps/web/Caddyfile
What Read more
Events named once in the contracts, sent from the API, web and mobile apps Product analytics
Sign-ups, invitations and every change of plan, sent by the API through jobs Product analytics
People identified on sign-in, and grouped by workspace with teams on Product analytics
Mixpanel or PostHog (US, EU or your own), chosen with one variable Mixpanel or PostHog
An interface in each app for another provider Product analytics
Off until you add a key: no script downloaded, nothing sent Product analytics
What Read more
A shell with a sidebar that collapses, and slides over the page on phones apps/web/src/features/shell
Light, dark or the device’s choice, with no flash on load apps/web/src/lib/theme.ts
A get-started checklist for new customers, ticked off from what they did apps/web/src/features/onboarding
A notification bell with an unread count, live, and a page of where they go Notifications
Upgrade prompts with the plan’s price and perks; the recommended plan marked Charge for a feature
Every answer from the API checked against its contract Architecture
Forms validated with the same schemas as the API Add a resource
useWorkspace() with can() for roles and has() for plans Architecture
Confirmation dialogs that can ask for a password or a typed name apps/web/src/components/confirm-dialog.tsx
Search boxes and pagers that keep their state in the address apps/web/src/components/list-controls.tsx
Pages split into their own files, loaded when a link is about to be clicked apps/web/src/main.tsx
One “Page not found” for pages that do not exist and pages you may not see apps/web/src/routes/__root.tsx
An overview page with team, plan and system status cards to replace apps/web/src/routes/_authenticated/w.$slug/index.tsx
A banner on every page of a public demo, with the test card Marketing site
What Read more
Home, pricing, about, contact, blog, terms, privacy and a 404 page Marketing site
Pricing drawn from your plans, with a monthly and yearly switch Marketing site
A blog in MDX with tags, drafts, reading time and an RSS feed Marketing site
A share image made for every page and post Marketing site
Canonical links, Open Graph and Twitter cards, JSON-LD, a sitemap, robots.txt apps/site/src/layouts/Base.astro
A contact form that emails you, with a trap for bots and a limit per address Marketing site
Terms and privacy templates Marketing site
Follows the device’s dark mode apps/site/src/layouts/Base.astro
What Read more
An Expo app on the same contracts, with the same checked API client apps/mobile/src/lib/api.ts
Sign-in with a password, Google or GitHub, the session kept in the device’s secure storage Mobile app
Sign-up, forgot password, and deleting the account from inside the app Mobile app
Workspace switching, people and invitations, with teams on Mobile app
The audit log, for admins on a plan that has it Mobile app
The assistant, streamed, and the plan and what it includes Mobile app
Push notifications through the job queue, one call from any module Mobile app
A Notifications tab with an unread badge, live, and a screen to choose what reaches the phone Notifications
Bottom tabs drawn by the system (glass on iOS 26), and light, dark or system theme Mobile app
EAS profiles for development, testers and the stores Mobile builds
What Read more
Contracts shared by the API, web and mobile: change a field and they stop compiling Architecture
Guards for sessions, admins, membership, roles and plans, in that order Architecture
Every error in one shape, apiErrorSchema packages/contracts/src/errors.ts
Environment variables checked at startup, with one clear line per mistake Environment variables
Structured logs with a request id on every line and every response Logs
Secrets kept out of the logs, with a test that keeps it so Logs
OpenTelemetry traces across requests, jobs and queries, and metrics, with one variable Traces and metrics
Errors from the API, web and mobile apps reported to Sentry, with one variable Error reporting
Source maps sent by the web and mobile builds, never served Error reporting
Reports without passwords, tokens, cookies or emails, with a test Error reporting
A health check that knows about the database Health checks
Stops cleanly: finishes its work and closes its connections Health checks
Redis: the job queue, realtime, answers in flight, shared rate limits and a cache Redis
Drizzle, Prisma or TypeORM, chosen once; the kit works with any, tested on all three Database and ORMs
Migrations with your ORM, run before each release Other hosts
db:migrate needs only DATABASE_URL, so it runs before the rest is set up apps/api/src/db/migrate.ts
What Read more
300 API tests against a real Postgres and Redis, on each ORM Test your features
Browser journeys against the production images, in both modes, on every pull request Test your features
The mobile app’s flows with Maestro, on iOS and Android, and Android in CI on demand Test your features
Helpers to sign people up, add members and read their email Test your features
Stand-ins for Stripe, Polar, email and the AI model; no test reaches a real service Test your features
Either mode and any pricing, per test Test your features
bun run check: types, lint, formatting and every test, in one command Commands
Strict TypeScript everywhere, oxlint and Prettier tsconfig.base.json, .oxlintrc.json, .prettierrc
GitHub Actions on every pull request, with no secrets to set Continuous integration
The production images built, started and checked on every pull request Continuous integration
What Read more
Postgres, Redis, API, web, site and an optional worker on Railway, from one file Railway
deploy:plan shows what would change before deploy:apply changes it Railway
A guard that refuses to touch the wrong Railway project Railway
Migrations before each release; if they fail, the old version keeps serving Railway
Only the services whose files changed are rebuilt Railway
Health checks on every service, and restarts when one exits Health checks
The same production on AWS from one command: ECS, RDS and ElastiCache, in the CDK AWS
Settings kept in Secrets Manager on AWS, never in a template AWS
Settings checked against the API’s own rules before every deploy Check a deployment
deploy:check: sixteen checks of a deployment from outside, on any host Check a deployment
Production described once, apart from any host, and a guide and skill to add a host Add a host
Docker images for any host, and the production setup on your own machine Try it locally
One address in production: no CORS to set up, first-party cookies Architecture
Security headers, compression and long-lived caching of files that never change Security
Your own domains Railway
A launch checklist Launch checklist
What Read more
AGENTS.md at the root and in each app, read by Claude Code, Cursor and Codex Build with your coding agent
Ten skills, each ending in a checklist of what must be true Build with your coding agent
Upgrade notes for every release, and a skill that applies them on a branch Make it yours
These pages in the repository, in docs/ Overview