A production-ready TypeScript monorepo template with strict linting, comprehensive testing, and quality controls built-in.
- 🚀 Bun - Fast package manager and runtime
- 📦 Monorepo - Workspace-based package management
- 🔒 TypeScript - Strict type checking with composite projects
- ✅ Vitest - Fast unit, integration, and system testing
- 🔍 ESLint - Maximum strictness with sonarjs, unicorn, and security plugins
- 📊 Code Coverage - 80% minimum threshold with Codecov integration
- 🔄 Code Duplication - Baseline approach with jscpd
- 🎯 vibe-validate - Git-aware validation orchestration
- 🔧 Cross-Platform - Tested on Windows, macOS, and Linux
- 🤖 CI/CD - GitHub Actions with Node 22/24 matrix testing
- 📝 Pre-commit Hooks - Husky integration for quality gates
- Bun (latest version)
- Node.js 22 or 24
- Git
# Clone the repository
git clone https://github.com/jdutton/ts-monorepo-template.git
cd ts-monorepo-template
# Install dependencies
bun install
# Build all packages
bun run build# Run tests
bun test
# Run tests in watch mode
bun test:watch
# Lint code
bun run lint
# Type check
bun run typecheck
# Run full validation (like CI)
bun run validatets-monorepo-template/
├── packages/ # Published packages
│ └── example-utils/ # Example package (replace with your packages)
│ ├── src/ # Source code
│ ├── test/ # Tests
│ ├── package.json
│ └── tsconfig.json
├── tools/ # Development tools (TypeScript)
│ ├── common.ts # Shared utilities
│ ├── duplication-check.ts
│ ├── jscpd-check-new.ts
│ └── jscpd-update-baseline.ts
├── docs/ # Documentation
├── .github/ # CI/CD workflows
│ └── workflows/
│ └── validate.yml # Validation pipeline
├── eslint.config.js # ESLint configuration (strict!)
├── vitest.config.ts # Unit test configuration
├── vitest.integration.config.ts # Integration test config
├── vitest.system.config.ts # System test config
├── tsconfig.json # Root TypeScript config
├── tsconfig.base.json # Base config for packages
├── vibe-validate.config.yaml # Validation orchestration
├── package.json # Root package.json
├── CLAUDE.md # AI assistant guidelines
└── README.md # This file
- Create the package directory:
mkdir -p packages/my-package/src packages/my-package/test- Create
packages/my-package/package.json:
{
"name": "@ts-monorepo-template/my-package",
"version": "0.1.0",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"scripts": {
"build": "tsc",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsc --noEmit",
"clean": "rm -rf dist *.tsbuildinfo"
},
"devDependencies": {
"typescript": "^5.9.3",
"vitest": "^3.2.4"
}
}- Create
packages/my-package/tsconfig.json:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}- Add to root
tsconfig.jsonreferences:
{
"references": [
{ "path": "./packages/example-utils" },
{ "path": "./packages/my-package" } // Add this
]
}- Create source and tests:
# Create your source files
touch packages/my-package/src/index.ts
# Create tests
touch packages/my-package/test/index.test.ts- Install and build:
bun install
bun run buildThis project supports three levels of testing:
- Test individual functions/classes
- Fast execution (< 100ms)
- Mock external dependencies
- Run with:
bun test
- Test multiple modules together
- May use real dependencies
- Medium execution (< 5s)
- Run with:
bun test:integration
- End-to-end workflows
- Real external services
- Longer execution (< 30s)
- Run with:
bun test:system
packages/my-package/
├── src/
│ ├── utils.ts
│ └── utils.test.ts # Unit tests (co-located)
└── test/
├── api.test.ts # Unit tests
├── integration/
│ └── workflow.integration.test.ts
└── system/
└── e2e.system.test.ts
This project enforces strict linting rules:
- Zero warnings policy:
--max-warnings=0 - SonarJS: Catches code smells and bugs
- Unicorn: Modern JavaScript patterns
- Security: Prevents common vulnerabilities
- Import organization: Alphabetical with groups
All code (src, tests, tools) is held to the same standards.
Minimum thresholds enforced:
- Statements: 80%
- Branches: 80%
- Functions: 80%
- Lines: 80%
Uses jscpd with a baseline approach:
- Existing duplication is baselined
- New duplication blocks commits
- Update baseline:
bun run duplication-update-baseline
Strict mode enabled with additional checks:
noUncheckedIndexedAccessnoImplicitOverrideexactOptionalPropertyTypes
This project uses vibe-validate for git-aware validation:
# Run all validation checks
bun run validate
# Pre-commit check (fast)
bun run pre-commitValidation runs:
- TypeScript type checking
- ESLint (strict)
- Code duplication check
- Build
- Unit tests
- Integration tests (optional)
- Coverage report
- System tests (optional)
GitHub Actions workflows run on every push/PR:
- Matrix Testing: Node 22/24 × Ubuntu/Windows
- Full Validation: All checks must pass
- Parallel Execution: Faster feedback
- See
.github/workflows/validate.yml
- Codecov Integration: Automatic coverage upload
- 80% Threshold: Project and patch coverage targets
- PR Comments: Coverage diff on pull requests
- See
.github/workflows/coverage.yml
- Sign up at codecov.io with your GitHub account
- Enable your repository
- Add
CODECOV_TOKENto GitHub repository secrets - Coverage reports will be uploaded automatically on push/PR
- Update badge URLs in README.md with your repository details
Husky is configured to run validation before commits:
# Install hooks
bun install # Runs automatically via "prepare" script
# Manually run pre-commit checks
bun run pre-commitWhen you're ready to publish to npm:
- Update package versions
- Build packages:
bun run build - Test thoroughly:
bun run validate - Publish:
npm publish(or create publish scripts)
Replace @ts-monorepo-template with your org name:
# Update package names in:
# - packages/*/package.json
# - Import statementsEdit these files:
vitest.config.ts- Coverage thresholdseslint.config.js- Linting rulesvibe-validate.config.yaml- Validation steps
Add scripts to tools/ directory:
- Use TypeScript (cross-platform)
- Import from
tools/common.ts - Add to package.json scripts
This project includes an example package to validate everything works:
# Run all validation checks
bun run validate
# See full validation checklist
cat docs/template-validation.mdThe example package (packages/example-utils/) has 100% test coverage and demonstrates all patterns. Delete it when you start your own project.
- CLAUDE.md - Detailed development guidelines
- Template Validation - Validate the template setup
- Bun Documentation
- Vitest Documentation
- vibe-validate
- TypeScript
MIT - see LICENSE file
- Fork the repository
- Create a feature branch
- Make your changes
- Run
bun run validateto ensure quality - Submit a pull request
Built with ❤️ using Bun, TypeScript, and modern tooling