A modern monorepo built with Turborepo, TypeScript, and Next.js.
This Turborepo includes the following packages/apps:
web: a Next.js app@capsule/ui: a React component library shared across applications@capsule/eslint-config: ESLint configurations (includes Next.js, React, and Prettier integration)@capsule/typescript-config: Sharedtsconfig.jsonfiles used throughout the monorepo@capsule/domain: Domain logic and business rules
Each package/app is 100% TypeScript with strict mode enabled.
- TypeScript - Static type checking (strict mode)
- ESLint - Code linting
- Prettier - Code formatting
- Husky - Git hooks
- lint-staged - Run linters on staged files
- commitlint - Enforce conventional commits
- Tailwind CSS - Utility-first CSS framework
- Turborepo - Monorepo build system
- PostgreSQL - Production-ready database
- Docker - Containerization for development and deployment
- Node.js v22.15.0 (LTS)
⚠️ IMPORTANTE: Usa Node 22. Storybook NO funciona con Node 23+ - pnpm 9.0.0 or higher
- Docker & Docker Compose (for database and containerized development)
Este proyecto requiere Node 22. Si tienes Node 23+, usa nvm para cambiar:
# Instalar nvm (si no lo tienes)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Instalar Node 22
nvm install 22.15.0
# El proyecto incluye .nvmrc, simplemente ejecuta:
nvm use
# Verificar versión
node -v # Debe mostrar v22.15.0¿Por qué Node 22? Storybook 9.1.13 no es compatible con Node 23+ debido a dependencias nativas. Ver FAQ.md para más detalles.
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build all apps and packages
pnpm build
# Run linting
pnpm lint
# Run type checking
pnpm check-types
# Format code
pnpm formatDocker provides an isolated development environment with PostgreSQL database.
# 1. Copy environment variables
cp .env.example .env
# 2. Start all services (database + app)
docker compose up -d
# 3. View logs
docker compose logs -f web
# 4. Stop all services
docker compose down- web: Next.js application (http://localhost:3000)
- postgres: PostgreSQL database (localhost:5432)
- pgadmin: Database management UI (http://localhost:5050) - Optional
# Start with pgadmin
docker compose --profile tools up -d
# Access pgAdmin at http://localhost:5050
# Email: admin@capsule.local
# Password: admin# Start services
docker compose up -d # Start in background
docker compose up # Start with logs
# Stop services
docker compose down # Stop and remove containers
docker compose down -v # Stop and remove volumes (deletes database data)
# View logs
docker compose logs -f # Follow all logs
docker compose logs -f web # Follow web app logs
docker compose logs -f postgres # Follow database logs
# Restart a service
docker compose restart web
docker compose restart postgres
# Execute commands inside containers
docker compose exec web pnpm lint # Run lint inside container
docker compose exec postgres psql -U capsule -d capsule_dev # Access database CLI
# Rebuild containers
docker compose build # Rebuild all
docker compose build web # Rebuild web only
docker compose up -d --build # Rebuild and startConnection String:
postgresql://capsule:capsule_dev_password@localhost:5432/capsule_dev
Using psql CLI:
docker compose exec postgres psql -U capsule -d capsule_devUsing pgAdmin:
- Start pgAdmin:
docker compose --profile tools up -d - Open http://localhost:5050
- Login with credentials from
.env - Add server:
- Host:
postgres - Port:
5432 - Database:
capsule_dev - Username:
capsule - Password:
capsule_dev_password
- Host:
This project uses Dotenv Vault for secure environment variable management.
For team members with vault access:
# Login to dotenv vault
npx dotenv-vault login
# Pull environment variables
npx dotenv-vault pullFor local development without vault:
# Copy example file
cp .env.example .env
# Edit .env with your local valuesKey variables:
POSTGRES_USER: Database userPOSTGRES_PASSWORD: Database passwordPOSTGRES_DB: Database nameDATABASE_URL: Full connection stringWEB_PORT: Port for web application
Note: The .env.vault file is encrypted and safe to commit to Git. Your local .env file is gitignored.
This project follows GitHub Flow for branch management:
main (protected branch - always deployable)
↑
└── feat/feature-name # New features
└── fix/bug-description # Bug fixes
└── chore/task-name # Maintenance tasks
└── refactor/description # Code refactoring
└── docs/description # Documentation updates
feat/description- New features or enhancementsfix/description- Bug fixeschore/description- Maintenance tasks (deps, configs, etc.)refactor/description- Code refactoring without functionality changesdocs/description- Documentation updates
-
Create a feature branch from
maingit checkout main git pull origin main git checkout -b feat/your-feature-name
-
Make your changes and commit
- Commits must follow Conventional Commits
- Examples:
feat: add user authentication,fix: resolve login bug - commitlint will validate your commit messages
-
Push your branch
git push -u origin feat/your-feature-name
-
Open a Pull Request
- Go to GitHub and create a PR to
main - CI will automatically run (lint, type-check, format-check)
- All checks must pass before merging
- Go to GitHub and create a PR to
-
Merge to main
- Merge the PR once approved and all checks pass
- Delete the feature branch after merging
We use Conventional Commits:
<type>(<scope>): <subject>
Types:
feat: New feature
fix: Bug fix
docs: Documentation changes
style: Code style changes (formatting, etc.)
refactor: Code refactoring
test: Adding or updating tests
chore: Maintenance tasks
Examples:
git commit -m "feat: add user profile page"
git commit -m "fix: resolve navigation bug on mobile"
git commit -m "chore: update dependencies"The main branch is protected with the following rules:
- ✅ Requires pull request before merging
- ✅ Requires status checks to pass (CI must pass)
- ✅ Requires branches to be up to date before merging
- ❌ No direct pushes to
main
GitHub Actions automatically runs on every push and pull request:
- Lint: ESLint validation across all workspaces
- Type Check: TypeScript type validation
- Format Check: Prettier format validation
See .github/workflows/ci.yml for configuration.
Husky runs automatically before each commit:
- lint-staged: Formats staged files with Prettier
- commitlint: Validates commit message format
capsule/
├── apps/
│ └── web/ # Next.js application
├── packages/
│ ├── ui/ # Shared React components
│ ├── domain/ # Business logic
│ ├── eslint-config/ # Shared ESLint configs
│ └── typescript-config/# Shared TypeScript configs
├── .github/
│ └── workflows/ # GitHub Actions workflows
└── turbo.json # Turborepo configuration
# Development
pnpm dev # Start all apps in dev mode
pnpm dev --filter=web # Start only web app
# Building
pnpm build # Build all apps and packages
pnpm build --filter=web # Build only web app
# Code Quality
pnpm lint # Run ESLint
pnpm check-types # Run TypeScript compiler
pnpm format # Format all files with Prettier
# Git Hooks
pnpm prepare # Install Husky hooks- SETUP.md - Complete current setup and configuration
- ARCHITECTURE.md - Technical decisions and architecture
- FAQ.md - Frequently asked questions with detailed explanations
- TROUBLESHOOTING.md - Problem-solving guide
- packages/ui/README.md - Component library overview
- packages/ui/STRUCTURE.md - Component structure guide
- packages/ui/CONTRIBUTING.md - Contribution guidelines
- packages/tailwind-config/README.md - Design tokens documentation
- Node Version: See FAQ.md for why we use Node 22
- Tailwind v4: See ARCHITECTURE.md for v3 vs v4 differences
- Source vs Dist: See ARCHITECTURE.md for why we export source files