Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 200 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<div align="center">

<img src="assets/logo.png" alt="logo" width="200" height="auto" />
<h1>Template</h1>

<p>
Monorepo template with Turborepo and changeset
Modern monorepo template with Turborepo, PNPM, and Changesets
</p>

<!-- Badges -->
Expand Down Expand Up @@ -35,22 +33,209 @@

<br />

<!-- About the Project -->
<!-- Table of Contents -->
## :notebook_with_decorative_cover: Table of Contents

- [About the Project](#star2-about-the-project)
- [Features](#dart-features)
- [Tech Stack](#space_invader-tech-stack)
- [Package Structure](#package-package-structure)
- [Getting Started](#toolbox-getting-started)
- [Prerequisites](#bangbang-prerequisites)
- [Installation](#gear-installation)
- [Running Locally](#running-running-locally)
- [Usage](#eyes-usage)
- [Available Scripts](#available-scripts)
- [Development Workflow](#development-workflow)
- [Contributing](#wave-contributing)
- [License](#warning-license)

<!-- About the Project -->
## :star2: About the Project

<div align="center">
<img src="assets/screenshot.jpg" alt="screenshot" />
</div>
A production-ready monorepo template built with modern tooling and best practices. This template is designed to help you quickly bootstrap TypeScript libraries and applications with a scalable, maintainable structure.

<!-- Features -->

### :dart: Features

- Nx for monorepo graph
- Turborepo + PNPM support
- TypeScript support
- Linting with ESLint, Prettier and Husky(Git hooks)
- Testing with Jest
- ESM and CommonJS builds with TSUP
- Release with changeset
- **🚀 Turborepo v2** - High-performance build system with intelligent caching and parallel execution
- **📦 PNPM Workspaces** - Fast, disk-efficient package manager with workspace support
- **🎨 Biome** - Fast, modern linter and formatter (replacing ESLint + Prettier)
- **🔷 TypeScript 5.9+** - Latest TypeScript with strict type checking
- **⚡ Vitest** - Lightning-fast unit testing with native ESM support
- **📦 tsdown** - Modern TypeScript bundler for ESM and CommonJS builds
- **📋 Changesets** - Automated versioning and changelog generation
- **🔄 Nx Graph** - Visualize your monorepo dependency graph
- **🎯 Type-safe** - End-to-end type safety across all packages
- **📝 Shared Configs** - Centralized TypeScript, Biome, and tsdown configurations

<!-- Tech Stack -->
### :space_invader: Tech Stack

<details>
<summary>Build Tools</summary>
<ul>
<li><a href="https://turbo.build/">Turborepo</a> - v2.7.3</li>
<li><a href="https://pnpm.io/">PNPM</a> - v10.24.0</li>
<li><a href="https://tsdown.vercel.app/">tsdown</a> - TypeScript bundler</li>
</ul>
</details>

<details>
<summary>Language & Runtime</summary>
<ul>
<li><a href="https://www.typescriptlang.org/">TypeScript</a> - v5.9.3</li>
<li><a href="https://nodejs.org/">Node.js</a> - >=20</li>
</ul>
</details>

<details>
<summary>Code Quality</summary>
<ul>
<li><a href="https://biomejs.dev/">Biome</a> - v2.3.11 - Linting & Formatting</li>
<li><a href="https://vitest.dev/">Vitest</a> - v4.0.16 - Testing</li>
</ul>
</details>

<details>
<summary>Versioning & Release</summary>
<ul>
<li><a href="https://github.com/changesets/changesets">Changesets</a> - v2.29.8</li>
</ul>
</details>

<!-- Package Structure -->
### :package: Package Structure

```
packages/
├── config/ # Shared configuration packages
│ ├── biome-config/ # Biome linting & formatting config
│ ├── eslint-config/ # Legacy ESLint config (if needed)
│ ├── ts-config/ # Shared TypeScript configurations
│ └── tsdown-config/ # Shared tsdown build configurations
├── core/ # Core library package
└── demo/ # Demo/example package
```

<!-- Getting Started -->
## :toolbox: Getting Started

<!-- Prerequisites -->
### :bangbang: Prerequisites

This project requires the following to be installed on your system:

- **Node.js** >= 20.0.0
- **PNPM** >= 10.0.0

You can enable PNPM using Corepack (comes with Node.js):

```bash
corepack enable
corepack prepare pnpm@10.24.0 --activate
```

<!-- Installation -->
### :gear: Installation

Clone the repository and install dependencies:

```bash
# Clone the repository
git clone https://github.com/stijnvanhulle/template.git

# Navigate to the directory
cd template

# Install dependencies
pnpm install
```

<!-- Running Locally -->
### :running: Running Locally

Build all packages:

```bash
pnpm run build
```

Watch mode for development:

```bash
pnpm run start
```

<!-- Usage -->
## :eyes: Usage

### Available Scripts

| Script | Description |
|--------|-------------|
| `pnpm run build` | Build all packages in the monorepo |
| `pnpm run clean` | Remove all build artifacts |
| `pnpm run start` | Start all packages in watch mode |
| `pnpm run test` | Run all tests with coverage |
| `pnpm run test:watch` | Run tests in watch mode |
| `pnpm run typecheck` | Type-check all packages |
| `pnpm run lint` | Lint all files with Biome |
| `pnpm run lint:fix` | Auto-fix linting issues |
| `pnpm run format` | Format all files with Biome |
| `pnpm run graph` | Visualize monorepo dependency graph with Nx |
| `pnpm run changeset` | Create a new changeset for versioning |
| `pnpm run version` | Version packages based on changesets |
| `pnpm run release` | Publish packages to npm |

### Development Workflow

1. **Create a new package**: Add a new directory under `packages/`
2. **Make changes**: Develop your features
3. **Test**: Run `pnpm run test` to ensure everything works
4. **Type-check**: Run `pnpm run typecheck` to verify types
5. **Lint**: Run `pnpm run lint:fix` to fix any linting issues
6. **Create changeset**: Run `pnpm run changeset` to document your changes
7. **Build**: Run `pnpm run build` to build all packages
8. **Version**: Run `pnpm run version` to bump versions
9. **Release**: Run `pnpm run release` to publish

#### Adding a Changeset

When you make changes that should be published, create a changeset:

```bash
pnpm run changeset
```

Follow the prompts to:
1. Select which packages have changed
2. Specify the type of change (major, minor, patch)
3. Write a summary of the changes

#### Visualizing Dependencies

View your monorepo's dependency graph:

```bash
pnpm run graph
```

This opens an interactive visualization of how your packages depend on each other.

<!-- Contributing -->
## :wave: Contributing

Contributions are always welcome! Please follow these steps:

1. Fork the repository
2. Create a new branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Commit your changes (`git commit -m 'Add some amazing feature'`)
5. Push to the branch (`git push origin feature/amazing-feature`)
6. Open a Pull Request

<!-- License -->
## :warning: License

Distributed under the MIT License. See `LICENSE` for more information.
50 changes: 24 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,25 @@
"workspaces": {
"packages": [
"packages/*",
"packages/config/eslint-config/*",
"packages/config/biome-config/*",
"packages/config/tsup-config/*",
"packages/config/ts-config/*"
"packages/config/*"
]
},
"scripts": {
"//changeset:beta:enter": "changeset pre enter beta",
"//changeset:beta:exit": "changeset pre exit",
"build": "turbo run build --filter=./packages/*",
"changeset": "changeset",
"clean": "turbo run clean",
"graph": "npx nx graph ",
"install:csb": "corepack enable && pnpm install --frozen-lockfile",
"format": "bun biome format --write ./ && bun format:pack",
"format:pack": "npx sort-package-json package.json",
"graph": "npx nx graph ",
"install:csb": "corepack enable && pnpm install --frozen-lockfile",
"lint": "bun biome lint .",
"lint:case": "npx case-police --fix",
"lint:ci": "bun biome lint .",
"lint:fix": "bun biome lint --apply-unsafe . && bun run lint:case",
"lint:turbo": "turbo run lint",
"version": "changeset version",
"release": "changeset publish",
"version:canary": "changeset version --snapshot canary",
"release:canary": "changeset publish --no-git-tag",
"start": "turbo run start --filter=./packages/*",
"test": "vitest run --config ./configs/vitest.config.ts --coverage",
Expand All @@ -42,30 +40,30 @@
"test:watch": "vitest --config ./configs/vitest.config.ts",
"typecheck": "turbo run typecheck --continue --filter='./packages/*'",
"upgrade": "npx taze -r -w --exclude pnpm",
"changeset": "changeset",
"//changeset:beta:enter": "changeset pre enter beta",
"//changeset:beta:exit": "changeset pre exit"
"version": "changeset version",
"version:canary": "changeset version --snapshot canary"
},
"devDependencies": {
"@biomejs/biome": "^1.6.4",
"@changesets/changelog-github": "^0.5.0",
"@changesets/cli": "^2.27.1",
"@biomejs/biome": "^2.3.11",
"@changesets/changelog-github": "^0.5.2",
"@changesets/cli": "^2.29.8",
"@stijnvanhulle/biome-config": "workspace:*",
"@stijnvanhulle/ts-config": "workspace:*",
"@types/node": "^20.12.5",
"@vitest/coverage-v8": "^1.4.0",
"@vitest/ui": "^1.4.0",
"bun-types": "^1.1.3",
"rimraf": "^5.0.5",
"@types/node": "^20.19.27",
"@vitest/coverage-v8": "^4.0.16",
"@vitest/ui": "^4.0.16",
"bun-types": "^1.3.5",
"rimraf": "^6.1.2",
"ts-node": "^10.9.2",
"turbo": "^1.13.2",
"typescript": "^5.4.4",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.4.0"
"tsdown": "^0.18.4",
"turbo": "^2.7.3",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^6.0.3",
"vitest": "^4.0.16"
},
"packageManager": "pnpm@8.3.0",
"packageManager": "pnpm@10.24.0",
"engines": {
"node": ">=18",
"pnpm": ">=8.3.0"
"node": ">=20",
"pnpm": ">=10.0.0"
}
}
24 changes: 12 additions & 12 deletions packages/config/eslint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.cjs"
},
"./legacy": {
"import": "./dist/legacy.js",
"import": "./dist/legacy.mjs",
"require": "./dist/legacy.cjs",
"default": "./dist/legacy.cjs"
},
"./flat": {
"import": "./dist/flat.js",
"import": "./dist/flat.mjs",
"require": "./dist/flat.cjs",
"default": "./dist/flat.cjs"
},
"./package.json": "./package.json",
"./*": "./*"
},
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "./dist/index.d.ts",
"module": "dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"src",
"dist",
"!/**/**.test.**",
"!/**/__tests__/**"
],
"scripts": {
"build": "tsup",
"build": "tsdown",
"clean": "npx rimraf ./dist",
"lint": "ESLINT_USE_FLAT_CONFIG=true eslint --format pretty .",
"lint-fix": "bun run lint --quiet --fix",
"release": "pnpm publish --no-git-check",
"release:canary": "bash ../../../.github/canary.sh && node ../../../scripts/build.js canary && pnpm publish --no-git-check",
"start": "tsup --watch",
"start": "tsdown --watch",
"typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
},
"dependencies": {
Expand All @@ -62,15 +62,15 @@
},
"devDependencies": {
"@stijnvanhulle/ts-config": "workspace:*",
"@stijnvanhulle/tsup-config": "workspace:*",
"@stijnvanhulle/tsdown-config": "workspace:*",
"eslint": "^8.55.0",
"tsup": "^8.0.1",
"tsdown": "^0.18.4",
"typescript": "~5.2.2"
},
"packageManager": "pnpm@8.3.0",
"packageManager": "pnpm@10.24.0",
"engines": {
"node": ">=18",
"pnpm": ">=8.3.0"
"node": ">=20",
"pnpm": ">=10.0.0"
},
"publishConfig": {
"access": "public",
Expand Down
Loading
Loading