Skip to main content
Buildstory is built on Next.js 16 with a modern serverless architecture powered by server actions, Neon Postgres, and Drizzle ORM.

Architecture

Next.js 16 App Router

Buildstory uses the Next.js 16 App Router with React 19 and TypeScript. The application follows a server-first architecture:
  • Server Components: All pages are server components by default, fetching data server-side
  • Server Actions: All mutations use Next.js server actions with "use server" directive
  • Client Components: Interactivity isolated to specific UI components
  • Streaming: Progressive rendering with React Suspense boundaries

Database Stack

Database
Neon Postgres
Serverless Postgres with branch-based isolation:
  • dev branch for local development and preview deployments
  • main branch for production
  • HTTP adapter via @neondatabase/serverless
ORM
Drizzle ORM
Type-safe SQL query builder with:
  • Schema-first design in lib/db/schema.ts
  • Relational queries with with API
  • Migration-based schema changes
  • Full TypeScript inference

Tech Stack Summary

Core Framework

  • Next.js 16 (App Router, React 19, TypeScript)
  • Deployment: Vercel with automatic preview deployments
  • Path Aliases: @/ maps to project root

Styling & UI

  • Tailwind CSS v4 with custom configuration
  • shadcn/ui (new-york style) for component primitives
  • Radix UI for accessible headless components
  • Motion (Framer Motion) for animations
  • Fonts: DM Sans (body), Instrument Serif (headings), DM Mono (code)

Authentication & Authorization

Auth Provider
Clerk
Custom UI implementation (not pre-built components):
  • Email/password and OAuth (Google, GitHub)
  • Custom sign-in/sign-up forms in app/(auth)/
  • Just-in-time profile creation via ensureProfile()
Authorization
Role-based
Three-tier role system:
  • user (default)
  • moderator (can hide users, ban users)
  • admin (full access, can manage roles)
  • Super-admin override via ADMIN_USER_IDS env var

Data Layer

Database
Neon Postgres
Connection: @neondatabase/serverless HTTP adapter
ORM
Drizzle ORM
Client in lib/db/index.ts with full relational schema
Migrations
Automated
  • npm run db:generate — generate migration from schema changes
  • npm run db:migrate — run pending migrations
  • Production migrations automated in CI on merge to main

Integrations

Notifications
Discord Webhooks
Fire-and-forget webhooks in lib/discord.ts:
  • Signup notifications
  • Project creation notifications
  • Milestone alerts (10, 25, 50, 75, 100+ signups/projects)
CMS
Sanity
Embedded studio at /studio (admin-only):
  • Sponsor logo management
  • Volunteer role content
  • Homepage content management
Error Tracking
Sentry
Configured for server, edge, and client runtimes:
  • Server actions use Sentry.captureException with tags
  • Component and action tags for debugging
  • Extra context in error reports

Development Tools

Testing
Vitest
  • Unit tests in __tests__/unit/ (no DB required)
  • Integration tests in __tests__/integration/ (real Neon DB)
  • Mocked: Clerk auth, Sentry, Discord webhooks
Linting
ESLint
  • Pre-commit hooks via Husky + lint-staged
  • Rules: no-console (warn), prefer-const, eqeqeq
CI/CD
GitHub Actions
Three workflows:
  • lint.yml — runs on PRs
  • test.yml — unit + integration tests on PRs
  • deploy.yml — migrates production DB, then triggers Vercel deploy

Request Flow

Authentication Flow

  1. User signs in via Clerk custom form (app/(auth)/sign-in)
  2. Clerk middleware (proxy.ts) validates session
  3. ensureProfile(clerkId) creates profile record just-in-time
  4. Profile created with default user role
  5. Subsequent requests use cached profile (React cache())

Data Mutation Flow

  1. Client component calls server action
  2. Server action:
    • Validates authentication via auth()
    • Ensures profile exists with ensureProfile()
    • Validates input with Zod schemas
    • Performs database mutations
    • Handles errors with Sentry
    • Revalidates affected paths
  3. Returns ActionResult<T> type:
    | { success: true; data?: T }
    | { success: false; error: string }
    

Error Handling Pattern

All server actions follow a consistent error handling pattern:
try {
  const profileId = await getProfileId();
  // ... business logic
  revalidatePath("/path");
  return { success: true };
} catch (error) {
  if (isUniqueViolation(error, "constraint_name")) {
    return { success: false, error: "User-friendly message" };
  }
  Sentry.captureException(error, {
    tags: { component: "server-action", action: "actionName" },
    extra: { /* context */ },
  });
  return { success: false, error: "Generic error message" };
}

Environment Variables

Required (Development & Production)

  • DATABASE_URL — Neon Postgres connection string
  • NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY — Clerk publishable key
  • CLERK_SECRET_KEY — Clerk secret key
  • NEXT_PUBLIC_CLERK_SIGN_IN_URL/sign-in
  • NEXT_PUBLIC_CLERK_SIGN_UP_URL/sign-up
  • NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL/dashboard
  • NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL/hackathon
  • ADMIN_USER_IDS — Comma-separated Clerk user IDs with super-admin access

Optional

  • DISCORD_WEBHOOK_SIGNUPS — Discord webhook for signup notifications
  • DISCORD_WEBHOOK_MILESTONES — Discord webhook for milestone alerts
  • DISCORD_WEBHOOK_TEAM_CHAT — Discord webhook for team chat notifications
  • NEXT_PUBLIC_MAPBOX_TOKEN — Mapbox access token for Globe component
  • TWITCH_CLIENT_ID — Twitch API client ID for streamers feature
  • TWITCH_CLIENT_SECRET — Twitch API client secret
  • LINEAR_API_KEY — Linear API key for issue tracking integration
  • LINEAR_TEAM_ID — Linear team identifier
  • LINEAR_PROJECT_ID — Linear project identifier
  • LINEAR_LABEL_ID — Linear label identifier for categorization
  • SENTRY_AUTH_TOKEN — Sentry authentication token for releases
  • SENTRY_ORG — Sentry organization slug
  • SENTRY_PROJECT — Sentry project slug

CI-Only

  • PRODUCTION_DATABASE_URL — Production Neon connection string
  • VERCEL_DEPLOY_HOOK — Vercel deploy hook URL

Next Steps

Database Schema

Complete reference for all tables, fields, and relationships

Server Actions

API reference for all server actions organized by feature area

Build docs developers (and LLMs) love