# Introduction
Developer starter: a Fastify REST API with OpenAPI-generated clients, self-hosted Web2 auth (Web3 on the API, no web wallet UI), and a Cursor-first workflow. Shared packages keep web, mobile, and docs consistent.
LLM-friendly index: [`/llms.txt`](/llms.txt) (table of contents) and [`/llms-full.txt`](/llms-full.txt) (full text dump).
## Explore the docs [#explore-the-docs]
Architecture
Monorepo, API, auth, frontend, observability, and security.
Development
Setup, tooling, packages, and the AI-assisted workflow.
Testing
Vitest, Playwright, and the Product Ready fork-and-run bar.
Deployment
GitHub Actions, Vercel, mobile CI/CD, and publishing.
Architecture Decision Records live under [ADRs](/docs/adrs).
# ADR 001: Monorepo vs Standalone Repositories
## Context [#context]
The project involves multiple front-end applications and backend services that share UI components, TypeScript types, and development tooling.\
Managing these pieces in separate repositories makes synchronization harder and slows down iteration.
We need an architecture that:
* Promotes **code reuse** across UI and backend apps.
* Provides **shared tooling and consistent standards** (linting, formatting, build scripts).
* Simplifies dependency management and CI/CD pipelines.
* Keeps developer experience consistent across the codebase.
## Considered Options [#considered-options]
### Option A – Monorepo (Turborepo) [#option-a--monorepo-turborepo]
All applications and packages coexist in one repository (`apps/*`, `packages/*`), orchestrated by Turborepo.
**Pros**
* Shared UI components, types, and config across apps.
* Unified tooling and faster CI/CD via Turborepo caching.
* Easier developer onboarding and dependency upgrades.
* Consistent standards enforced project-wide.
**Cons**
* Slightly higher repo complexity and workspace management overhead.
* Requires clear ownership boundaries to avoid tight coupling.
### Option B – Standalone Repositories [#option-b--standalone-repositories]
Each app or service lives in its own repo, communicating via published packages or APIs.
**Pros**
* Clean separation of concerns and clearer version boundaries.
* Easier for teams to work independently with isolated pipelines.
**Cons**
* Harder to keep shared dependencies synchronized.
* Requires multiple CI/CD setups.
* Repeated tooling configuration and code duplication.
## Decision [#decision]
Adopt a **Monorepo architecture** using **Turborepo** to orchestrate builds and caching.\
Shared components, utilities, and standards will live under `packages/`, while each app resides under `apps/`.
### TLDR: Comparison Table [#tldr-comparison-table]
| Feature | Monorepo ✅ (Turborepo) | Standalone Repos |
| ------------------------ | ------------------------- | --------------------- |
| **Code reuse** | ✅ Shared components/types | ❌ Requires publishing |
| **Unified tooling** | ✅ Consistent standards | ❌ Multiple configs |
| **CI/CD speed** | ✅ Turborepo caching | ⚠️ Separate pipelines |
| **Dependency sync** | ✅ Automatic | ❌ Manual coordination |
| **Developer onboarding** | ✅ Single repo | ⚠️ Multiple repos |
| **Complexity** | ⚠️ Higher repo complexity | ✅ Simpler per repo |
| **Team independence** | ⚠️ Requires coordination | ✅ Independent work |
**Main reasons:**
* Enables code reuse across UI and backend apps through shared components and types
* Unified tooling and consistent standards across all projects
* Faster CI/CD via Turborepo caching
* Simplified dependency management and easier developer onboarding
## Why Turborepo [#why-turborepo]
Turborepo is not only a parallel script runner. `turbo.json` encodes a multi-hop codegen graph that a zero-config tool cannot infer:
```
@repo/utils#build + @repo/error#build
→ @repo/api#generate:openapi
→ @repo/core#generate
→ @repo/cli#generate
```
Four apps (API, web, mobile, docs) have different env footprints. Swapping Turbo would move that ordering into custom scripts, which is more code to maintain than a declarative `turbo.json`.
**Rejected alternatives:**
* **Nx** — faster at 50+ packages, but adds `project.json` per package and a plugin ecosystem. Wrong direction for this repo size.
* **Moon** — built for polyglot repos (Node + Rust + Go). This repo is all TypeScript.
* **Hand-written shell order** — more code to maintain than the existing task graph.
See [Development Tooling](/docs/development/dev-tooling) for the task graph and `pnpm` commands.
## Related Documentation [#related-documentation]
* [Monorepo Structure](/docs/architecture/monorepo) - Detailed Turborepo organization and package architecture
* [Package Conventions](/docs/development/package-conventions) - Package organization and dependency rules
* [Development Tooling](/docs/development/dev-tooling) - Turbo task graph and lint pipeline
* [Architecture Overview](/docs/architecture) - Technical stack and design decisions
# ADR 002: Backend API Framework & Runtime
## Context [#context]
We need to select a runtime and framework for building the backend API that:
* Supports TypeScript with full type inference
* Provides **portability** - runs anywhere (Vercel, Google Cloud, AWS, on-premises)
* Enables **functional programming** style (no classes, no decorators, pure functions)
* Delivers **excellent developer experience** (fast feedback, intuitive API, minimal boilerplate)
* Offers **production performance** (fast runtime, efficient resource usage)
* Supports **AI-friendly** architecture (clean HTTP contracts, OpenAPI generation)
* Integrates well with our monorepo structure (pnpm, Node.js LTS, ESM-native)
* Has strong ecosystem support and tooling
* Provides **no vendor lock-in** - can migrate between deployment platforms without code changes
* Enables **security controls** - can migrate to environments with KMS, VPC, HSM when needed
## Considered Options [#considered-options]
### Runtime Selection: Node.js vs Bun vs Deno [#runtime-selection-nodejs-vs-bun-vs-deno]
Before selecting a framework, we evaluated runtime environments:
**Node.js LTS (Chosen)** — currently **24.x (Krypton)**, pinned in `.nvmrc`
* **Pros**:
* Long-term support with predictable release cycle
* Battle-tested stability in production environments
* Largest npm ecosystem with 100% package compatibility
* Wide enterprise adoption and professional support available
* Best-in-class tooling (debugging, monitoring, APM: DataDog, New Relic, etc.)
* Universal cloud provider support (AWS, GCP, Azure)
* Mature ESM support
* **Cons**:
* Slower than Bun (but acceptable for stability and ecosystem)
**Bun**
* **Pros**: Very fast, all-in-one runtime and package manager, modern tooling
* **Cons**:
* Compatibility issues with some npm packages
* Smaller ecosystem, less enterprise adoption
* Less mature tooling and monitoring support
* Less predictable for production workloads
**Deno**
* **Pros**: Modern security model, TypeScript-first, good standard library
* **Cons**:
* Smaller ecosystem, less npm compatibility
* Less enterprise adoption
* Steeper learning curve
**Decision: Node.js LTS chosen for stability, ecosystem maturity, and enterprise support over cutting-edge performance.**
### Option A – Fastify (Chosen) [#option-a--fastify-chosen]
Fast and low overhead web framework for Node.js.
**Pros**
* **Portability**: Runs anywhere - Vercel (rapid iteration), Google Cloud Run/Compute, AWS ECS/EC2, on-premises
* **No vendor lock-in**: Standard Node.js app, can migrate from Vercel to GCP/AWS without code changes
* **No cold starts**: Can run as always-on service on Google Cloud Run, Cloud Compute, AWS, or on-premises
* **Performance**: Fast, low overhead, production-ready with Node.js LTS support
* **Flexibility**: Functional, plugin-based architecture (no classes required)
* **Control**: Full control over deployment, data, and infrastructure for sensitive environments
* **Security**: Easy migration to environments with advanced security controls (KMS, VPC, HSM) when needed
* **Plugin ecosystem**: Rich plugin ecosystem including `@fastify/swagger` and `@fastify/swagger-ui` for OpenAPI
* **TypeScript support**: Excellent TypeScript support with type inference
* **Mature ecosystem**: Well-established, battle-tested framework
* **OpenAPI support**: Via plugins for API documentation and AI integration
* **Testing**: Works well with standard Node.js testing tools
**Cons**
* No native Zod integration (requires plugins like `@fastify/type-provider-typebox` or manual validation)
* Less opinionated structure (can be pro or con)
* WebSocket support requires additional setup
### Option B – Hono.js [#option-b--honojs]
Ultrafast web framework for the Edge.
**Pros**
* Very fast performance
* Designed for edge environments and serverless
* Lightweight and minimal
* Good TypeScript support
**Cons**
* Designed for edge/serverless, less suitable for traditional backend applications
* WebSocket support is more limited
* No native Zod integration (requires plugins)
* Less mature OpenAPI generation
* Newer framework with smaller ecosystem
* Less community resources and examples
### Option C – Express.js [#option-c--expressjs]
Minimal and flexible Node.js web framework.
**Pros**
* Very flexible and unopinionated
* Large ecosystem and community
* Simple to get started
* Mature and battle-tested
**Cons**
* Minimal framework requires more boilerplate
* No built-in validation (requires manual setup)
* Less opinionated, leading to inconsistent patterns
* WebSocket support requires additional libraries and setup
* No built-in OpenAPI generation (requires manual setup)
* Testing requires manual setup and mocking infrastructure
* Less TypeScript-first approach
* More manual type definitions needed
* Not ESM-native (requires additional configuration)
* Less suitable for functional programming patterns
## Decision [#decision]
We will use **Node.js LTS** as our runtime and **Fastify** as our backend API framework.
### TLDR: Comparison Table [#tldr-comparison-table]
| Feature | Node.js LTS + Fastify ✅ | Bun + Elysia | Deno + Hono | Express |
| ---------------------------- | --------------------------- | ------------------------- | ------------------------- | ------------------- |
| **Portability** | ✅ Runs anywhere | ⚠️ Bun-specific | ⚠️ Deno-specific | ✅ Runs anywhere |
| **Vendor lock-in** | ✅ None (standard Node.js) | ❌ Bun runtime required | ❌ Deno runtime required | ✅ None |
| **Cold starts** | ✅ None (always-on possible) | ⚠️ Serverless constraints | ⚠️ Serverless constraints | ✅ None |
| **LTS Support** | ✅ Predictable | ⚠️ Fast-moving | ⚠️ Fast-moving | ✅ Predictable |
| **npm Ecosystem** | ✅ 100% compatible | ⚠️ Some issues | ⚠️ Limited | ✅ 100% compatible |
| **Enterprise adoption** | ✅ Widespread | ⚠️ Emerging | ⚠️ Niche | ✅ Widespread |
| **Tooling (APM/monitoring)** | ✅ Best-in-class | ⚠️ Limited | ⚠️ Limited | ✅ Good |
| **Performance** | ✅ Fast | ✅ Very fast | ✅ Fast | ✅ Good |
| **Functional style** | ✅ Plugin-based | ✅ Pure functions | ✅ Functional | ⚠️ Flexible |
| **OpenAPI generation** | ✅ Via plugin | ✅ Built-in | ⚠️ Limited | ❌ Manual |
| **TypeScript inference** | ✅ Good | ✅ Excellent | ✅ Good | ⚠️ Manual types |
| **Migration path** | ✅ Change deployment | ❌ Rewrite needed | ❌ Rewrite needed | ✅ Change deployment |
**Main reasons:**
* **Portability**: Fastify runs as standard Node.js process, can deploy to Vercel, Google Cloud Run, AWS ECS, or on-premises without code changes
* **No vendor lock-in**: Standard Node.js app enables migration from Vercel to GCP/AWS by changing deployment targets only
* **No cold starts**: Can run as always-on service on Google Cloud Run, Compute Engine, AWS ECS, or on-premises
* **Node.js LTS stability**: Long-term support, predictable release cycle, battle-tested stability
* **Ecosystem maturity**: Largest npm ecosystem with 100% package compatibility, wide enterprise adoption
* **Security flexibility**: Easy migration to environments with KMS encryption, VPC isolation, Cloud HSM when needed
* **Performance**: Fast, low overhead, production-ready with excellent resource efficiency
* **Flexibility**: Functional, plugin-based architecture (no classes required) aligns with our architectural values
* **Deployment strategy**: Start on Vercel for rapid iteration, migrate to Google Cloud/AWS for production security
* **Tooling**: Best-in-class debugging, monitoring, and APM tools (DataDog, New Relic, etc.)
* **OpenAPI support**: Via `@fastify/swagger` and `@fastify/swagger-ui` plugins for API documentation and AI integration
## Notes [#notes]
* **Deployment flexibility**: Fastify runs as standard Node.js process with no platform-specific code
* **Shipped path**: Vercel + Fastify. GCP/AWS remain an unresolved **adopter** choice, not Basilic’s destination.
* **Migration path**: application code stays portable via Node + Fastify; changing hosts is an Operations/adopter decision
* Consider framework-agnostic patterns when building shared utilities
* OpenAPI generation via `@fastify/swagger` enables AI tool integration and typed SDK generation
* Functional patterns provide consistent, composable architecture without decorator complexity
* Node.js LTS provides stability and ecosystem support over cutting-edge performance
* Fastify's plugin architecture enables modular, composable route organization
## Related Documentation [#related-documentation]
* [API Development](/docs/architecture/api) - Node.js LTS + Fastify architecture and patterns
* [API Architecture](/docs/architecture/api) - REST API with OpenAPI generation and client generation
* [Portability Strategy](/docs/architecture/portability) - Zero vendor lock-in architecture and migration paths
* [ADR 009: API Architecture](/docs/adrs/009-api-architecture) - API architecture and client generation decisions
# ADR 003: Frontend Apps Framework
## Context [#context]
We need to select a framework for building frontend applications in our monorepo that:
* Supports React (our chosen UI library)
* Provides server-side rendering and routing capabilities
* Integrates well with our monorepo structure
* Has strong ecosystem support and tooling
* Enables fast development and prototyping
## Considered Options [#considered-options]
### Option A – Next.js [#option-a--nextjs]
Full-stack React framework with file-based routing.
**Pros**
* Mature ecosystem with extensive documentation and community support
* Excellent integration with React Server Components
* Strong TypeScript support out of the box
* Built-in optimizations (image optimization, font optimization, etc.)
* File-based routing that's intuitive and easy to understand
* Hot module replacement and fast refresh
* Turbopack for faster builds and development
* Battle-tested in production at scale
* Strong deployment options (Vercel, self-hosted, etc.)
* Works seamlessly with Turbo and pnpm workspaces
* Easy to share components and utilities across apps
**Cons**
* Larger bundle size compared to minimal frameworks
* Some opinionated patterns that may not fit all use cases
* Learning curve for React Server Components and App Router
### Option B – TanStack Start [#option-b--tanstack-start]
Full-stack React framework with file-based routing and streaming SSR, built by the TanStack team.
**Pros**
* Streaming SSR capabilities with excellent performance
* Modern React patterns and hooks-first approach
* File-based routing similar to Next.js
* Built on Vite for fast development and builds
* Strong TypeScript support
* Flexible and unopinionated architecture
* Excellent developer experience with TanStack Router integration
* Lightweight compared to Next.js
* Good integration with TanStack ecosystem (Query, Router, etc.)
* Built-in support for React Server Components
* Progressive enhancement and streaming capabilities
**Cons**
* Newer framework with smaller ecosystem compared to Next.js
* Less community resources, documentation, and examples
* Fewer third-party integrations and plugins
* Team familiarity with Next.js may require learning curve
* Next.js has more mature tooling and IDE support
* Better integration with design tools and prototyping platforms in Next.js
* Less battle-tested at scale compared to Next.js
* Fewer deployment options and hosting integrations
### Option C – Remix [#option-c--remix]
Full-stack React framework with data loading patterns.
**Pros**
* Strong data loading patterns
* Good developer experience
* Full-stack capabilities
**Cons**
* Remix's data loading patterns are different from Next.js
* Team preference for Next.js's approach to data fetching
* Smaller ecosystem compared to Next.js
* Fewer integrations with design tools and prototyping platforms
### Option D – Vite + React Router [#option-d--vite--react-router]
Build tool with client-side routing.
**Pros**
* Fast development server
* Flexible routing
* Good build performance
**Cons**
* Next.js provides built-in API routes and server-side rendering
* Less setup required for full-stack applications with Next.js
* Next.js includes many optimizations out of the box
* Better support for modern React features (Server Components, etc.)
## Decision [#decision]
We will use **Next.js** as our frontend framework for applications.
### TLDR: Comparison Table [#tldr-comparison-table]
| Feature | Next.js ✅ | TanStack Start | Remix | Vite + React Router |
| --------------------------- | ------------------- | -------------- | ------------ | ------------------- |
| **Ecosystem maturity** | ✅ Extensive | ⚠️ Growing | ✅ Mature | ✅ Mature |
| **React Server Components** | ✅ Excellent | ✅ Supported | ⚠️ Limited | ❌ No |
| **TypeScript support** | ✅ Excellent | ✅ Strong | ✅ Good | ✅ Good |
| **Built-in optimizations** | ✅ Image, font, etc. | ⚠️ Vite-based | ⚠️ Limited | ⚠️ Manual |
| **File-based routing** | ✅ Intuitive | ✅ Similar | ⚠️ Different | ⚠️ Manual |
| **Turbopack** | ✅ Fast builds | ❌ Vite | ❌ Vite | ❌ Vite |
| **Monorepo integration** | ✅ Excellent | ✅ Good | ✅ Good | ⚠️ Manual |
| **Deployment options** | ✅ Many | ⚠️ Limited | ✅ Good | ⚠️ Manual |
| **Community & docs** | ✅ Extensive | ⚠️ Smaller | ✅ Good | ✅ Good |
| **Battle-tested** | ✅ At scale | ⚠️ Newer | ✅ Yes | ✅ Yes |
**Main reasons:**
* Mature ecosystem with extensive documentation and community support
* Excellent integration with React Server Components and strong TypeScript support
* Built-in optimizations (image, font, etc.) and Turbopack for faster development
* Battle-tested in production at scale with strong deployment options
* Works seamlessly with Turbo and pnpm workspaces for monorepo integration
## Notes [#notes]
* TanStack Start may be reconsidered for specific use cases that benefit from its streaming SSR capabilities
* Next.js continues to evolve rapidly with new features and optimizations
* Consider framework-agnostic patterns when building shared components
## Related Documentation [#related-documentation]
* [Frontend Architecture](/docs/architecture/frontend) - Detailed Next.js architecture and component patterns
* [ADR 004: Design System](/docs/adrs/004-design-system) - Shadcn/ui and Tailwind CSS design system decision
* [Architecture Overview](/docs/architecture) - Technical stack and design decisions
# ADR 004: Design System
## Context [#context]
We need to establish a design system approach for our frontend applications that:
* Provides consistent UI components across applications
* Enables rapid prototyping and iteration
* Integrates well with our chosen frontend framework (Next.js)
* Supports modern design patterns and accessibility
* Allows for easy customization and theming
## Considered Options [#considered-options]
### Option A – Shadcn/ui with Tailwind CSS [#option-a--shadcnui-with-tailwind-css]
Copy-paste component library with Tailwind.
**Pros**
* Leveraging v0 for prototyping was a key factor in picking Next.js
* v0 generates Next.js + Shadcn/ui components, enabling fast iteration
* Seamless workflow from AI-generated prototypes to production code
* Components are copied into the codebase, giving full ownership
* No dependency on external component library versions
* Easy to customize and modify components as needed
* No vendor lock-in or breaking changes from library updates
* Utility-first CSS approach enables rapid styling
* Consistent design tokens and spacing system
* Built on Radix UI primitives (accessible by default)
* Well-tested components with good defaults
* Components can be shared through `@repo/ui` package
* Works seamlessly with Next.js and our monorepo structure
**Cons**
* Need to manually update components when Shadcn/ui releases new versions
* Some learning curve for Tailwind CSS utility classes
* Initial setup requires configuring Tailwind and component structure
### Option B – Material-UI / Mantine [#option-b--material-ui--mantine]
Full component libraries.
**Pros**
* Comprehensive component library
* Well-documented
* Large community
**Cons**
* Harder to customize beyond the library's design system
* More opinionated styling that may not match our brand
* Larger bundle sizes with unused components
* External dependency that can introduce breaking changes
* Less control over component implementation
* Potential version conflicts in monorepo
### Option C – Radix UI + Custom Styling [#option-c--radix-ui--custom-styling]
Headless components with custom styling.
**Pros**
* Full control over styling
* Accessible primitives from Radix UI
* Flexible customization
**Cons**
* Requires building all styling from scratch
* More time-consuming than using pre-styled components
* Less rapid prototyping capabilities
* Harder to maintain consistent design patterns
* More effort required for design system documentation
### Option D – Custom Component Library [#option-d--custom-component-library]
Building everything from scratch.
**Pros**
* Complete control over all aspects
* No external dependencies
* Custom to our needs
**Cons**
* Building everything from scratch is time-consuming
* More code to maintain and test
* Slower time to market
* Shadcn/ui provides a solid foundation to build upon
## Decision [#decision]
We will use **Shadcn/ui with Tailwind CSS** as our design system foundation.
### TLDR: Comparison Table [#tldr-comparison-table]
| Feature | Shadcn/ui + Tailwind ✅ | Material-UI/Mantine | Radix UI + Custom | Custom Library |
| ----------------------- | ------------------------ | --------------------- | ------------------ | -------------- |
| **v0 integration** | ✅ Seamless | ❌ Limited | ❌ Limited | ❌ None |
| **Component ownership** | ✅ Full (copy-paste) | ❌ External dependency | ✅ Full | ✅ Full |
| **Customization** | ✅ Easy | ⚠️ Limited | ✅ Full control | ✅ Full control |
| **Bundle size** | ✅ Small (tree-shakeable) | ⚠️ Larger | ✅ Small | ✅ Small |
| **Rapid prototyping** | ✅ Excellent | ✅ Good | ⚠️ Slower | ❌ Slow |
| **Accessibility** | ✅ Radix primitives | ✅ Good | ✅ Radix primitives | ⚠️ Manual |
| **Vendor lock-in** | ✅ None | ❌ Yes | ✅ None | ✅ None |
| **Maintenance** | ⚠️ Manual updates | ✅ Library updates | ⚠️ All custom | ⚠️ All custom |
| **Time to market** | ✅ Fast | ✅ Fast | ⚠️ Slower | ❌ Slow |
**Main reasons:**
* Leveraging v0 for prototyping was a key factor in picking Next.js; v0 generates Next.js + Shadcn/ui components
* Copy-paste philosophy gives full ownership of components with no external dependency versioning
* Easy to customize and modify components as needed without vendor lock-in
* Built on Radix UI primitives (accessible by default) with well-tested components
* Works seamlessly with Next.js and our monorepo structure through `@repo/ui` package
## Notes [#notes]
* v0's integration with Next.js + Shadcn/ui was a significant factor in choosing Next.js
* Components can be customized extensively while maintaining the base structure
* Consider contributing improvements back to Shadcn/ui when appropriate
* Monitor Shadcn/ui updates for new components and improvements
### MCP Server Integration [#mcp-server-integration]
MCP servers complement the v0 workflow for component discovery and installation:
* **shadcnui-official**: Provides canonical component reference for variants, props, and single primitives
* **shadcnui-jpisnice-react**: Provides React blocks and templates for complete page implementations
* MCP servers work alongside v0, enabling both AI-generated prototypes and direct component discovery
* **Note:** `shadcnui-jpisnice-react-native` exists for future React Native support but is not included in the current React workflow
## Related Documentation [#related-documentation]
* [Frontend Architecture](/docs/architecture/frontend) - Next.js and Shadcn/ui component architecture
* [ADR 003: Frontend Framework](/docs/adrs/003-frontend-framework) - Next.js framework selection decision
* [Packages Reference](/docs/development/packages) - UI components reference
# ADR 005: Package Manager Selection
## Context [#context]
We need to select a package manager for our monorepo that:
* Works reliably with workspace dependencies
* Supports Next.js, Fastify, and Turbo monorepo setup
* Handles complex dependency resolution (e.g., `@tailwindcss/postcss` in workspace packages)
* Provides good performance and developer experience
* Is production-ready and well-supported
## Considered Options [#considered-options]
### Option A – pnpm [#option-a--pnpm]
Mature, workspace-optimized package manager.
**Pros**
* Correctly hoists and resolves dependencies across workspace packages
* Handles complex scenarios like `@tailwindcss/postcss` in `@repo/ui` being accessible to `apps/web`
* Uses symlinks and proper node\_modules structure for workspace packages
* Well-tested with Next.js, Fastify, and Turbo
* Mature support for monorepo patterns
* Extensive community adoption and documentation
* Battle-tested in production environments
* Reliable builds without workarounds
* Better tooling support (debugging, monitoring, CI/CD)
* No module resolution issues during builds
* Consistent behavior across development and production
**Cons**
* Slightly slower package installation compared to Bun (acceptable trade-off for reliability)
* Separate package manager and runtime (Node.js for runtime, pnpm for package management)
### Option B – Bun [#option-b--bun]
Fast, all-in-one runtime and package manager.
**Pros**
* Very fast package installation
* All-in-one runtime and package manager
* Modern tooling
**Cons**
* Workspace implementation still maturing compared to pnpm
* Less ecosystem testing for complex monorepo setups with Next.js/Fastify
* Potential module resolution edge cases in monorepo context
* Binary lockfile format (`bun.lockb`) is less debuggable than YAML
* Smaller tooling ecosystem compared to pnpm
* Some compatibility issues with certain Node.js packages
* Less production battle-testing in large-scale monorepos
## Decision [#decision]
We will use **pnpm** as our package manager.
### TLDR: Comparison Table [#tldr-comparison-table]
| Feature | pnpm ✅ | Bun |
| ------------------------ | ------------------------- | ----------------------- |
| **Installation speed** | ✅ Fast | ✅ Very fast |
| **Workspace support** | ✅ Mature | ✅ Mature (2024) |
| **Monorepo reliability** | ✅ Battle-tested | ⚠️ Improving |
| **Runtime** | ⚠️ Separate | ✅ All-in-one |
| **TypeScript support** | ✅ Excellent | ✅ Excellent |
| **Ecosystem testing** | ✅ Extensive | ✅ Growing |
| **Lockfile format** | ✅ YAML (`pnpm-lock.yaml`) | ⚠️ Binary (`bun.lockb`) |
| **CI/CD integration** | ✅ pnpm setup action | ✅ Bun setup action |
| **Production stability** | ✅ Battle-tested | ⚠️ Maturing |
| **Tooling ecosystem** | ✅ Extensive | ⚠️ Growing |
**Main reasons:**
* **Reliable workspace resolution**: Correctly hoists and resolves dependencies across workspace packages, handling complex scenarios like `@tailwindcss/postcss` in `@repo/ui` being accessible to `apps/web`
* **Monorepo maturity**: Well-tested with Next.js, Fastify, and Turbo with mature support for monorepo patterns
* **Production stability**: Battle-tested in production environments with reliable builds and no module resolution issues
* **Ecosystem support**: Extensive community adoption, documentation, and better tooling support for debugging, monitoring, and CI/CD
* **Consistent behavior**: No module resolution workarounds needed, consistent behavior across development and production
* **Zero build issues**: No dependency resolution edge cases or build failures requiring workarounds
## Notes [#notes]
* **Runtime**: We use **Node.js 24.x (LTS Krypton)** for runtime with pnpm for package management
* **Workspace protocol**: pnpm supports `workspace:*` protocol for internal package dependencies
* **Lockfile**: pnpm uses `pnpm-lock.yaml` format (committed to repository)
* **CI/CD**: All GitHub Actions workflows use pnpm setup action
* **Installation**: Use `pnpm install` for dependencies, `pnpm add` for new packages
* **Scripts**: Run scripts with `pnpm run