A comprehensive guide for developers working on the Tentix project, covering essential concepts, best practices, and learning resources for modern monorepo development.
- Core Technologies Overview
- Development Prerequisites
- Key Development Concepts
- Best Practices & Guidelines
- Common Pitfalls & Solutions
- Performance Considerations
- Learning Resources
- References
Bun is a fast JavaScript runtime and package manager that serves as the foundation of our development stack. It provides significant performance improvements over traditional Node.js and npm workflows.
Key Features:
- Ultra-fast package installation - 28x faster than npm, 12x faster than Yarn
- Built-in bundler - No need for separate build tools in many cases
- Native TypeScript support - Direct execution of TypeScript files
- Workspace management - First-class monorepo support
Important Notes:
- This project exclusively uses Bun as the package manager
- Do not use npm, yarn, or pnpm - they will cause dependency conflicts
- Always use
bun installinstead ofnpm install
Turborepo orchestrates our monorepo build system, providing intelligent caching and task execution.
Key Concepts:
- Internal Packages - Shared libraries within the monorepo
- Task Graphs - Dependency-aware task execution
- Remote Caching - Shared build artifacts across team members
- Incremental Builds - Only rebuild what has changed
Hono powers our backend API with a focus on performance and developer experience.
Key Features:
- RPC (Remote Procedure Call) - Type-safe client-server communication
- Middleware ecosystem - Comprehensive request/response handling
- Edge runtime compatibility - Works across different JavaScript runtimes
- OpenAPI integration - Automatic API documentation generation
Before contributing to this project, developers should be familiar with:
- TypeScript - Advanced type system usage, generics, and utility types
- React 19 - Latest features including concurrent rendering and server components
- Modern JavaScript - ES2022+ features, async/await, modules
- Monorepo concepts - Package dependencies, workspace management
- Database fundamentals - SQL, migrations, ORM concepts
# Required versions
Node.js >= 20
Bun >= 1.2.16
PostgreSQL >= 14
Docker (optional but recommended)
# Verify installations
bun --version
node --version
psql --versionOur monorepo uses Bun workspaces to manage dependencies and shared code:
{
"name": "tentix-v2",
"workspaces": ["frontend", "server", "packages/*"]
}Best Practices:
- Use
workspace:*protocol for internal dependencies - Keep shared packages in the
packages/directory - Avoid circular dependencies between packages
We use Turborepo's Just-in-Time Packages approach for maximum development speed:
- TypeScript files are consumed directly by applications
- No build step required for internal packages
- Faster development iteration cycles
- Simplified configuration
Trade-offs to Consider:
- Cannot use TypeScript
pathsconfiguration - Build caching is limited to applications
- Type errors propagate across package boundaries
For large-scale TypeScript development, we implement project references to:
- Enforce project boundaries - Prevent arbitrary imports
- Enable incremental compilation - Faster type checking
- Improve IDE performance - Better intellisense and navigation
- Support build orchestration - Dependency-aware compilation
Configuration Structure:
tsconfig.json (root)
├── tsconfig.options.json (shared compiler options)
├── frontend/tsconfig.json
├── server/tsconfig.json
└── packages/*/tsconfig.json
Our API uses Hono's RPC feature for end-to-end type safety:
// Server-side route definition
const route = app.post("/api/tickets", zValidator("json", ticketSchema), (c) =>
c.json({ success: true }),
);
// Export type for client consumption
export type AppType = typeof route;
// Client-side usage with full type safety
const client = hc<AppType>("http://localhost:3000");
const result = await client.api.tickets.$post({
json: { title: "New ticket" },
}).then(r => r.json());- Feature-based structure - Group related files by feature, not by type
- Barrel exports - Use index files to create clean import paths
- Consistent naming - Use kebab-case for files, PascalCase for components
- Type definitions - Keep types close to their usage
- Migration-first approach - Always create migrations for schema changes
- Seed data management - Use scripts for consistent test data
- Environment isolation - Separate databases for dev/test/prod
- Backup strategies - Regular backups before destructive operations
- Environment variables - Never commit secrets to version control
- Input validation - Validate all user inputs using Zod schemas
- Authentication - Implement proper JWT token management
- Rate limiting - Protect APIs from abuse
- Bundle analysis - Regular monitoring of bundle sizes
- Database indexing - Optimize queries with proper indexes
- Caching strategies - Implement appropriate caching layers
- Lazy loading - Load components and data on demand
Problem: Using different package managers causes lockfile conflicts.
Solution:
- Always use
bun install - Delete
node_modulesand other lockfiles if switching from npm/yarn - Add
.npmrcwithpackage-manager=bunto enforce usage
Problem: Complex tsconfig inheritance causing compilation errors.
Solutions:
- Use project references for large codebases
- Keep shared options in
tsconfig.options.json - Avoid circular references between projects
- Use
tsc --build --verbosefor debugging
Problem: Internal packages not resolving correctly.
Solutions:
- Verify
workspace:*syntax in package.json - Run
bun installafter adding new dependencies - Check that package names match directory names
- Use absolute imports with proper path mapping
Problem: Schema changes breaking existing data.
Solutions:
- Always backup before migrations
- Test migrations on sample data first
- Use reversible migration patterns
- Document breaking changes clearly
- Incremental compilation - Use TypeScript project references
- Parallel execution - Leverage Turborepo's task parallelization
- Selective builds - Only build affected packages
- Cache optimization - Configure proper cache keys
- Bundle splitting - Separate vendor and application code
- Tree shaking - Eliminate unused code
- Image optimization - Use appropriate formats and sizes
- Database optimization - Optimize queries and use connection pooling
- Hot reloading - Fast feedback during development
- Type checking - Separate type checking from compilation
- Linting - Fast, incremental linting
- Testing - Parallel test execution
- Bun Official Documentation - Comprehensive guide to Bun runtime and package manager
- Bun Workspaces Guide - Detailed workspace configuration and management
- Performance Benchmarks - Understanding Bun's speed advantages
- Turborepo Core Concepts - Internal packages, task graphs, and caching strategies
- Repository Crafting Guide - Best practices for structuring monorepos
- Package Compilation Strategies - Just-in-time vs compiled vs publishable packages
- Project References - Scaling TypeScript in large codebases
- Module Resolution - Understanding how TypeScript finds modules
- Performance Optimization - Techniques for faster compilation
- Hono RPC Guide - Type-safe client-server communication
- React 19 Features - Latest React capabilities and patterns
- Database Design - PostgreSQL optimization and best practices
- Set up development environment
- Understand Bun basics and workspace concepts
- Learn Turborepo fundamentals
- Study project references implementation
- Practice advanced TypeScript patterns
- Configure optimal development setup
- Master Hono RPC patterns
- Implement type-safe API communication
- Optimize build and development workflows
- Learn deployment strategies
- Implement monitoring and logging
- Optimize performance and security
- Start Small - Create a simple monorepo with 2-3 packages
- Experiment - Try different compilation strategies
- Measure - Compare build times and bundle sizes
- Iterate - Refine configuration based on learnings
- Discord Communities - Join Bun, Turborepo, and Hono Discord servers
- GitHub Discussions - Participate in project discussions
- Stack Overflow - Search for specific technical issues
- YouTube Tutorials - Visual learning for complex concepts
-
"Cannot find module" errors
- Check workspace configuration
- Verify package.json names match directory names
- Run
bun installto refresh dependencies
-
TypeScript compilation errors
- Use
tsc --build --verbosefor detailed output - Check project references configuration
- Verify tsconfig inheritance chain
- Use
-
Build performance issues
- Enable Turborepo caching
- Use project references for TypeScript
- Optimize task dependencies
-
Database connection issues
- Verify environment variables
- Check PostgreSQL service status
- Validate connection string format
- Verbose logging - Enable detailed output for all tools
- Incremental testing - Isolate issues to specific components
- Clean rebuilds - Remove cache and node_modules when stuck
- Version verification - Ensure all tools are at required versions
- Bun Runtime - Fast JavaScript runtime and package manager
- Bun Workspaces Guide - Monorepo configuration with Bun
- Turborepo Internal Packages - Package management strategies
- Turborepo Repository Guide - Best practices for monorepo structure
- Hono RPC Documentation - Type-safe client-server communication
- TypeScript Project References - Official TypeScript documentation
- Modern React, Bun & Hono Tutorial - Drizzle, Kinde, Tailwind, Tanstack, TypeScript, RPC, and more - A practices for Modern Devlopment
- TypeScript Monorepo Best Practices - Chinese community insights on monorepo development
- Bun vs npm Performance - Detailed benchmarks and comparisons
- TypeScript Project References Performance - Comprehensive guide to TypeScript optimization
Happy Coding! 🎉
This guide is a living document. Please contribute improvements and updates as you learn and discover new best practices.