BaselineNext New App Setup Guide
The BaselineNext repository is intended to be copied, renamed, and governed into a real SaaS product. This guide starts after you have duplicated the repository in GitHub and want to configure BaselineNext.
This baseline supports your hosting choice of Postgres database, Upstash for Redis/caching, Stripe for billing and Resend for outbound email. Other providers can be integrated but need to be added on top of this baseline repository.
The repository includes the implementation described here, Vitest unit tests with enforced coverage thresholds, integration tests, and end-to-end functional tests through Playwright. The governance framework allows you to extend this repository with the same rules that guided its creation and with deployment checks enforced through CI.
How to setup TL;DR
Create the infrastructure accounts, fill .env.local, apply the checked-in database migrations, create the first admin through /setup/first-admin, bootstrap scheduled jobs, prepare the optional E2E support tables, then let your development agent work inside the governance framework.
Full Guide
1. Create Your Repository Copy
- Duplicate the BaselineNext repository in GitHub.
- Rename the repository for your product.
- Clone your copy locally:
git clone git@github.com:<your-org>/<your-repo>.git
cd <your-repo>
- Open the folder in VS Code:
code .
- Install dependencies:
npm install
2. Provision Local Development Services
Create separate development resources before filling the environment file.
Postgres
Use any Postgres provider that gives you:
- a runtime connection URL for the app pool
- a direct or unpooled connection URL for Drizzle migrations and schema verification
Neon, Supabase, Railway, Render, RDS, and local Docker Postgres all work as long as both connection modes are available. Put the pooled URL in DATABASE_URL and the direct URL in DATABASE_URL_UNPOOLED.
Redis
Create an Upstash Redis database for shared runtime state. Local development can run without Upstash because the cache layer falls back to an in-memory implementation, but Redis is required for preview, staging, and production environments.
Use a unique APP_ID and, when you intentionally share Redis between multiple local/test processes, set REDIS_KEYSPACE.
Stripe
Create or reuse a Stripe test-mode account. You need:
STRIPE_SECRET_KEYNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYSTRIPE_WEBHOOK_SECRETfromstripe listenor a configured webhook endpoint
Billing can stay disabled with BILLING_ENABLED=false while you are adapting the starter. Turn it on only after test-mode Stripe keys, products, prices, tax settings, and webhook handling are ready.
Create a Resend API key for deployed environments. Local APP_ENV=dev can use the development email bypass, but preview, staging, and production should have RESEND_API_KEY, EMAIL_FROM, OPS_ALERT_EMAIL, and SUPPORT_EMAIL.
3. Fill .env.local
Copy the example file:
cp .env.example .env.local
Set at least these local values:
APP_ID: machine-safe namespace, for examplemyappNEXT_PUBLIC_APP_NAME: the display name shown in UI and emailDATABASE_URL: app runtime Postgres URLDATABASE_URL_UNPOOLED: direct migration Postgres URLAUTH_SECRET: cryptographically random secret generated withopenssl rand -base64 32oropenssl rand -hex 32. Preview, staging, and production require hex, Base64, or Base64URL encoding of at least 32 bytes. Rotating this value invalidates existing sessions and authentication tokens; validate deployed values before rollout and do not rotate them automatically.ADMIN_SECRET: long random secret for admin-only bearer endpointsFIRST_ADMIN_SETUP_TOKEN: long random one-time setup secret for creating the first admin accountINTERNAL_CONTROL_SECRET: long random secret for local E2E/internal controlsDEV_PORT: local dev server portAPP_URL: usuallyhttp://localhost:<DEV_PORT>NEXT_PUBLIC_SITE_URL: usuallyhttp://localhost:<DEV_PORT>
For local billing or E2E, also set:
TEST_SERVER_PORT: separate from the dev port so you can run a compiled local test server for Playwright and webhook testsSTRIPE_SECRET_KEY: Stripe test-mode secret key, beginning withsk_test_STRIPE_WEBHOOK_SECRET: Stripe webhook signing secret, usually fromstripe listenlocally or the configured test webhook endpointNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: Stripe test-mode publishable key used by browser checkout flowsE2E_APP_ADMIN_LOGIN: app admin email/username used by Playwright admin flowsE2E_ADMIN_PASSWORD: app admin password used by Playwright admin flows
Keep NODE_ENV=development and APP_ENV=dev for normal local development.
4. Apply the Database Schema
The BaselineNext repository uses Drizzle migrations. The unpooled database user URL is used for schema work because migration tools should not run through a transaction pooler.
npm run db:generate:local
npm run db:migrate:local
npm run db:verify:local
This will create the empty baseline schema in the database as a starting point for your app.
For any further changes generation should not create surprising SQL. Migrate applies the checked-in migrations, and verify compares the live database to db/schema.ts.
The governance rules include instructions on how your agent evolves and changes the schema. Do not use drizzle-kit push, npm run db:push, or npm run db:push:force manually.
5. Start the App
Run the local development server:
npm run dev
Open:
http://localhost:<DEV_PORT>
The repo-local launcher reads .env.local, so you do not need to globally export database URLs.
6. Create the First Admin
Before staring, ensure you have set a FIRST_ADMIN_SETUP_TOKEN env variable / secret in your environment so that first time admin user setup can be authenticated.
- Visit
/setup/first-admin. - Enter
FIRST_ADMIN_SETUP_TOKEN. - Enter the email, display name, and password for the first admin account.
- Submit the form, then continue to
/admin/login.
This setup page is available only while no admin account exists and FIRST_ADMIN_SETUP_TOKEN is configured. Once the first admin exists, the page returns 404.
If an account already exists with the submitted email and no admin exists yet, the setup flow promotes that account, updates its display name and password, and revokes any existing sessions.
Direct SQL promotion is an emergency local fallback only:
update accounts
set is_admin = true
where email = '<your-admin-email>';
Prefer the setup page for local, preview, and serverless deployments because it uses the same app-owned password hashing, lifecycle, and audit paths as the rest of the application.
7. Bootstrap Scheduled Jobs
After admin login:
- Open
/admin/jobs/scheduled. - Click
Bootstrap. - Confirm scheduled jobs are listed.
This creates the recurring job rows declared by the app. The operation is idempotent.
8. Prepare E2E Support Tables
The Playwright billing simulations use guarded E2E-only support tables for Stripe Test Clock customer overrides and runtime flags. Create them only in development or test-like databases:
npm run test:e2e:setup-stripe-test-clock-overrides
The setup script refuses to run when APP_ENV is staging or prod.
If you plan to run browser E2E tests locally, also install browser binaries if your machine does not already have them:
npx playwright install
10. Run Verification
Use the normal baseline checks before making the copy your working foundation:
npm run typecheck
npm run test:run
npm run test:integration
npm run lint
npm run validate:openapi
npm run db:verify:local
Playwright is available but intentionally not automatic. Run it when you are ready for full browser coverage. e.g.:
npm run test:e2e:playwright:smoke
For local Playwright against the compiled test server, build/start the test target according to the current E2E workflow, then run with PLAYWRIGHT_BASE_URL=http://localhost:<TEST_SERVER_PORT> when needed.
Review the e2e testing readme at e2e/README.md.
11. Connect Your Development Agent
Open the repository in VS Code and attach your coding agent to that workspace. Before asking the agent to change code, direct it to follow the repository governance:
Before planning, reviewing, or editing code, read governance/baseline.md and governance/project.md. Treat them as authoritative. Use the BaselineNext governed-slice workflow for implementation. Keep changes scoped. If an allowlist is supplied, do not edit outside it. Include the governance checklist before finishing.
When you ask for a feature, give the agent a controlled slice:
Implement <feature>. Allowed files: <list files or folders>. Preserve the route -> module -> db boundary. Add focused tests. Do not create architecture exceptions unless you report the required exception first.
The governance framework is the product discipline. It keeps route handlers at the transport boundary, business workflows in modules, persistence in the owning module, environment access behind helpers, Redis keys centralized, and tests matched to risk.
12. Start Product Adaptation
After the baseline is running:
- Update app branding through
NEXT_PUBLIC_APP_NAME, public assets, and UI copy. - Add project-specific rules to
governance/project.md. - Replace starter marketing content with your positioning.
- Define your first domain slice and implement it through the governed workflow.
- Keep reusable baseline rules in
governance/baseline.md; keep product-specific rules ingovernance/project.md.
At this point the repository is ready for normal development and testing.