Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Run Linting, Tests and Prettier in git Hooks with Husky

    Andy Van SlaarsAndy Van Slaars

    With the ability to run unit tests, automatic code formatting and linting, we should avoid ever committing code that does not adhere to our project standards or breaks our tests. In this lesson, we'll install and configure the Husky npm package and enforce these checks before a git commit is allowed.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson


    Instructor: 00:01 Our project has Prettier, ESLint, and Jest all configured, so we can ensure we're creating consistently-formatted, well-tested, high quality code. Let's ensure that all tests and linting rules pass, and our code is properly formatted before any new code can be committed to Git.

    00:15 We'll start by running npm i -d to save as a dev dependency, Husky. With that installed, let's go into our package.json and configure it. Husky is going to have its own configuration in our package.json, so I'm going to create a Husky key at the top level.

    00:34 That's going to get an object. We're going to define a section in here called hooks. Then we want to define the key for the pre-commit hook. That's going to be pre-commit. Then we can give this a value. This'll be a script that runs.

    00:53 Let's start with npm run lint. We'll save that. Now, I'm going to come into my app.js file, and I'm going to do something that will cause a lint error. I'm just going to add a new constant. I'll call it A. I'm going to assign it a value A, and I'm not going to do anything with it.

    01:10 I'm going to save this, and if I do an npm run lint, we'll see that our linter fails, because we have a value that's never used. Now that I know I have a linting error, what I expect to happen is, if I add this file, and then try to commit it to Git, that commit should fail.

    01:30 In my terminal, I'm going to do a git add source/app.js. If I run a git status, we will see that I have one file that's been modified and ready to commit. I'm going to do a git commit -m, and this should fail. We'll see that we get an error here.

    01:58 If I scroll up, it's our linting error that we expected. We'll see that Husky is running that pre-commit script. If I do a git status, we're right back where we were before I attempted to commit. We know a linting error will fail our commit.

    02:17 I'm going to come in here, and I'm going to remove this code that causes that error in the first place. I'll save that. I would also like committing to fail if our tests aren't all passing. I'm going to come into our app.spec.js, and I'm going to add a second test that just always fails.

    02:38 Here, we'll just expect true to be false, so this test can never pass. We'll just verify that by running npm test. We have our failing test. Now, I'm going to come back into package.json, and I'm going to update this pre-commit script to run npm run lint.

    03:00 Then I'm also, with the double ampersand, if the linting passes, then I'm going to run npm run test. I can save that, and I'll go back down into my terminal here. If I do a git status, we'll see that we have some new modified files, but we still have a file ready to be committed.

    03:23 We can run this experiment again without doing anything else. We'll do a git commit -m. This should fail. We can see that our test is failing. It ran lint. Lint passed, then it ran Jest. Our test failed. If we look at our git status, our commit never happened.

    03:53 Now, we know that our pre-commit hook will also fail if our test fails. I can come into app.spec, and I can remove this test that's always going to fail. The last thing we need to add is automatically formatting our code using our Prettier settings.

    04:07 I'm going to go into package.json, and I'm going to update this script. I'm going to add this one to the beginning, because it's going to run pretty fast. I'm going to add pretty quick. I'm going to pass it the --staged flag, and then use the double ampersands to run lint, and then test after that.

    04:26 This is only going to apply to staged files, things that we've added to git that are about to be committed. This is what we're worried about here, is those staged files. I'm going to save this, and I'm going to go back into app.js.

    04:39 I'm going to mess up my formatting. Now, I have turned off my automatic format on save setting in my editor so that I can save this file. Now, I'm going to back down into the terminal. At this point, we expect everything to pass.

    04:52 Down here, I'm going to just add everything that we've changed. Then I'm going to git commit. This commit says that we added Husky, with pre-commit hooks. We'll see that our file has been formatted. It also ran all of our lint checks.

    05:21 It ran our tests. If we look at our git status, we'll see that we've successfully made our commit. Now, we can't commit without our test passing, all the linting rules being cleared up. It'll automatically format anything that hasn't been formatted by our editor, or by running our format script.