This document describes how this project works and how to perform common operations.
This is a Bun-powered TypeScript monorepo using Turborepo for orchestration. It contains an ElysiaJS API backend, a React frontend, and a type-safe Eden Treaty client SDK.
bun-elysiajs-starter-turbo-monorepo/
├── apps/
│ ├── backend/ # ElysiaJS API server
│ └── frontend/ # React frontend (Vite, TanStack Router, TanStack Query, Tailwind CSS)
├── packages/
│ ├── tsconfig/ # Shared TypeScript configuration
│ ├── backend-errors/ # Error handling package
│ └── backend-client/ # Eden Treaty client SDK
├── turbo.json # Turbo task configuration
├── package.json # Root workspace definition
├── biome.json # Linting and formatting
└── lefthook.yml # Git hooks
- Runtime: Bun (>= 1.0.0)
- Backend Framework: ElysiaJS
- Frontend: React 19, Vite, TanStack Router, TanStack Query, Tailwind CSS
- Database: PostgreSQL with Kysely (type-safe query builder)
- Validation: Elysia's
tmodule (TypeBox-based, generates OpenAPI schemas) - Logging: LogLayer + @loglayer/elysia (request-scoped logging)
- API Docs: @elysiajs/openapi (Scalar UI at /docs)
- Client SDK: Eden Treaty (type-safe, no code generation)
- Testing: Vitest + Testcontainers
- Linting/Formatting: Biome
- Monorepo: Turborepo + Bun workspaces
bun run start # Start dev mode with watch (turbo watch dev)
turbo watch dev # Same as aboveturbo build # Build all packagesturbo test # Run tests across all packagesturbo run lint # Lint all packages
turbo run verify-types # Type check all packages
# Format specific files
biome check --write --unsafe srcbun run clean # Remove node_modules, turbo cache, dist, .hashes.json
bun run clean:turbo # Remove .turbo directories only
bun run clean:dist # Remove dist directories onlyUse turbo gen to generate boilerplate code:
turbo genSee apps/backend/AGENTS.md for details on available generators.
The Turbo pipeline ensures correct build order:
@internal/backend-errorsbuilds first@internal/backenddepends on backend-errors@internal/backend-clientdepends on backend (imports theApptype for Eden Treaty)apps/frontenddepends on backend-client
For development, build:dev tasks use hash-runner for incremental builds — only rebuilding when source inputs change.
Keep dependencies in sync across packages:
bun run syncpack:update # Update all dependencies
bun run syncpack:format # Format package.json files
bun run syncpack:lint # Check for version mismatchesPre-commit:
- Formats package.json files
- Runs
turbo run lint:stagedon staged TypeScript files
Pre-push:
- Runs type checking (
turbo run verify-types) - Runs full lint (
turbo run lint)