From dffa0980a7d3823b79b14951d555e3c43d0d8500 Mon Sep 17 00:00:00 2001 From: Emiel De Vleeschouwer Date: Sat, 28 Mar 2026 17:37:46 +0100 Subject: [PATCH] docs: improve package READMEs with monorepo setup guidance Add monorepo configuration sections to both biome-config and tsconfig READMEs, explaining config resolution, recommended structure, and common patterns like project references and rule overrides. --- .github/CODEOWNERS | 1 + packages/biome-config/README.md | 120 ++++++++++++++++++++++++++++++-- packages/tsconfig/README.md | 90 +++++++++++++++++++++--- 3 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..f636b67 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Emieldv diff --git a/packages/biome-config/README.md b/packages/biome-config/README.md index 2be3215..d7cc5ee 100644 --- a/packages/biome-config/README.md +++ b/packages/biome-config/README.md @@ -1,6 +1,6 @@ # @nimblestudio/biome-config -Shared [Biome](https://biomejs.dev/) configuration for Nimble projects. +Shared [Biome](https://biomejs.dev/) configuration for Nimble projects. Provides composable presets for formatting, linting, and import organization across different project types. ## Installation @@ -8,6 +8,8 @@ Shared [Biome](https://biomejs.dev/) configuration for Nimble projects. npm install -D @nimblestudio/biome-config @biomejs/biome ``` +> `@biomejs/biome` is a peer dependency (>=2.0.0) and must be installed alongside this package. + ## Usage Create a `biome.json` in your project root and extend the config that matches your project: @@ -49,6 +51,8 @@ Extends the root config with Next.js-specific linting rules: } ``` +> **Note:** The Next.js config sets the React linter domain to `"none"` because Next.js has its own set of rules. Do not combine `next.biome.json` with `react.biome.json` — use one or the other. + ### NestJS Extends the root config with NestJS-specific settings (decorator support, relaxed import types): @@ -63,22 +67,124 @@ Extends the root config with NestJS-specific settings (decorator support, relaxe } ``` +## Monorepo setup + +Biome walks up the directory tree looking for configuration files. In a monorepo, this means you need to be deliberate about where configs live so that packages pick up the right settings. + +### How Biome resolves configuration + +1. Biome starts from the file being checked and walks up directories looking for a `biome.json`. +2. When it finds one, it checks for `"root": true` (the default). If set, resolution stops there. +3. If `"root": false`, Biome merges that config with any parent config found further up the tree. + +This means a monorepo root `biome.json` acts as the base, and each package can layer on its own overrides. + +### Recommended structure + +``` +monorepo/ +├── biome.json ← root config (root: true by default) +├── packages/ +│ ├── web/ +│ │ └── biome.json ← extends root + adds React rules (root: false) +│ ├── api/ +│ │ └── biome.json ← extends root + adds NestJS rules (root: false) +│ └── shared/ +│ └── (no biome.json) ← inherits root config automatically +``` + +### Step 1: Root config + +The monorepo root `biome.json` should extend the base config and serve as the default for all packages: + +```json +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["@nimblestudio/biome-config/root.biome.json"] +} +``` + +Since `"root"` defaults to `true`, Biome will stop here for any package that doesn't have its own `biome.json`. + +### Step 2: Package-level configs + +Packages that need framework-specific rules should add their own `biome.json` with `"root": false`. This tells Biome to merge the package config with the root config found further up the tree: + +```json +{ + "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["@nimblestudio/biome-config/react.biome.json"], + "root": false +} +``` + +Key details: + +- **`"root": false`** is required — without it, Biome stops at this file and won't inherit the root config's formatter and base linter settings. +- **`$schema` path** — In a monorepo with hoisted dependencies, point the schema to the root `node_modules` using a relative path (e.g. `../../node_modules/...`). +- **Only extend the framework config** — The root `biome.json` already extends `root.biome.json`, so the package config only needs to add the framework-specific layer (e.g. `react.biome.json`). Biome merges them automatically. + +### Packages that only need the base config + +If a package doesn't need framework-specific rules, you have two options: + +1. **No `biome.json` at all** — Biome walks up and finds the root config. Simplest approach. +2. **Explicit `biome.json` with `root: false`** — Useful if you want to add package-specific overrides later: + +```json +{ + "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["@nimblestudio/biome-config/root.biome.json"], + "root": false +} +``` + +## Overriding rules + +You can override any setting from the shared configs in your project's `biome.json`. Rules defined later in the file take precedence over extended configs: + +```json +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["@nimblestudio/biome-config/root.biome.json"], + "linter": { + "rules": { + "suspicious": { + "noConsole": "error" + } + } + }, + "formatter": { + "lineWidth": 80 + } +} +``` + ## Available configs | Config | Description | | ------------------- | -------------------------------------------------------- | | `root.biome.json` | Base formatter and linter settings (2-space indent, single quotes, import organization) | | `react.biome.json` | React recommended linting, relaxed a11y rules, Tailwind CSS parsing | -| `next.biome.json` | Next.js recommended linting (disables React rules) | +| `next.biome.json` | Next.js recommended linting (sets React domain to `none`) | | `nest.biome.json` | Unsafe parameter decorators, `useImportType` off | +### Config composition + +The configs are designed to be layered on top of `root.biome.json`: + +- **`root`** — Always required. Provides formatter settings, base linter rules, and import organization. +- **`react`** — Adds React linting and Tailwind CSS support. Use for React apps (Vite, CRA, etc.). +- **`next`** — Adds Next.js linting. Do **not** combine with `react` — Next.js replaces the React domain with its own rules. +- **`nest`** — Adds NestJS support (decorators, relaxed import types). Use for NestJS backends. + ## What's included ### Formatter - 2-space indentation - 120 character line width -- Single quotes +- Single quotes (single quotes in JSX too) - Semicolons as needed - Trailing commas everywhere - Arrow function parentheses always @@ -92,11 +198,11 @@ Extends the root config with NestJS-specific settings (decorator support, relaxe ### Import organization -Imports are automatically organized into groups: +Imports are automatically organized into three groups separated by blank lines: -1. URL and Node.js built-in imports -2. Package imports -3. Alias and relative path imports +1. URL and Node.js built-in imports (`node:`, `https://`) +2. Package imports (`react`, `@nestjs/core`, etc.) +3. Alias and relative path imports (`@/`, `./`, `../`) ## License diff --git a/packages/tsconfig/README.md b/packages/tsconfig/README.md index 2e4a8d1..177d591 100644 --- a/packages/tsconfig/README.md +++ b/packages/tsconfig/README.md @@ -1,6 +1,6 @@ # @nimblestudio/tsconfig -Shared TypeScript configurations for Nimble projects. +Shared TypeScript configurations for Nimble projects. Provides opinionated presets for different project types, all built on a strict base configuration. ## Installation @@ -72,17 +72,87 @@ The base config that all others extend from. Use this directly only if none of t } ``` +## Monorepo setup + +In a monorepo, each package typically has its own `tsconfig.json` that extends one of these presets. TypeScript resolves `extends` from `node_modules`, so as long as `@nimblestudio/tsconfig` is installed (at the root or in the package), it works out of the box. + +### Recommended structure + +``` +monorepo/ +├── packages/ +│ ├── web/ +│ │ └── tsconfig.json ← extends next.json or react-vite.json +│ ├── api/ +│ │ └── tsconfig.json ← extends nest.json +│ └── shared/ +│ └── tsconfig.json ← extends node.json +``` + +### Adding project-specific settings + +Extend a preset and add your own `compilerOptions`, `include`, and `exclude` as needed. Your settings merge with (and override) the preset: + +```json +{ + "extends": "@nimblestudio/tsconfig/next.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "next-env.d.ts"], + "exclude": ["node_modules"] +} +``` + +### Multiple tsconfigs in one package + +Some setups need separate configs for different file sets (e.g. app code vs. tooling config). A common pattern in React Vite projects: + +``` +packages/web/ +├── tsconfig.json ← references the others +├── tsconfig.app.json ← extends react-vite.json (src files) +└── tsconfig.node.json ← extends react-vite-node.json (vite.config.ts) +``` + +The root `tsconfig.json` ties them together with [project references](https://www.typescriptlang.org/docs/handbook/project-references.html): + +```json +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} +``` + ## Available configs -| Config | Extends | Use case | -| ------------------ | -------- | ----------------------------------------- | -| `base.json` | - | Shared base settings (ES2022, strict) | -| `node.json` | base | Node.js projects | -| `nest.json` | node | NestJS projects (decorators, source maps) | -| `next.json` | node | Next.js projects (JSX preserve) | -| `mastra.json` | node | Mastra projects | -| `react-vite.json` | base | React apps with Vite | -| `react-vite-node.json` | node | Vite config / server-side in React Vite | +| Config | Extends | Key settings | +| ---------------------- | -------- | ----------------------------------------------------------------------------- | +| `base.json` | - | ES2022, strict mode, bundler module resolution, isolated modules | +| `node.json` | base | Adds Node.js types, `noEmit: true` | +| `nest.json` | node | Decorators, emit enabled, source maps, nodenext module resolution | +| `next.json` | node | DOM libs, JSX preserve, allows JS files, incremental builds | +| `mastra.json` | node | ES2022 target, bundler resolution, emits to `dist/` | +| `react-vite.json` | base | DOM libs, `jsx: react-jsx`, Vite client types, verbatim module syntax | +| `react-vite-node.json` | node | ES2023, verbatim module syntax, erasable syntax only | + +### Config hierarchy + +``` +base.json +├── node.json +│ ├── nest.json +│ ├── next.json +│ ├── mastra.json +│ └── react-vite-node.json +└── react-vite.json +``` ## License