Skip to content

Lint-staged Workflow for OWOX Data Marts

OWOX Data Marts uses distributed lint-staged configurations following official best practices for multi-package monorepos.

sequenceDiagram
participant Dev as Developer
participant Git as Git Hook
participant LS as lint-staged
participant Config as .lintstagedrc.json
participant ESL as ESLint
participant Prettier as Prettier
Dev->>Git: git commit -m "..."
Git->>LS: Trigger pre-commit hook
LS->>LS: Detect staged files
Note over LS,Config: Automatic config discovery
LS->>Config: Find nearest .lintstagedrc.json
Config-->>LS: Return configuration rules
LS->>ESL: Run ESLint validation
ESL-->>LS: Return results
alt ESLint has errors
LS->>Dev: ❌ Commit blocked
Note right of Dev: Fix errors manually
Dev->>Dev: git add fixes
Dev->>Git: git commit (retry)
else ESLint passes
LS->>Prettier: Format files
Prettier-->>LS: Files formatted
LS->>Git: βœ… Continue commit
Git->>Dev: πŸŽ‰ Commit successful
end

lint-staged automatically finds the nearest configuration file to each staged file:

πŸ“ project-root/
β”œβ”€β”€ .lintstagedrc.json # Root config (fallback)
β”œβ”€β”€ πŸ“ apps/
β”‚ β”œβ”€β”€ πŸ“ backend/
β”‚ β”‚ β”œβ”€β”€ .lintstagedrc.json # Backend-specific rules
β”‚ β”‚ └── src/app.module.ts # β†’ Uses backend config
β”‚ └── πŸ“ web/
β”‚ β”œβ”€β”€ .lintstagedrc.json # Frontend-specific rules
β”‚ └── src/App.tsx # β†’ Uses web config
└── πŸ“ packages/
β”œβ”€β”€ πŸ“ ui/
β”‚ β”œβ”€β”€ .lintstagedrc.json # UI-specific rules
β”‚ └── src/button.tsx # β†’ Uses UI config
└── README.md # β†’ Uses root config
  1. File Detection: Git detects staged files
  2. Config Discovery: lint-staged finds nearest .lintstagedrc.json for each file
  3. Workspace Isolation: Each workspace runs with its own rules
  4. Tool Execution: ESLint validates β†’ Prettier formats (if validation passes)
  5. Commit Control: Commit blocked if any errors found
{
"*.{ts,tsx}": [
"eslint --config ./eslint.config.mjs",
"prettier --config ./prettier.config.mjs --write"
],
"*.json": ["prettier --config ./prettier.config.mjs --write"],
"*.md": ["prettier --config ./prettier.config.mjs --write"]
}
{
"*.{ts,tsx,js,jsx}": [
"eslint --config ./eslint.config.js",
"prettier --config ./prettier.config.js --write"
],
"*.json": ["prettier --config ./prettier.config.js --write"],
"*.{css,scss}": ["prettier --config ./prettier.config.js --write"]
}
{
"*.json": "prettier --write",
"*.{yml,yaml}": "prettier --write"
}

The setup is handled automatically by the tools/setup-husky.js script:

Terminal window
# Manual setup (if needed)
npm run setup:husky
# Automatic setup (runs on npm install)
npm install # β†’ triggers postinstall β†’ setup:husky
  1. Initializes Husky: Creates .husky/ directory
  2. Creates pre-commit hook: Runs npm run pre-commit
  3. Makes hook executable: Sets proper permissions

Sometimes you need to commit without running lint-staged:

Terminal window
# Emergency commit (skip all hooks)
git commit --no-verify -m "Emergency hotfix"
# Alternative short form
git commit -n -m "Emergency hotfix"
Terminal window
# Disable pre-commit hook
mv .husky/pre-commit .husky/pre-commit.disabled
# Make your commits
git commit -m "WIP: Large refactoring"
git commit -m "WIP: Continue refactoring"
# Re-enable hook
mv .husky/pre-commit.disabled .husky/pre-commit
Terminal window
# Check if hooks are executable
ls -la .husky/pre-commit
# Fix permissions (Unix/macOS)
chmod +x .husky/pre-commit
# Reinstall hooks
npm run setup:husky
Terminal window
βœ– ESLint couldn't find a configuration file.
# Solution: Ensure workspace has eslint.config.js/mjs
ls apps/backend/eslint.config.mjs
ls apps/web/eslint.config.js
Terminal window
βœ– Prettier configuration not found
# Solution: Ensure workspace has prettier.config.js/mjs
ls apps/backend/prettier.config.mjs
ls apps/web/prettier.config.js
Terminal window
# Run lint-staged with debug output
DEBUG=lint-staged* npm run pre-commit
# Check what files would be processed
npx lint-staged --dry-run
  1. Write code with ESLint IDE integration
  2. Stage changes: git add .
  3. Commit: git commit -m "descriptive message"
  4. If blocked: Fix errors and retry
Terminal window
# See what's wrong
npm run lint
# Auto-fix simple issues
npm run lint:fix
# Format after fixing
npm run format
# Stage fixes and retry
git add . && git commit
  • Don’t blindly use --no-verify to skip hooks
  • Don’t disable ESLint rules without team discussion
  • Don’t commit with lint:fix without reviewing changes

To add lint-staged to a new workspace:

  1. Create configuration file:

    packages/new-package/.lintstagedrc.json
    {
    "*.{ts,tsx}": ["eslint --config ./eslint.config.js", "prettier --write"],
    "*.json": ["prettier --write"]
    }
  2. Test the configuration:

    Terminal window
    cd packages/new-package
    echo "test" > test.ts
    git add test.ts
    git commit -m "test" # Should use new config automatically
  3. No additional setup needed - lint-staged discovers configs automatically!