Documentation
NextRun documentation
Everything you need to clone NextRun, configure the integrations, and ship. Pick a section, or read top to bottom.
Overview
NextRun is a production-ready Next.js 16 starter. Authentication, payments, a Postgres database, and a Telegram bot come configured, typed, and tested, so you can delete what you do not need and build the part that matters. The marketing surface follows a strict monochrome design language meant to be reused as a starting point for other projects.
Quick start
You need Bun 1.x and a PostgreSQL database. Neon works out of the box. Clone the repository, install dependencies, set your environment variables, and start the dev server.
$ git clone https://github.com/hamanovich/nextrun$ cd nextrun$ bun install$ cp .env.example .env$ bun run db:push$ bun run devThen open http://localhost:3000.
Environment variables
All configuration is validated at startup by src/lib/env.ts. Copy .env.example to .env and fill in the values below. Variables prefixed with NEXT_PUBLIC are exposed to the browser.
| Variable | Required | Description |
|---|---|---|
| DATABASE_URL | Yes | Neon or PostgreSQL connection string. |
| NEXT_PUBLIC_DOMAIN | Yes | Absolute site URL, for example http://localhost:3000. |
| BETTER_AUTH_SECRET | Yes | Session secret for Better Auth (min 32 characters). |
| BETTER_AUTH_URL | Yes | Base URL Better Auth runs on. |
| GOOGLE_CLIENT_ID | Yes | Google OAuth client ID. |
| GOOGLE_CLIENT_SECRET | Yes | Google OAuth client secret. |
| STRIPE_SECRET_KEY | Yes | Stripe API secret key. |
| STRIPE_WEBHOOK_SECRET | Yes | Signing secret for the Stripe webhook. |
| TELEGRAM_BOT_TOKEN | Yes | Token for the grammY Telegram bot. |
| OPENAI_API_KEY | Yes | Used by the health-check endpoint. |
| HEALTH_CHECK_SECRET | Yes | Guards the health endpoint (min 32 characters). |
| NEXT_PUBLIC_UMAMI_URL | Optional | Umami instance URL. Leave empty to disable analytics. |
| NEXT_PUBLIC_UMAMI_WEBSITE_ID | Optional | Umami website ID (UUID). |
Project structure
Database access goes through Drizzle inside Server Actions. There is intentionally no service layer and no raw client calls from components.
src/
actions/ Server Actions: Drizzle queries, auth, Stripe
app/ App Router routes, layouts and API handlers
bot/ grammY Telegram bot
components/ UI and feature components
db/ Drizzle schema and client
hooks/ TanStack Query hooks
lib/ env, auth, stripe and utils
test/ Vitest setup and mocksWhat is included
Authentication
Better Auth with Google OAuth and sessions, read server-side through Server Actions.
Payments
Stripe checkout, a credit system, and signature-verified webhooks.
Database
Drizzle ORM on Neon Postgres with fully typed queries.
Telegram bot
A grammY bot with conversations, file handling and throttling.
UI kit
shadcn/ui, Tailwind v4 and dark mode, wired and themeable.
Type safety
TypeScript strict mode and Zod validation on every input.
Scripts
Run bun run check before declaring work done. It covers types, linting, formatting, and tests.
bun run devStart the dev server with Turbopack.bun run buildCreate a production build.bun run checkRun ts:check, lint, format and tests.bun run db:pushPush the Drizzle schema to the database.bun run stripe:listenForward Stripe webhooks to localhost.bun run bot:devRun the Telegram bot in watch mode.Deployment
NextRun ships with a multi-stage Dockerfile and a standalone build. Server clients initialize lazily, so the build needs no server secrets, only NEXT_PUBLIC variables are passed as build arguments so they are inlined into the client and the Content-Security-Policy. Every secret is injected at runtime.
docker build \
--build-arg NEXT_PUBLIC_DOMAIN=https://your-domain.com \
--build-arg NEXT_PUBLIC_UMAMI_URL=https://analytics.your-domain.com \
-t nextrun .The runner stage adds curl so Coolify and similar platforms can run an in-container HTTP health check. The full self-hosted runbook lives in docs/DEPLOYMENT.md.
Need the full reference?
The README on GitHub covers every script, integration, and deployment detail in depth.