Skip to content

fikst/fullstack-starter

Repository files navigation

Fullstack Starter

Opinionated fullstack starter for new client engagements. Built so a new project goes from git clone to a deployed app in about 30 minutes.

This is the standard template for fikst consulting engagements. Use it as the starting point for every new client project unless there's a specific reason not to.

What's in the box

Layer Choice
Framework Next.js 15 (App Router) + React 19
Language TypeScript (strict)
Styling Tailwind CSS v4
Database Postgres via Drizzle ORM
Auth Auth.js v5 (NextAuth) + GitHub OAuth
Validation Zod (shared types between client/server)
Testing Vitest
Lint/Format ESLint (next/core-web-vitals) + Prettier
CI GitHub Actions (typecheck / lint / format / test / build)
Hosting Vercel (default)
DB hosting Neon (default; any Postgres works)

Why these picks: every one is boring, well-supported, and something a client engineering team can pick up without a handoff document. If you're tempted to swap in something exotic, write down why in the engagement README.

Quick start (30-minute deploy)

You'll need: Node 20+, a GitHub account, a Neon account (free tier is fine), and a Vercel account.

1. Clone (1 min)

Click Use this template in GitHub, or:

gh repo create my-client-app --template fikst/fullstack-starter --private --clone
cd my-client-app

2. Install dependencies (2 min)

npm install

3. Provision a Postgres database (5 min)

Sign in to Neon, create a new project, copy the connection string. (Or use Supabase, Railway, RDS, or local Postgres — anything that speaks Postgres.)

4. Configure environment (3 min)

cp .env.example .env

Fill in:

  • DATABASE_URL — the Neon connection string from step 3.
  • AUTH_SECRET — generate with openssl rand -base64 32.
  • AUTH_URL — leave as http://localhost:3000 for now.
  • AUTH_GITHUB_ID / AUTH_GITHUB_SECRET — see step 5.

5. Set up GitHub OAuth (5 min)

Create a new OAuth app:

  • Homepage URL: http://localhost:3000
  • Authorization callback URL: http://localhost:3000/api/auth/callback/github

Copy the client ID and generate a client secret into .env.

6. Run migrations (1 min)

npm run db:generate   # generates SQL from src/db/schema.ts
npm run db:migrate    # applies migrations to your DATABASE_URL

7. Run it locally (1 min)

npm run dev

Open http://localhost:3000, sign in, confirm you land on /dashboard.

8. Deploy to Vercel (10 min)

  1. Push this repo to GitHub.
  2. In Vercel, import the repo.
  3. Add the same env vars from .env to the Vercel project.
  4. Update AUTH_URL to your production URL (e.g. https://my-client-app.vercel.app).
  5. Add a second GitHub OAuth callback URL on your OAuth app: https://my-client-app.vercel.app/api/auth/callback/github.
  6. Trigger a deploy. CI will run on every PR thereafter.

That's the engagement on a real URL. Replace the home page and dashboard with client-specific UI and you're shipping product, not boilerplate.

Project layout

src/
  app/                # Next.js App Router
    page.tsx          # public home page
    layout.tsx        # root layout
    globals.css       # Tailwind v4 entry
    (auth)/signin/    # sign-in screen
    api/
      auth/[...nextauth]/route.ts  # Auth.js handlers
      health/route.ts              # health check (used by uptime monitors)
    dashboard/        # authenticated area
  auth/
    index.ts          # NextAuth() config + exports (auth, signIn, signOut)
  db/
    client.ts         # Drizzle + postgres-js client (singleton)
    schema.ts         # Drizzle schema (users, accounts, sessions, todos)
    migrate.ts        # migration runner used by `npm run db:migrate`
  lib/
    env.ts            # Zod-validated environment config
    utils.ts          # cn() + small shared helpers
  middleware.ts       # protects /dashboard/*

tests/                # Vitest tests
drizzle/              # generated SQL migrations (commit these)
.github/workflows/    # CI

Scripts

Command What it does
npm run dev Start the dev server on :3000
npm run build Production build
npm start Start the production build
npm run typecheck tsc --noEmit
npm run lint ESLint
npm run format Prettier write
npm run format:check Prettier check (used in CI)
npm test Vitest (one-shot)
npm run test:watch Vitest watch mode
npm run db:generate Generate SQL migrations from src/db/schema.ts
npm run db:migrate Apply pending migrations
npm run db:studio Drizzle Studio (UI for the DB)

Adding a new table

  1. Edit src/db/schema.ts.
  2. npm run db:generate (creates SQL in drizzle/).
  3. npm run db:migrate (applies to DATABASE_URL).
  4. Commit both the schema change and the generated SQL.

Auth: adding another provider

Auth.js providers are configured in src/auth/index.ts. To add Google:

import Google from 'next-auth/providers/google';

providers: [
  GitHub({ ... }),
  Google({
    clientId: process.env.AUTH_GOOGLE_ID,
    clientSecret: process.env.AUTH_GOOGLE_SECRET,
  }),
],

Then add AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET to .env.example, .env, and your Vercel project. The Drizzle adapter handles the database side automatically.

Protecting a route

The src/middleware.ts file gates /dashboard/*. To protect another path, add it to the matcher array. For per-page checks (server components), call auth() at the top:

import { redirect } from 'next/navigation';
import { auth } from '@/auth';

export default async function Page() {
  const session = await auth();
  if (!session?.user) redirect('/signin');
  // ...
}

Tech-stack defaults (and when to deviate)

This template is the fikst default. Reasons to deviate:

  • Client already runs on AWS / GCP / their own infra → use it. Vercel is the fallback, not a hard requirement.
  • Workload requires long-running background jobs or websockets at scale → swap Next.js API routes for a dedicated Node service (Fastify or Hono on Fly/Render). Keep the Next.js frontend.
  • Heavy reporting / analytics → add Postgres read replicas before reaching for a separate analytics database.
  • Client already uses Prisma → swap Drizzle for Prisma. The rest of the template stays.

Document the deviation in the client repo's README so future you knows why.

License

MIT — see LICENSE.

About

Opinionated fullstack starter for new client engagements: Next.js + TS + Drizzle + Postgres + Auth.js. Clone, configure, deploy in 30 min.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors