Skip to main content

Architecture Overview

folksbase is a monorepo — all apps and shared packages live in one repository, managed by pnpm workspaces and Turborepo. This page explains what each piece does and why the tech stack was chosen.

Monorepo Structure

folksbase/
├── apps/
│   ├── web/        # Next.js 15 frontend (deployed to Vercel)
│   ├── api/        # Hono backend (deployed to Render)
│   └── docs/       # This documentation site (Mintlify)
├── packages/
│   ├── db/         # Drizzle schema + migrations (shared)
│   ├── emails/     # Email templates via Resend
│   └── types/      # Shared TypeScript types

Apps

AppWhat it doesDeployed to
apps/webNext.js 15 frontend with App Router and React Server Components. Handles the UI, auth redirects, and server-side rendering.Vercel
apps/apiHono v4 REST API. Handles all business logic, database access, file uploads, and background job orchestration.Render
apps/docsThis documentation site, built with Mintlify. Auto-deploys on push to main.Mintlify

Packages

Packages are shared code that both apps can import. They live in packages/ and are referenced by their package names.
PackageWhat it doesPackage name
packages/dbDrizzle ORM schema definitions and database migrations. Both the API and background jobs use this to talk to Postgres.@folksbase/db
packages/emailsReact Email templates for transactional emails (import complete, export ready, weekly digest). Sent via Resend.@folksbase/emails
packages/typesShared TypeScript types used by both frontend and backend — contacts, imports, exports, API responses. Single source of truth for data shapes.@folksbase/types

Why a monorepo?

A few reasons:
  1. Shared types stay in sync. When you change a type in @folksbase/types, both the frontend and backend see the change immediately. No version mismatches, no publishing packages.
  2. One PR, one review. A feature that touches the API, the UI, and the types can be reviewed as a single pull request.
  3. Turborepo caches builds. If you only change apps/web, Turborepo skips rebuilding apps/api and all packages. This keeps CI fast.

Why pnpm?

pnpm’s strict dependency resolution prevents phantom dependencies — you can’t accidentally import a package that isn’t in your package.json. It also uses a content-addressable store, so shared dependencies across the monorepo are stored once on disk.

Tech Stack

Here’s what folksbase uses and, more importantly, why.

Frontend

TechnologyWhy
Next.js 15 (App Router)React Server Components reduce client-side JavaScript. The App Router’s file-based routing and layouts keep the codebase organized.
Tailwind CSSUtility-first CSS that’s fast to write and easy to maintain. No CSS-in-JS runtime overhead.
Radix Primitives + Radix ColorsAccessible, unstyled UI primitives (dialogs, dropdowns, selects) with a consistent color system built on oklch.
SWRLightweight data fetching for client components. Handles caching, revalidation, and optimistic updates with minimal boilerplate.
ZodRuntime validation for API responses, form inputs, and environment variables. Types are derived from schemas via z.infer<>.

Backend

TechnologyWhy
Hono v4Lightweight, fast, and TypeScript-native. Runs anywhere (Node, Bun, Cloudflare Workers). Perfect for a REST API that doesn’t need the overhead of Express.
Drizzle ORMType-safe SQL queries without the magic of heavy ORMs. You write queries that look like SQL, and TypeScript catches mistakes at compile time.
Neon (Postgres, HTTP driver)Serverless Postgres with instant branching. The HTTP driver was chosen over WebSocket because the API runs on Render, where persistent WebSocket connections to Neon were unreliable.
Upstash RedisServerless Redis for caching (stats, contact counts) and rate limiting. Pay-per-request pricing keeps costs near zero for small workloads.
InngestBackground job orchestration with step-level retries. CSV imports and exports run as multi-step jobs — if one step fails, only that step retries.

Infrastructure

TechnologyWhy
Vercel BlobFile storage for uploaded CSVs and exported files. Integrates natively with the Vercel ecosystem.
Supabase AuthAuthentication with email/password, magic links, and OAuth. Handles JWTs, session management, and user metadata.
ResendTransactional email delivery with React Email templates. Simple API, good deliverability.
Anthropic API (Claude Haiku)AI-powered CSV column mapping. Haiku is fast and cheap — perfect for a feature that needs to respond in under 2 seconds.

Developer Experience

TechnologyWhy
BiomeReplaces ESLint + Prettier with a single, faster tool. Handles linting and formatting in one pass.
VitestFast unit testing with native TypeScript support. Compatible with the Jest API but significantly faster.
PlaywrightE2E testing against real browsers. Runs against Vercel preview URLs in CI.
Storybook 8Component documentation and visual testing. Deployed to Netlify for the team to browse.
TurborepoMonorepo build orchestration with caching. Only rebuilds what changed.

What’s Next?