Tech Stack

Meister Bill is built with modern, performance-oriented technologies across all layers.

Overview

Layer Technology
Frontend Nuxt 4 + Tailwind CSS 4 + DaisyUI 5
Backend/API Hono on Node.js 24 (Docker image)
Shared Types Zod v4 schemas
Package Mgmt pnpm with workspaces
Database PostgreSQL 18 (Docker locally, hoststack.dev staging/prod)
ORM Prisma 7
Auth Better Auth (JWT + passkeys)
CI/CD Gitea with act_runner

Frontend Technologies

Nuxt 4

  • Purpose: Web application framework
  • Features: SSR/SSG support, auto-imports, file-based routing
  • Location: apps/web/

Tailwind CSS 4 + DaisyUI 5

  • Purpose: Utility-first CSS framework with component library
  • Features: Responsive design, dark mode, customizable themes

Vue 3

  • Purpose: Reactive frontend framework
  • Features: Composition API, TypeScript support, <script setup>

Backend Technologies

Hono

  • Purpose: Lightweight web framework
  • Features: Fast routing, middleware support, OpenAPI integration
  • Location: apps/api/

Node.js 24 (Docker)

  • Purpose: Server runtime
  • Features: native fetch, native crypto, native test runner
  • Deploy: Multi-stage Dockerfile at apps/api/Dockerfile, image runs node dist/index.js
  • Locally: pnpm --filter @meisterbill/api dev with hot reload

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 18

  • Purpose: Primary data store
  • Features: JSONB support, full-text search, complex queries
  • Access: via Prisma 7 (apps/api/src/db/client.ts)
  • Schema: apps/api/prisma/schema.prisma is the single source of truth; migrations in apps/api/prisma/migrations/

Prisma 7

  • Purpose: ORM with auto-generated types from the schema
  • Driver adapter: @prisma/adapter-pg over pg
  • Generated client: apps/api/src/generated/ (regenerable via pnpm --filter @meisterbill/api prisma generate)

Authentication

Better Auth

  • Purpose: Email+password auth, JWT issuance, passkey WebAuthn
  • Plugins: jwt (1h access tokens), passkey (@better-auth/passkey)
  • Client-side: @simplewebauthn/browser wraps the native WebAuthn API
  • Verification: JWTs verified locally in API middleware (no DB round-trip per request)

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.json files

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