mise manages Node.js and Yarn versions per-project.
mise.toml
[tools]
node = "latest"
yarn = "latest"Install with brew install mise, then run mise install in the project root to activate the correct runtimes. mise replaces nvm/fnm/volta for Node version management.
Yarn 4 (Berry) with node-modules linker.
.yarnrc.yml
nodeLinker: node-modulesSet in package.json:
{
"packageManager": "yarn@4.9.2"
}Enable with corepack enable then yarn set version stable.
{
"private": true,
"type": "module",
"main": "dist/index.js",
"scripts": {
"format:fix": "biome check --error-on-warnings --write .",
"check": "biome check --error-on-warnings .",
"typecheck": "tsc --noEmit"
}
}Version: ^5.8.3
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowJs": false,
"noEmit": true,
"sourceMap": true,
"declaration": true,
"declarationMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowImportingTsExtensions": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Key choices:
- ES2022 target/module — modern baseline with top-level await,
Array.at(), etc. strict: trueplus extra strictness flags (noUnusedLocals,noUnusedParameters,noImplicitReturns,noFallthroughCasesInSwitch)noEmit: true— TypeScript is used for type checking only; Vite/ts-node handle compilationallowImportingTsExtensions: true— allowsimport "./foo.ts"style imports (requiresnoEmit)moduleResolution: "node"— standard Node resolution
Version: ^2.1.2
biome.json
{
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
"files": {
"includes": [
"src/**/*",
"*.ts",
"*.tsx",
"*.js",
"*.jsx",
"*.json"
],
"ignoreUnknown": true
},
"linter": {
"domains": {
"project": "recommended",
"test": "recommended"
},
"rules": {
"style": "warn",
"correctness": "error",
"nursery": {
"noTsIgnore": "error",
"noFloatingPromises": "error",
"noShadow": "error",
"noSecrets": {
"level": "error",
"options": {
"entropyThreshold": 60
}
}
}
}
},
"formatter": {
"indentStyle": "space",
"indentWidth": 2
},
"overrides": [
{
"includes": ["**/*"],
"linter": {
"rules": {
"correctness": {
"noNodejsModules": "off"
},
"style": {
"noProcessEnv": "off"
}
}
}
}
]
}Key choices:
--error-on-warningsflag in scripts — treats warnings as errors in CI/scripts so nothing slips through- Nursery rules enabled:
noTsIgnore,noFloatingPromises,noShadow,noSecrets— catches common bugs that the stable ruleset misses noNodejsModules: off— needed for Node.js backend code (Biome defaults to browser context)noProcessEnv: off— allowsprocess.envaccess directly- Space indent, width 2
Version: ^7.0.5
Dev dependencies for a React + Tailwind setup:
{
"@vitejs/plugin-react": "^4.7.0",
"@tailwindcss/vite": "^4.1.11",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.11",
"vite": "^7.0.5"
}No vite.config.ts is present in this project yet — use Vite defaults or configure as needed.
Used to run TypeScript scripts directly:
{
"dependencies": {
"ts-node": "^10.9.2"
}
}Run scripts with: yarn ts-node src/scripts/my-script.ts
lefthook.yml
pre-commit:
parallel: true
commands:
biome:
glob: "*.{js,ts,jsx,tsx,json,jsonc,css}"
run: ./node_modules/.bin/biome check --error-on-warnings --staged
tsc:
glob: "*.{js,ts,tsx,jsx}"
run: ./node_modules/.bin/tsc --noEmit
todos:
tags: style
run: OUTPUT=$(grep -r "TODO" {staged_files} | tee /dev/stderr | wc -l) && test $OUTPUT -eq 0Three parallel pre-commit checks:
- Biome — lint + format on staged files only
- TypeScript — full type check
- TODO check — prevents committing TODO comments
Install with brew install lefthook then lefthook install.
brew install mise lefthook- Create
mise.tomlwith Node and Yarn tools, thenmise install corepack enable && yarn inityarn set version stable- Create
.yarnrc.ymlwithnodeLinker: node-modules yarn add -D typescript @biomejs/biome- Copy
tsconfig.jsonandbiome.jsonfrom above - Add scripts to
package.json(check,format:fix,typecheck) lefthook installand copylefthook.ymlfrom above- For frontend:
yarn add -D vite @vitejs/plugin-react tailwindcss @tailwindcss/vite autoprefixer postcss - For scripts:
yarn add ts-node