This guide explains how to set up and use the local development environment for the generic template.
The template supports local development with:
- Multi-project tmux sessions - All services in one terminal
- Hot-reload - Python and TypeScript automatically reload on changes
- Local databases - PostgreSQL in Docker containers
- 1Password integration - Secrets loaded from vaults
- Branding sync - Shared CSS and assets across projects
# Install all dependencies
make install
# Build styles
make styles
# Run all dev servers in tmux
make devThis starts:
- Python FastAPI on
http://localhost:8000 - TypeScript Vite web app on
http://localhost:5173 - TypeScript Express API on
http://localhost:3001 - PostgreSQL on
localhost:5432(Python only)
All Projects:
- 1Password CLI (
op) - For secrets management - Make - Command runner
Python:
- Python 3.12
- uv - Python package manager
- Docker - For PostgreSQL container
TypeScript:
- Node.js 20.x
- pnpm - Installed automatically by project
# macOS
brew install --cask 1password-cli
brew install python@3.12
brew install --cask docker
# Install uv (Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Node.js (via nvm recommended)
nvm install 20
nvm use 20Run all projects simultaneously in a tmux session:
# Start all dev servers
make devThis creates a tmux session with:
- Pane 1: Python development server
- Pane 2: TypeScript development servers (web + api)
Tmux Navigation:
Ctrl-b %- Split pane verticallyCtrl-b "- Split pane horizontallyCtrl-b arrow- Navigate between panesCtrl-b d- Detach from sessiontmux attach -t <session-name>- Reattach to session
Stopping:
# Kill the tmux session
make dev ARGS="--kill"
# Or from inside tmux
Ctrl-b :kill-sessionRun projects individually:
# Python only
make dev-py
# TypeScript only
make dev-tsOr use project-specific commands:
# Python development
cd py/
make dev
# TypeScript development
cd ts/
make devcd ts/
# Install dependencies
make install
# Setup branding asset symlinks
make styles
# Start development servers
make dev# All apps (web + api)
make devThis starts:
- Vite web app on
http://localhost:5173 - Express API on
http://localhost:3001
Both with:
- Hot module replacement
- TypeScript compilation
- Auto-restart on changes
# Format code
make fmt
# Check formatting
make fmt-check
# Type checking
make types
# Run tests
make test
# Run all checks
make check# Create asset symlinks
make styles
# Clean symlinks
make cleanThis creates symlinks in ts/apps/web/public/ pointing to branding/assets/:
favicon.ico→branding/assets/favicon.icoicon.svg→branding/assets/icon.svg- etc.
Note: Symlinks are used in development. For Docker builds, assets are copied instead.
ts/
├── apps/
│ ├── web/ # Vite React app
│ │ ├── src/ # Source code
│ │ ├── public/ # Static files (symlinks to branding)
│ │ └── package.json
│ └── api/ # Express API
│ ├── src/ # Source code
│ ├── tests/ # Test files
│ └── package.json
├── packages/
│ ├── typescript-config/ # Shared TypeScript configs
│ └── http-api/ # Shared HTTP API types
├── bin/
│ └── styles.sh # Branding asset setup
├── package.json # Root package.json
├── pnpm-workspace.yaml # pnpm workspace config
└── turbo.json # Turbo monorepo config
Add a new page (web app):
- Create component in
apps/web/src/pages/YourPage.tsx - Add route to your router
- Test:
http://localhost:5173/your-page
Add an API endpoint:
- Create route in
apps/api/src/routes/ - Register in
apps/api/src/index.ts - Test:
curl http://localhost:3001/your-endpoint
Add a dependency:
# To web app
cd apps/web
pnpm add package-name
# To API
cd apps/api
pnpm add package-name
# To root (dev dependency)
pnpm add -D -w package-namecd py/
# Install dependencies
make install
# Build styles
make styles
# Start local PostgreSQL
make db up
# Run migrations
make db migrate# With 1Password vault (recommended)
make dev
# Without vault (requires manual env vars)
make runServer runs on http://localhost:8000 with hot-reload.
Starting Database:
# Start PostgreSQL container
make db up
# Check status
make db status
# View connection URL
make db endpointMigrations:
# Run all pending migrations
make db migrate
# Create new migration (auto-detect changes)
make db prepare "Add user table"
# Create manual migration
MANUAL=1 make db prepare "Custom data migration"Database Access:
# Connect via psql
make db connect
# Run SQL query
make db connect
> SELECT * FROM users;
# View migration history
uv run alembic historyStopping Database:
# Stop container (keeps data)
docker stop <container-name>
# Remove container and volumes (deletes data)
make db downShared branding assets are in branding/:
branding/
├── assets/ # Icons, favicons
│ ├── favicon.ico
│ ├── icon.svg
│ ├── icon.png
│ └── favicon.png
├── styles/ # CSS source files
│ └── global.css # Tailwind base + custom CSS
└── tailwind.config.js # Shared Tailwind config
# From project root
make styles # Build styles for all projects
make styles-py # Build Python styles only
make styles-ts # Build TypeScript styles only
# Or from individual projects
cd py/ && make styles
cd ts/ && make stylesPython: Copies assets and compiles Tailwind CSS to py/static/css/main.css
TypeScript: Creates symlinks from ts/apps/web/public/ to branding/assets/
For local development, secrets can be loaded from 1Password or set manually.
Python (via bin/app/dev.sh):
# Example environment variables
GOOGLE_O_AUTH_CLIENT_ID
GOOGLE_O_AUTH_CLIENT_SECRET
POSTGRES_URL # Auto-set by db commandsTypeScript:
# Web app can use .env.local or environment variables
VITE_API_URL=http://localhost:3001
# API can use environment variables for config
PORT=3001cd py/
# Run all tests
make test
# Run specific test file
uv run pytest tests/test_auth.py
# Run with coverage
uv run pytest --cov=src tests/
# Run with verbose output
uv run pytest -v tests/cd ts/
# Run all tests
make test
# Run specific test
pnpm test your-test.spec.ts
# Run with watch mode
cd apps/api
pnpm test --watchcd py/
make install # Reinstall dependenciescd ts/
make install # Installs pnpm and dependencies# Check database is running
make db status
# Start database
make db up
# Check connection URL
make db endpoint# Python (8000)
lsof -i :8000
kill -9 PID
# TypeScript Web (5173)
lsof -i :5173
kill -9 PID
# TypeScript API (3001)
lsof -i :3001
kill -9 PID
# PostgreSQL (5432)
lsof -i :5432
make db down# Rebuild styles
make styles
# Python: Check static/css/main.css exists
ls py/static/css/
# TypeScript: Check symlinks exist
ls -la ts/apps/web/public/After setting up local development:
- Make changes to your application
- Test locally with
make dev - Run checks with
make check - Commit changes to git
- Deploy to staging/production (see deployment guides)
For deployment workflows, see: