Tech Stack¶
Meister Bill is built with modern, performance-oriented technologies across all layers.
Overview¶
| Layer | Technology |
|---|---|
| Frontend | Nuxt 3 + Tailwind CSS |
| Backend/API | Hono + Cloudflare Workers |
| Shared Types | Zod schemas | | Package Mgmt | pnpm with workspaces | | Database | PostgreSQL (Supabase) | | CI/CD | Gitea with act_runner |
Frontend Technologies¶
Nuxt 3¶
- Purpose: Web application framework
- Features: SSR/SSG support, auto-imports, file-based routing
- Location:
apps/web/
Tailwind CSS + DaisyUI¶
- Purpose: Utility-first CSS framework with component library
- Features: Responsive design, dark mode, customizable themes
- Configuration:
apps/web/tailwind.config.ts
Vue 3¶
- Purpose: Reactive frontend framework
- Features: Composition API, TypeScript support,
Backend Technologies¶
Hono¶
- Purpose: Lightweight web framework
- Features: Fast routing, middleware support, OpenAPI integration
- Location:
apps/api/
Cloudflare Workers¶
- Purpose: Serverless edge runtime
- Features: Zero cold starts, global edge deployment, V8 isolates
- Deploy:
pnpm run deploy(production),pnpm run deploy:staging
Validation & Type Safety¶
Zod V4¶
- Purpose: Runtime type validation and schema definitions
- Features: TypeScript inference, composable schemas, custom validations
- Location:
schemas/(workspace package) - See: Schema Validation Guide
Database¶
PostgreSQL¶
- Purpose: Primary data store
- Features: JSONB support, full-text search, complex queries
- Access: Via Supabase client library
- Schema:
database/tables/
Supabase¶
- Purpose: Database access layer and authentication
- Features: Row-level security, real-time subscriptions, auth
Package Management¶
pnpm Workspaces¶
- Purpose: Monorepo management
- Features: Efficient disk usage, fast installs, workspace protocol
- Configuration:
pnpm-workspace.yaml
Testing Frameworks¶
Vitest¶
- Purpose: Unit testing for frontend
- Used In:
apps/web/,schemas/ - Features: Fast, Vite-native, Jest-compatible API
Jest¶
- Purpose: Unit testing for backend
- Used In:
apps/api/ - Features: Mature, extensive ecosystem, snapshot testing
Playwright¶
- Purpose: End-to-end testing
- Features: Cross-browser support, auto-waiting, trace viewer
State Management¶
XState V5¶
- Purpose: State machine for complex workflows
- Used For: Invoice status, project status, payment workflows
- Benefits: Predictable state transitions, prevents invalid states
Development Tools¶
mise¶
- Purpose: Runtime version management
- Manages: Node.js version (24+)
TypeScript¶
- Purpose: Type-safe JavaScript
- Configuration: Per-workspace
tsconfig.jsonfiles
CI/CD¶
Gitea + act_runner¶
- Purpose: Continuous integration and deployment
- Features: Self-hosted, Docker-based jobs, GitHub Actions compatible
- Configuration:
.gitea/workflows/
Deployment Platform¶
Cloudflare Workers (API)¶
- Purpose: API hosting on edge
- Features: Zero cold starts, 300+ edge locations, auto-scaling
- Environments:
meisterbill-api(production),meisterbill-api-staging(staging) - Config:
apps/api/wrangler.jsonc
Cloudflare Pages (Web)¶
- Purpose: Web application hosting (static + SSR via Functions)
- Features: Global CDN, automatic HTTPS, edge rendering
- Project:
meisterbill-web - Config:
apps/web/wrangler.toml
Additional Services¶
Mailpit (Development)¶
- Purpose: Local email testing
- Interface: http://localhost:8026/
- Use: Testing invoice emails and auth flows
Cloudflare Browser Rendering (PDF Generation)¶
- Purpose: HTML to PDF conversion
- Features: Puppeteer API via Cloudflare Workers
- Use: Generating invoice PDFs (replaces Gotenberg)
- Cost: $0.50 per 1000 renders
Umami Analytics¶
- Purpose: Privacy-friendly web analytics
- Features: GDPR-compliant, self-hosted, no cookies
Performance Optimizations¶
Frontend Bundle Optimization¶
The web application is optimized for fast initial load and Core Web Vitals:
| Optimization | Implementation | Benefit |
|---|---|---|
| Content-Based Chunk Naming | Hash-based filenames for long-term caching | Better caching, CDN optimization |
| CSS Code Splitting | Per-component CSS extraction | Smaller initial CSS payload |
| Terser Minification | Console/debugger removal in production | Smaller bundle size |
| Component Lazy Loading | Lazy prefix for heavy modals |
Load components on-demand |
| Route Rules | Aggressive caching for static pages | Instant repeat visits |
Configuration Details¶
Vite Build Settings (apps/web/nuxt.config.ts):
vite: {
build: {
cssCodeSplit: true,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true, // Remove in production
drop_debugger: true,
},
},
rollupOptions: {
output: {
// Content-based naming for optimal caching
entryFileNames: '_nuxt/[name]-[hash].js',
chunkFileNames: '_nuxt/[name]-[hash].js',
assetFileNames: (assetInfo) => {
const info = assetInfo.name || ''
if (info.endsWith('.css')) return '_nuxt/css/[name]-[hash][extname]'
return '_nuxt/[name]-[hash][extname]'
},
},
},
},
}
Route Caching Strategy:
- Static pages (/, /blog, /glossary, /info): 1-year cache
- Member area: No caching (dynamic content)
- Auth pages: No cache (security)
Lazy Loaded Components:
- LazyCurrencyConversionModal - Heavy currency conversion logic
- LazyImageCropperModal - Image processing functionality
See Also¶
- Development Setup - Getting started with these technologies
- Project Structure - How these technologies are organized
- Testing Guide - Using the testing frameworks
- Cloudflare Workers Deployment - API deployment details