Ship internal tools in hours, not weeks. Real auth, users, jobs, audit logs, and cohesive UI included. Early access $249 $499 → [Get it now]

How to set up Husky with Angular

Maintaining code consistency in complex Angular applications is a major challenge for growing teams.
As the creator of CoreUI, a widely used open-source UI library, I have integrated Husky into dozens of enterprise Angular Dashboard Templates to automate code validation.
With over 25 years of experience in software development and working with Angular since 2014, I’ve found that preventing bad code at the commit stage is the most effective way to maintain a clean codebase.
The modern standard for managing Git hooks in the Angular ecosystem is Husky, which allows you to run linting, formatting, and tests automatically before every commit.

Use npx husky init to quickly bootstrap Husky in your Angular project and automate your pre-commit workflows.

npm install --save-dev husky
npx husky init

This installs the Husky package and runs the built-in init command, which creates a .husky directory and adds a prepare script to your package.json. This ensures that every developer on your team has Git hooks automatically configured when they run npm install.

1. Initializing Husky in Angular

The first step in modernizing your workflow is initializing the Husky environment. Since Husky v9, the recommended approach is the built-in init command.

# Install and initialize Husky
npm install --save-dev husky
npx husky init

When you run this command, Husky creates a sample pre-commit hook in .husky/pre-commit. By default, it might contain npm test. For Angular projects, you will want to customize this to match your workspace scripts. This automation is crucial for teams using our Free Angular Admin Template to ensure that no broken components are accidentally committed.

2. Configuring the Prepare Script

The prepare script is a lifecycle hook in npm that runs after the installation process. It is the bridge that connects Husky’s local configuration to the Git hooks on each developer’s machine.

{
  "scripts": {
    "prepare": "husky"
  }
}

This configuration ensures that whenever someone joins the project and runs npm install, the local Git hooks are correctly mapped to the scripts defined in your .husky folder. Without this step, Husky would only work on your machine, defeating the purpose of team-wide quality standards. In our experience building CoreUI, this is the single most important step for repository portability.

3. Automating Angular Linting

One of the most common use cases for Husky is running the Angular linter before allowing a commit. This prevents syntax errors and style violations from ever reaching your repository.

# Write the pre-commit hook (overwrites the default created by husky init)
echo 'npm run lint' > .husky/pre-commit

By adding npm run lint to the pre-commit hook, Git will abort the commit process if the linter finds any errors. This forces developers to fix issues like unused variables or missing imports immediately, ensuring new files adhere to your project’s linting rules before they are shared.

4. Running Unit Tests on Commit

Testing is the backbone of reliability. In Angular, we use the ng test command to verify component logic. Adding a headless test run to your pre-commit hook guarantees that changes don’t break existing functionality.

# .husky/pre-commit
npm run lint
ng test --watch=false --browsers=ChromeHeadless

In Husky v9, hooks are plain shell scripts — no sourcing or boilerplate required. Running tests in ChromeHeadless mode is essential for terminal compatibility. Note that ChromeHeadless requires the karma-chrome-launcher package and a corresponding entry in your karma.conf.js. At CoreUI, we use this pattern to maintain reliability across our component library.

5. Integrating Lint-Staged for Performance

As your Angular project grows, running linting and tests on the entire codebase for every small commit becomes slow. lint-staged solves this by only running scripts on files that are actually being committed.

# Install lint-staged
npm install --save-dev lint-staged

# Update package.json
{
  "lint-staged": {
    "src/**/*.{ts,html}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Once configured, you should change your .husky/pre-commit file to run npx lint-staged. This drastically improves developer productivity while still enforcing strict quality standards. It is especially useful when working with complex forms where validation logic needs to be perfectly formatted.

6. Enforcing Commit Message Standards

Beyond code quality, Husky can also enforce commit message formats. This is often done using commitlint, which ensures that all messages follow the Conventional Commits specification.

# Install commitlint
npm install --save-dev @commitlint/config-conventional @commitlint/cli

# Create a commit-msg hook (Husky v9 — write the file directly)
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg

# Create config file
echo "module.exports = { extends: ['@commitlint/config-conventional'] }" > commitlint.config.js

This setup prevents vague commit messages like “fix” or “update”. Instead, it requires messages like feat: add new sidebar component or fix: resolve navigation bug. Standardized messages are vital for generating automated changelogs and maintaining a readable project history.

7. Troubleshooting Common Issues

Occasionally, developers might need to bypass Husky hooks for emergency patches. While discouraged, it is possible to skip the hooks using the --no-verify flag in Git.

# Bypass hooks for a single commit
git commit -m "Emergency fix" --no-verify

Common issues often stem from permissions or environment variables. Ensure that the .husky directory is tracked by Git and that all scripts have execution permissions on Unix-based systems. If a hook fails to run, verify that the prepare script has successfully executed. We recommend keeping hooks lightweight to avoid frustrating developers during their daily coding cycles.

Best Practice Note:

This is the same approach we use in CoreUI components to ensure clean and predictable data.
Always keep your pre-commit hooks focused on fast tasks like linting and formatting. Long-running integration tests should ideally be moved to your CI/CD pipeline to keep the local development experience snappy. Integrating Husky with tools like lint-staged is the gold standard for high-performance Angular teams.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team