Comprehensive setup for linting, formatting, type checking, testing, Git hooks, CI/CD, and publishing across TypeScript, Rust, and Python projects.
When to Use This Skill
Use this skill when you need to:
- Initialize tooling for a new TypeScript/Rust/Python project
- Set up monorepo with Nx + pnpm workspaces
- Configure Git hooks with lefthook (conventional commits, pre-commit, pre-push)
- Add GitHub Actions for CI/CD
- Set up automated publishing to npm/crates.io/PyPI
- Configure version bumping and changelog generation with Changesets
- Migrate from Husky to lefthook
- Choose between ESLint+Prettier vs Biome for TypeScript
Quick Start
TypeScript Project
Automated setup:
bash
1./scripts/init_typescript.sh
Choose tooling:
- Biome (recommended) - Fast, all-in-one, modern
- ESLint + Prettier - Traditional, highly configurable
What you get:
- Linting and formatting
- TypeScript strict mode
- Vitest for testing
- Package.json scripts
→ See: references/typescript.md
Rust Project
Manual setup (opinionated configs in assets/):
bash
1# Tools come with Rust
2rustup component add rustfmt clippy
3
4# Optional: Enhanced tooling
5brew install cargo-nextest cargo-deny
6
7# Copy configs from assets/configs/rust/
8cp assets/configs/rust/rustfmt.toml .
9cp assets/configs/rust/clippy.toml .
→ See: references/rust.md
Python Project
Using uv (recommended):
bash
1# Install uv
2brew install uv
3
4# Create project
5uv init my-project
6cd my-project
7
8# Add dev dependencies
9uv add --dev ruff mypy pytest
10
11# Copy config from assets/
12cp assets/configs/python/pyproject.toml .
→ See: references/python.md
Monorepo Setup
Create Nx + pnpm monorepo:
bash
1./scripts/init_monorepo.sh
Or manually:
bash
1npx create-nx-workspace@latest my-monorepo
2# Choose: pnpm + integrated monorepo
→ See: references/monorepo.md
Workflow Decision Tree
1. Choose Project Type
Single Language Project
→ Use language-specific init script or manual setup
→ See Quick Start above
Monorepo (Multiple Packages)
→ Set up Nx + pnpm workspaces
→ See references/monorepo.md
Automated setup:
bash
1./scripts/setup_lefthook.sh
This configures:
- commit-msg - Conventional commits validation
- pre-commit - Format and lint staged files
- pre-push - Full validation (lint, type-check, test, build)
→ See: references/git-hooks.md
3. Set Up CI/CD
Copy workflow templates:
bash
1# Basic CI
2cp assets/workflows/ci.yml .github/workflows/
3
4# Language-specific workflows available in assets/
→ See: references/ci-cd.md
For npm packages:
bash
1./scripts/setup_changesets.sh
Then copy publishing workflows from assets/workflows/.
→ See:
Language-Specific Guides
TypeScript/JavaScript
Tooling options:
- Biome - Fast, opinionated, all-in-one (recommended for new projects)
- ESLint + Prettier - Traditional, highly configurable (recommended for existing projects)
Testing:
- Vitest - Modern, fast, Vite-based (recommended)
- Jest - Established, widely used
Key decisions:
- Choose Biome for speed and simplicity
- Choose ESLint+Prettier for existing projects or specific plugins
→ Full guide: references/typescript.md
Rust
Built-in tools:
rustfmt - Code formatting
clippy - Linting
cargo test - Testing
Enhanced tools:
cargo-nextest - Faster test runner
cargo-deny - Dependency security
cargo-make - Task runner
→ Full guide: references/rust.md
Python
Modern stack (recommended):
- uv - Fast package manager
- ruff - Fast linting + formatting (replaces black, isort, flake8)
- mypy - Type checking
- pytest - Testing
→ Full guide: references/python.md
Git Hooks with lefthook
Why lefthook?
- Language-agnostic - Works across TS, Rust, Python
- Fast - Parallel execution, written in Go
- Simple - Single YAML config
- Better than Husky - Faster, works across languages
Setup
Automated:
bash
1./scripts/setup_lefthook.sh
Manual:
bash
1brew install lefthook
2lefthook install
Configuration Example
lefthook.yml:
yaml
1commit-msg:
2 commands:
3 commitlint:
4 run: npx commitlint --edit {1}
5
6pre-commit:
7 parallel: true
8 commands:
9 format:
10 glob: "*.{ts,rs,py}"
11 run: format-staged-files {staged_files}
12 stage_fixed: true
13
14pre-push:
15 commands:
16 validate:
17 run: ./scripts/validate_all.sh
→ Full guide: references/git-hooks.md
Monorepo Management
Nx + pnpm Workspaces
Key principle: Nx builds on top of pnpm, doesn't replace it.
- pnpm workspaces - Dependency management
- Nx - Task orchestration, caching, affected commands
Benefits
- Run tasks only for affected packages
- Intelligent caching
- Parallel execution
- Supports multiple languages
Common Commands
bash
1# Run target for all packages
2nx run-many --target=build --all
3
4# Run only for affected
5nx affected --target=test
6
7# Visualize dependencies
8nx graph
→ Full guide: references/monorepo.md
Version Management & Publishing
Changesets Workflow
Recommended for monorepos and npm packages.
- Add changeset:
bash
1pnpm changeset
2# Select packages, type (major/minor/patch), write summary
- Version packages:
bash
1pnpm changeset version
2# Updates package.json, generates CHANGELOG.md
- Publish:
bash
1pnpm changeset publish
2git push --follow-tags
Automated Publishing
Use GitHub Actions to automate releases:
Copy workflow:
bash
1cp assets/workflows/publish-changesets.yml .github/workflows/
This creates "Version Packages" PR on main when changesets exist.
→ See:
CI/CD Setup
Match Local Validation
Best practice: Run same checks in CI as local pre-push hook.
GitHub Actions templates:
ci.yml - Basic linting, testing, building
publish-npm.yml - Automated npm publishing
publish-crates.yml - Automated crates.io publishing
publish-pypi.yml - Automated PyPI publishing
Matrix Testing
Test across multiple versions:
yaml
1strategy:
2 matrix:
3 node-version: [18, 20, 21]
4 os: [ubuntu-latest, macos-latest]
Nx Monorepo CI
Use affected commands to only test changed packages:
bash
1nx affected --target=test
2nx affected --target=build
→ Full guide: references/ci-cd.md
Common Tasks
Initialize TypeScript Project
Automated:
bash
1./scripts/init_typescript.sh --biome
2# or
3./scripts/init_typescript.sh --eslint-prettier
Creates:
- tsconfig.json (strict mode)
- Linting config (biome.json or eslint.config.js)
- Formatting config (.prettierrc.json if ESLint)
- Testing config (vitest.config.ts)
- Package.json scripts
Set Up Git Hooks
bash
1./scripts/setup_lefthook.sh
Configures:
- Conventional commits validation
- Pre-commit: lint/format staged files
- Pre-push: full validation
bash
1./scripts/setup_changesets.sh
Sets up:
- .changeset/ directory
- Package.json scripts
- Public access configuration
Full Validation
bash
1./scripts/validate_all.sh
Runs:
- Format checking
- Linting
- Type checking
- Tests
- Builds
Bundled Resources
Scripts (scripts/)
Setup scripts:
init_typescript.sh - Initialize TypeScript project
setup_lefthook.sh - Configure Git hooks
setup_changesets.sh - Set up version management
validate_all.sh - Run all checks (used by pre-push)
Usage:
bash
1./scripts/script_name.sh
All scripts check if tools are installed/up-to-date before proceeding.
Config Templates (assets/configs/)
TypeScript:
tsconfig.strict.json - Strict TypeScript config
biome.json - Biome configuration
eslint.config.js - ESLint flat config
.prettierrc.json - Prettier configuration
Rust:
rustfmt.toml - Rustfmt configuration
clippy.toml - Clippy lints
deny.toml - Cargo-deny configuration
Python:
pyproject.toml - ruff, mypy, pytest config
ruff.toml - Standalone ruff config
Monorepo:
nx.json - Nx configuration
pnpm-workspace.yaml - pnpm workspaces
Git Hooks:
lefthook.yml - Complete lefthook config
commitlint.config.js - Conventional commits
GitHub Workflows:
ci.yml - Basic CI
publish-changesets.yml - Automated releases
publish-npm.yml - npm publishing
publish-crates.yml - crates.io publishing
publish-pypi.yml - PyPI publishing
Reference Documentation (references/)
Language guides:
typescript.md - ESLint+Prettier vs Biome, testing, monorepo
rust.md - rustfmt, clippy, cargo-nextest, cargo-deny
python.md - ruff, mypy, pytest, uv vs poetry
Infrastructure:
monorepo.md - Nx + pnpm workspaces setup
git-hooks.md - lefthook configuration
ci-cd.md - GitHub Actions workflows
publishing.md - npm, crates.io, PyPI publishing
version-management.md - Changesets workflow
Best Practices
- Use lefthook over Husky - Faster, language-agnostic
- Match CI and local - Same checks in pre-push and CI
- Choose Biome for new TS projects - Faster, simpler
- Use Nx affected commands - Only test changed packages
- Automate versioning - Use Changesets for npm packages
- Conventional commits - Enables automated changelogs
- Pre-commit: staged files - Fast feedback
- Pre-push: full validation - Catch issues before pushing
- Type-check everything - TypeScript, mypy, clippy
- Test before publish - Always run tests in pre-publish
Troubleshooting
Hooks Not Running
Check installation:
bash
1lefthook install
2ls -la .git/hooks/
Test manually:
bash
1lefthook run pre-commit
ESLint + Prettier conflicts:
- Ensure
eslint-config-prettier is last in config
- Run Prettier separately from ESLint
Biome + Prettier conflicts:
- Don't use both - choose one
- Biome is drop-in Prettier replacement
CI Failures
Debugging:
- Run
./scripts/validate_all.sh locally
- Check CI runs same commands
- Verify Node/Rust/Python versions match
- Check caching is working
Quick Reference
Setup new TypeScript project:
bash
1./scripts/init_typescript.sh
Setup Git hooks:
bash
1./scripts/setup_lefthook.sh
Setup Changesets:
bash
1./scripts/setup_changesets.sh
Run full validation:
bash
1./scripts/validate_all.sh
Common commands:
bash
1# TypeScript
2npm run lint && npm run type-check && npm test
3
4# Rust
5cargo fmt -- --check && cargo clippy -- -D warnings && cargo test
6
7# Python
8ruff check . && mypy . && pytest
9
10# Monorepo
11nx affected --target=test
12nx run-many --target=build --all
13
14# Changesets
15pnpm changeset
16pnpm changeset version
17pnpm changeset publish
Getting Help