Simple Git Hooks with Create React App, ESLint, and Husky

Let your Git hooks run your tests and lint your code automatically

Aug 14, 2019 · 4 min read
Image for post
Image for post
Photo by Brook Anderson on Upsplash

Git hooks are scripts that Git executes before or after events such as commits, pushes, etc. It’s a really cool and quick way of validating your code before Git lets you check it in.

In this piece, we will take a look at a simple example of implementing Git hooks on the React application using the Husky library. Then we will make a Git hook that validates your changes by invoking ESLint against your code before every commit.

The only prerequisite is having Node (well, and Git) installed on your machine. I will assume that you know how to create a Git repository. Put your repository into the same directory that you plan to put the React app.

Getting Started

Let’s start with the React app. There are many templates online for creating applications with React, but the most popular is Facebook's very own Create React App.

Create React App requires no configuration and creates a very simple React application with a single command:

npx create-react-app my-app-name

Now you should have the React application. If you want to verify everything works, you can run `npm run start` from your terminal and navigate to http://localhost:3000.

Setting Up ESLint and Husky

All right, now the fun part. Let’s set up ESLint and Husky.

Let’s install ESLint globally on your machine by running “npm install -g eslint” from your terminal.

Next, navigate to the root directory of your React app; it’s the place where the package.json file is located. Initiate ESLint from your terminal.

eslint --init

Answer questions about your ESLint usage, such as the framework you are using, your code style, etc. The set of questions is changing over time as ESLint evolves, so I’m not going to post them here. After all, in a few months, they might be outdated.

Just make sure to select React for your framework.

Eventually, you’ll get to the question, “How would you like to define a style for your project?” Choose: “Use a popular style guide.”

You’ll get a follow-up question asking, “Which style guide do you want to follow?” Choose: “Standard.”

If you run ESLint now by running “eslint src/**/*.js” from your terminal, you will see quite a lot of errors and warnings (probably more than 50).

Let’s fix them!

Most of the errors (90%) can be fixed by ESLint itself, so run ESLint with a fix flag:

eslint --fix src/**/*.js

You should only have a handful of errors left, they should look like this:

1:8 error ‘React’ is defined but never used no-unused-vars3:8 error ‘App’ is defined but never used no-unused-vars5:1 error ‘it’ is not defined no-undef

To fix these errors, we have to tell ESLint to take into an account that our app is running on Create React App and that we are using Jest as a test runner.

Open your ESLint config file, likely called .eslintrc. Your file name may vary, depending on config format you chose. I recommend the JSON format.

There are few customizations we need to make in the .eslintrc file

In the “env”: section, add jest. Not adding jest will make ESLint error out on Jest-specific functions like describe and it:

"env": {  "browser": true,  "es6": true,  "jest": true

In the “extends”: section, add “plugin:react/recommended”:

"extends": [  "standard",  "plugin:react/recommended"]

And now you are all set. If you try to run ESLint now, it will pass without errors.

A Few Additional Customizations

If you don’t really want to always run the linter manually from the terminal, add the npm scripts that’ll run the linter:

Open the package.json file. In the “scripts”: section, add the new ESLint scripts.

“scripts”: {
“lint”: “eslint src/**/*.js”,“lint:fix”: “eslint --fix src/**/*.js”},

You can run these scripts with npm by calling:

npm run lintnpm run lint:fix

You should be all set on ESLint at this point. Right now it’s really easy to set up Git hooks using Husky.

Setting Up Husky

For the last part, let’s finally set up Husky!

Install Husky by navigating to the root directory (it’s the one where package.json is located). Open terminal and run:

npm install husky --save-dev

When it’s successfully installed, add your“husky”: section into your package.json file.

Now we have Git hooks for commit and push actions.

Every time you run a Git commit, Husky will run a pre-commit script (“npm run lint:fix”) and will only let you commit your changes if validation passes. This functions in a similar fashion for Git pushes.

One Last Thing

What if we want to run both test and lint scripts pre-commit and pre-push (or any other more complex script)?

We can do that by adding a new script into package.json:

Setting CI=true is for making sure Jest runs tests only once and doesn’t run them in watch mode since watch mode does not make sense for Git hooks.

By the way, the syntax above is for Windows. On a Mac it should be something like:

“test:all”: “CI=true react-scripts-ts test && npm run lint”

Now, all we need to do is use a new script for the pre-commit or pre-push hook:

Congratulations! Now you have Git hooks that will run your tests and lint your code automatically each time you commit your code.

Pretty handy, huh?

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store