Development Setup¶
This guide covers installation, configuration, and getting the development environment running.
Prerequisites¶
Node.js Version¶
This project requires Node.js 24 or higher. We use mise for version management:
mise install # Installs node@24 from mise.toml
Native Dependencies¶
This project uses native Node.js modules that require compilation:
- sharp - Image processing library for
@nuxt/image(IPX provider) - better-sqlite3 - SQLite3 bindings for Nuxt Content
Build scripts run automatically during pnpm install without requiring manual approval.
Troubleshooting Image Loading:
- If images fail to load with 500 errors on /_ipx/ endpoints, ensure sharp is installed
- Restart the dev server after installing sharp to load the native module
- In CI environments, build tools (python3, make, g++) are automatically installed
Installation¶
Install all dependencies once (from root):
pnpm install
Build shared schemas (required before running apps):
pnpm --filter @meisterbill/schemas build
Environment Setup¶
API Configuration¶
The API requires environment variables. Create apps/api/.env:
# Supabase Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_service_role_key_here
# API Configuration
PORT=3001
# PDF Generation (Local Development)
GOTENBERG_URL=http://localhost:3003
# Web Application URL (used for email redirects in auth flows)
APP_URL=http://localhost:3000
Important: The SUPABASE_KEY should be the service role key (not the anon key) for full database access. Get it from Supabase Dashboard → Settings → API → service_role key.
Web Application Configuration¶
Create apps/web/.env:
# API URL
NUXT_PUBLIC_API_URL=http://localhost:3001
# Authentication Control
NUXT_PUBLIC_ENABLE_SIGNUPS=false # Hides login/register buttons
# Analytics (Privacy-friendly)
NUXT_PUBLIC_UMAMI_ENABLED=false
# Optional: Sentry error tracking
SENTRY_DSN=your_sentry_dsn_here
Optional Services¶
Stripe (Payment Processing)¶
Required for payment links and Stripe Connect:
STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_secret_here
STRIPE_CONNECT_CLIENT_ID=ca_your_client_id_here
See Stripe Workflow for complete setup.
Newsletter (Sender.net)¶
SENDER_API_KEY=your_sender_api_key_here
Development Services¶
Start the local development services:
docker-compose up -d
Services:
| Service | Purpose | Local URL |
|---|---|---|
| Mailpit | Email testing (SMTP) | http://localhost:8026/ |
| Gotenberg | PDF generation (dev only) | http://localhost:3003/ |
Note on PDF Generation: - Local development: Uses Gotenberg (Docker) for HTML-to-PDF conversion - Production: Uses Cloudflare Browser Rendering (Puppeteer API)
Running the Application¶
Development Mode (Hot Reload)¶
Start both API and web (recommended):
pnpm dev
Or start individually:
# API (Node.js with tsx)
pnpm --filter @meisterbill/api dev
# Web (Nuxt 3)
pnpm --filter @meisterbill/web dev
Access URLs: - Web: http://localhost:3000 - API: http://localhost:3001 - API Docs: http://localhost:3001/docs
Build for Production¶
# Build shared schemas first
pnpm --filter @meisterbill/schemas build
# Build web
pnpm --filter @meisterbill/web build
# Build API
pnpm --filter @meisterbill/api build
Testing¶
# Web unit tests (Vitest)
pnpm --filter @meisterbill/web test:unit
# API unit tests (Jest)
pnpm --filter @meisterbill/api test
# E2E tests (Playwright)
pnpm e2e
See Testing Guide for details.
Project Structure¶
meister-bill/
├── apps/
│ ├── api/ # Hono + Node.js (dev) / Cloudflare Workers (prod)
│ └── web/ # Nuxt 3 + Vue 3 + Tailwind CSS
├── schemas/ # Shared Zod schemas (must build first)
├── database/ # PostgreSQL table definitions
└── docs/ # MkDocs documentation
Common Issues¶
Port 3000 already in use¶
The web app defaults to port 3000. If busy, it will prompt for another port:
? Port 3000 is already in use. Try another port? (Y/n)
Or set explicitly:
PORT=3002 pnpm --filter @meisterbill/web dev
Schema changes not reflecting¶
If you modify files in schemas/, rebuild:
pnpm --filter @meisterbill/schemas build
Database connection errors¶
Ensure your Supabase project is active and the SUPABASE_KEY is the service role key.
Security¶
Dependency Auditing¶
Run security audits regularly:
pnpm audit
Vulnerability Fixes via Overrides¶
When transitive dependencies have known vulnerabilities, we use pnpm overrides in package.json:
{
"pnpm": {
"overrides": {
"diff": "^8.0.3",
"minimatch": "^10.2.1",
"tar-fs": "^3.1.1",
"ws": "^8.17.1"
}
}
}
See Also¶
- Tech Stack - Full technology overview
- Project Structure - Codebase layout
- Testing Guide - Running tests
- Cloudflare Workers Deployment - Production deployment
- Stripe Workflow - Payment setup