Skip to main content
Ship uses Husky and lint-staged to automatically validate and auto-fix the entire project before each commit, ensuring consistent code quality across the codebase.

How It Works

When you commit changes, Husky triggers a pre-commit hook that runs lint-staged. The configuration runs linters on the entire project to ensure project-wide code quality.
The pre-commit hook is automatically installed when you run pnpm install via the prepare script.
Project-wide Validation: Ship intentionally runs linters on ALL project files (using .), not just staged files. This defensive approach ensures that if someone bypassed hooks with --no-verify, the next commit will auto-fix those issues and prevent blocking other team members.

Configuration

API

"lint-staged": {
  "*.ts": [
    "eslint . --fix",
    "bash -c 'tsc --noEmit'",
    "prettier . --write"
  ]
}
When any .ts file is staged, runs on entire project:
  1. ESLint - Auto-fixes all .ts files (note the .)
  2. TypeScript - Type checks all files
  3. Prettier - Formats all files (note the .)

Web

"lint-staged": {
  "*.{ts,tsx}": [
    "eslint . --fix",
    "bash -c 'tsc --noEmit'",
    "prettier . --write"
  ]
}

Packages

All shared packages (schemas, mailer, app-types, etc.) have similar lint-staged configurations tailored to their file types.

Customization

Modify Linters

Edit lint-staged in your package.json:
"lint-staged": {
  "*.ts": [
    "eslint . --fix",       // The '.' runs on entire project
    "prettier . --write"    // The '.' formats all files
    // Add or remove tools as needed
  ]
}

Run on Staged Files Only (Alternative)

If you prefer to only lint staged files instead of the entire project:
"lint-staged": {
  "*.ts": [
    "eslint --fix",         // No '.' - only staged files
    "prettier --write"      // No '.' - only staged files
  ]
}
Linting only staged files means errors in other parts of the codebase (e.g., from --no-verify commits) won’t be caught or fixed until those files are modified.

Skip Hooks Temporarily

# Bypass pre-commit hook (not recommended)
git commit --no-verify -m "message"
Only skip hooks when absolutely necessary, as they help maintain code quality.

Troubleshooting

Hook Not Running

If pre-commit hooks don’t run:
  1. Ensure Husky is installed:
pnpm install
  1. Check if .husky/pre-commit exists in your project root
  2. Verify Git hooks path:
git config core.hooksPath

Linter Errors Blocking Commits

If linters fail:
  1. Review the error output
  2. Fix the issues manually or let auto-fix handle them
  3. Stage the fixed files: git add .
  4. Commit again

Best Practices

  • Never use --no-verify - It bypasses quality checks and can break the build for teammates
  • Fix issues early - Don’t accumulate linting errors across the codebase
  • Keep configs in sync - Ensure lint-staged matches your editor settings
I