Skip to content

Web, API and background jobs, in one repo.

A pnpm monorepo for a SaaS: web app, API and background worker as three apps, and one shared database-schema package all three use.

Open on GitHubMIT licence · free to use

Use it when

You're building a SaaS that needs a separate API and background jobs next to the web app from day one, with Clerk sign-in.

One Next.js app plus jobs is enough? template-next-supabase instead →

What's included

Done from the start.

  • The web app

    Clerk sign-in, a protected dashboard, privacy and terms pages, dark mode and security headers.

  • The API

    Express 5 with Clerk, Redis rate limiting, Zod validation and a complete example resource.

  • User sync

    A Clerk webhook that syncs users into the database.

  • Background jobs

    Inngest with a three-step example and a daily cleanup cron.

  • Shared schema

    A package with the Drizzle schema, migrations and seed that every app imports.

  • Docker

    A multi-stage Dockerfile per app.

Get started

pnpm install
cp .env.example .env
pnpm --filter @ketryon/database build
pnpm --filter @ketryon/database db:generate
pnpm --filter @ketryon/database db:migrate
pnpm --filter web dev
pnpm --filter backend dev
pnpm --filter worker dev

Structure

apps/
  web/        Next.js 15 frontend      (port 3000)
  backend/    Express 5 API server     (port 3001)
  worker/     Inngest background jobs  (port 3005)
packages/
  database/   Drizzle schema, types and db client

Environment variables

  • DATABASE_URL
  • REDIS_URL
  • CLERK_SECRET_KEY
  • NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
  • CORS_ORIGINS
  • NEXT_PUBLIC_API_URL

The Stripe, S3 and OpenAI variables in .env.example are placeholders for things you wire up yourself.

Good to know

  • Signature checks for the Clerk and Stripe webhooks are TODOs in the code.
  • The database package is built once before the API starts.
  • Lint has no config in the API and is missing a package in the web app — both were already the case before the update.

Built with

  • Next.js 15
  • React 19
  • Clerk
  • Express 5
  • Inngest
  • PostgreSQL
  • Drizzle
  • Redis
  • Zod

Let's build
the next thing.

You talk to me, not a salesperson. The first call is free.

— Kenny

psst, it takes 15 min

Write, and I reply the same working day.