Migrating to Gatsby 2 in 10 minutes

This site is being generated by a JavaScript framework called Gatsby. When I first started getting this site up and running in the summer of 2018, Gatsby was at version 1 and making waves as a “blazing fast modern site generator for React”. I had listened to a really interesting podcast on Gatsby plus tried out a couple demos and decided that I wanted to build my website with the combination of React and Gatsby. My experience thus far has been all that I could have asked for.

In September 2018, Gatsby 2.0.0 was released and offered a host of improved features and the latest of everything, including React 16, Webpack 4, Babel 7, and reach-router. Hats off to the Gatsby team and all that they’ve done to improve the project! 🚀 However, I was just about to roll out my site and didn’t want to bother updating the Gatsby package until I had things up and running in a good place.

I released my website (work always in progress 😅) in October but I was in the middle of changing jobs and countries and had too much going on to update Gatsby. This weekend I decided it was time to update and that I would document my steps in blog form. In hindsight updating was super smooth and I experienced minimal breaking changes along with some immediate wins. Should have done it sooner!

Read the docs first

Yes, please read the docs first as I think they will give you a great idea about where to start and what has changed. In my case, I knew that I had a dependency to update (renovate bot told me) so I didn’t look at the docs until I was writing this post. Whoops! I could have saved myself some time with trial and error debugging. Anyways, there is a great migration guide here and the announcement of Gatsby 2 here with some compelling reasons for migrating.

Manually install React

Running npm update updated all my project dependencies to their latest releases. The main one I was interested in was that Gatsby had updated to version 2.0.67 and the other Gatsby plugins that I was using were also updated to version 2.X.X. It was now time to figure out what needed to be migrated.

Taking the ready-fire-aim approach and not reading any of the migration documentation, I ran npm run develop to see what would happen.

Error: Cannot find module 'react'

Easy enough, and I proceeded to install react as a project dependency. Try again ...

Error: Cannot find module 'react-dom/server'

Okay, I guess that one would need to be installed as well. I tried once more ...

Got it! Although there were quite a few warnings showing up in the console, Gatsby compiled the build for development. We will take a look at the warnings in a minute. The thing to note here is that in upgrading from Gatsby 1 to Gatsby 2, I needed to explicitly install react and react-dom. As stated in the migration guide, Gatsby once bundled react and react-dom as dependencies but have now moved both packages to be peerDependencies which, I think, makes a lot of sense.

Fix eslint warnings in build

I couldn't find any documentation about eslint warnings in the build step for Gatsby 2 and I can't remember that there were any errors when I built the project before. But now I was getting eslint errors, which, when you have real errors in your code, is always helpful! We can all use some extra pairs of eyes on our work.

Lets take a look at some of the eslint messages I was now getting.

Module Warning (from ./node_modules/eslint-loader/index.js):

46:11 warning Using target="\_blank" without rel="noopener noreferrer" is a security risk: see https://mathiasbynens.github.io/rel-noopener react/jsx-no-target-blank
54:11 warning Using target="\_blank" without rel="noopener noreferrer" is a security risk: see https://mathiasbynens.github.io/rel-noopener react/jsx-no-target-blank
66:11 warning Using target="\_blank" without rel="noopener noreferrer" is a security risk: see https://mathiasbynens.github.io/rel-noopener react/jsx-no-target-blank

✖ 3 problems (0 errors, 3 warnings)

It turns out that I was using rel=“no opener” but not the combination of the two. Adding the second and re-running npm run develop showed that the warning has been cleared.

Another new warning that Gatsby 2 now showed was the global graphql variable:

warning Using the global `graphql` tag is deprecated, and will not be supported in v3.
Import it instead like: import { graphql } from 'gatsby' in file:

Easy enough and a simple import fixed that. Its actually nice to have everything explicitly imported instead of having those "magic" definitions.

Next there was a warning about boundActionCreators.

boundActionCreators is deprecated. Please use actions instead. For migration instructions, see https://gatsby.app/boundActionCreators
Check the following files:


The offending code in my gatsby-node.js file looked like this:

exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators

const blogPostTemplate = path.resolve(`src/templates/blogTemplate.js`)

And fixing the warning truly was as simple as renaming boundActionCreators to actions. Everything just worked! According to the migration guidelines: “boundActionCreators is deprecated in v2. You can continue using it, but it’s recommended that you rename it to actions."

This won’t throw a deprecation warning during the build process but is a simple update. All the components and utility functions from the gatsby-link package are now exported from gatsby package so you don’t need to have that extra package dependency. Just replace import Link from 'gatsby-link’ with import { Link } from gatsby. No breaking changes, but if you'd like to read about it, you can here.

Refactor layout components

At this point the build ran perfectly without any errors when I ran npm run develop. However, a quick look at the page in the browser showed something different. All my code blocks were completely black; none of the text was styled or visible. This turned out to be an issue with where I was requiring prismjs, the library that I am using for styling code blocks. I had originally been requiring the css file in the src/layouts/index.js file which was a special layout component in Gatsby v1. This has been changed in version 2 to move the projects architecture to be more component-based in nature. All that was needed to fix this code block styling was to move my require statement from the special index.js file to my template file for the blog posts.

This move away from the src/layouts/index.js file as the top-level component for Gatsby projects could require more work for you if you were doing a lot of custom things there. I would definitely recommend that you carefully read the suggested migration steps regarding layout components.

Launch and iterate

After installing some dependencies, refactoring the eslint errors, and changing my approach to lop-level components, everything was working again! The whole migration took me less than 10 minutes and was very straight forward. The console messages, whenever something didn't work, were very friendly and pointed me to exactly where I needed to fix something. Once again, thanks so much to the Gatsby team for all the hard work they've done with this project! I am looking forward to continuing to build out my site with the perfect combination of Gatsby and React.

Like what you've read? Give a share:

  • Tweet
  • Share on LinkedIn
  • Share on Facebook


I'm Timothy Vernon

Timothy Vernon

I build beautiful, modern web applications with Javascript. This is my website where I write about what I am learning and my experiences.


Find me online

My Github ProfileMy LinkedIn ProfileMy Twitter Profile

Check out my open source work, professional experience, and tweets.