Reusable SPA template for product frontends. This is a generic foundation — it contains no product logic, only app plumbing (auth, API client, routing, shell, components).
Built with Vite 6, React 19, TypeScript, Tailwind CSS v4, TanStack Router, and shadcn/ui.
- Node 24+ (pinned in
.nvmrc)
# Install dependencies
npm install
# Copy env file and fill in values
cp .env.example .env
# Run the dev server (hot reload)
npm run devThe app is available at http://localhost:5173.
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch# Format, lint, typecheck, and test
npm run precommit- Composition root:
main.tsxis the only file that readsimport.meta.env - Typed API client: Envelope-aware, auto-attaches Bearer token, 401 auto-refresh with mutex
- Auth flow: Login, register, logout, session bootstrap from refresh token, protected routes
- App shell: Responsive sidebar (desktop fixed, mobile overlay) + header, via pathless layout route
- shadcn/ui components: Button, Input, Card, Dialog, DropdownMenu, Toaster (owned files, not a dependency)
- File-based routing: TanStack Router with Vite plugin codegen, type-safe navigation
See docs/ARCHITECTURE.md for detailed design and docs/DECISIONS.md for the decision log.
Copy .env.example to .env. Dev requires:
| Variable | Default | Description |
|---|---|---|
VITE_API_BASE_URL |
— | Backend API URL (required) |
This is one of three reusable service templates. They share API conventions and response envelopes but are otherwise independent.
| Template | Purpose | Stack |
|---|---|---|
| elixir-api-core | Core backend APIs | Elixir, Phoenix, PostgreSQL |
| node-edge-core | Edge/integration services | TypeScript, Fastify, Zod |
| web-app-core (this repo) | Frontend SPA | TypeScript, React, Vite, Tailwind |
Product apps are created from these templates and then diverge freely with domain logic. They're designed to work together — a frontend built from web-app-core calls a backend API built from elixir-api-core, while edge services built from node-edge-core handle integrations.
This repo is intended to work as a standalone starting point. It does not require the companion templates to exist locally in the same directory. If you want to pair it with the related backend or edge templates, use the GitHub repos above rather than assuming a shared workspace layout.
See CHANGELOG.md for the versioned task tracker.