Gatsby vs Next.js in 2021 - What, Why and When?
Jan 22, 2021
A high level look at two of the leading React frameworks - Next.js and Gatsby - and what their strengths and weaknesses are and which is the better choice in 2021.
In 2019 I decided to write a post called "Gatsby vs Next.js - What, why and when?" out of frustration for the lack of resources that could summarise which of these React frameworks was best to use for what situations. I remember looking at both of these tools early on, trying to read articles considering the pros and cons and thinking "Ok cool, but I don't know what
getInitialPropsis or does". "What benefit does GraphQL bring to me?". I was sure many were feeling the same.
My approach was fairly jargon free, and I think because of this it has been my most viewed article.. well, ever. It still is shared fairly regularly on Twitter, and it has just amassed over 76000 views on DEV.to (where I originally posted it).
So. A year and a bit on, now that both Gatsby and Next are more mature, I am going to tackle it again, but update it for 2021. Still as jargon free as humanly possible. I hope you enjoy!
Not much has changed in this respect, so as I mentioned in my first article:
Both Gatsby and Next exist to lay the foundations of a React app, and offer you a guided way to build your application. What you are probably using to create a React app now is the boilerplate,
create-react-app, which creates you all the basic functionality and tooling. In comparison, these two frameworks will lay the foundations for you to create an application - they are not classed as boilerplates, but toolkits, laying not only the foundations and then giving you a set of instructions on how to build the house well, with a well stocked toolbag full of the right tools.
- create-react-app - Lays the foundations of a React Project. The rest is up to you.
- Gatsby & Next - Lay the foundations of a React Project. Give you guidelines on how you should build on top of them as well as a set of tools.
And yes, still the same as 2019, they are both fairly similar, in that they each:
- Provide a boilerplate application.
- Generate incredibly performant, accessible and SEO friendly websites.
- Create Single Page Applications out-of-the-box.
- Have a really awesome developer experience.
In the first article I started off describing the difference between 'Server Side Rendered' (SSR) and 'Statically Generated' (SSG) websites, the reason being because Next allowed you to only build server-side rendered pages, whilst Gatsby is a static site generator. At time of writing, Gatsby generated pure HTML/CSS/JS at build time and was serverless. Whereas, Next created HTML/CSS/JS at run time, so each time a new request comes in, it created a new HTML page from the server.
But, alas, that has changed!
As of Next.js release 9.3, you can now choose how you pre-render your pages - using either Static generation or Server Side Rendering. Read more about it on the official Next docs --> https://nextjs.org/docs/basic-features/pages#pre-rendering.
This changes things, because arguably alongside the methods for data fetching (which I will get on to) this was the biggest difference between the two tools. In fact, I stated in the last article that if you had a smaller website it made sense to use Gatsby (SSG) and if you had a larger scale application with lots of content go for Next (SSR). But that is just not the case anymore.
So, the best way to approach the rest of the article, is to go into more detail about what each framework does well, and what it doesn't.
When building websites in Gatsby, you gain access to your data through a query language named GraphQL. Created originally by Facebook in 2012, GraphQL was used internally for the companies mobile applications. The benefit of GraphQL is that by nature, it allows specific data-fetching and Facebook found this useful to reduce network usage.
A GraphQL server, provides the Front-End with a pre-defined 'schema', which allows the client side to extract only the relevant information and the fields you want to query, rather than the alternative REST which hands the client all the data, relevant or not, from the API. This is more labour intensive.
An example of a GraphQL query is below:
It returns this:
As you see, I have only specificed that I want
siteMetadatawhen in fact the
siteMetadataobject contains a lot more information. You are able to specifiy exactly what piece of information you are after.
There are obvious benefits to GraphQL as a query language, it is gaining popularity across various applications. It is nice that Gatsby has this and makes it relatively easy to get up to speed with this tech.
In my mind, the coolest thing about Gatsby is its vast ecosystem of 'plugins'. - https://www.gatsbyjs.com/plugins
They are pre-made Node.js packages that allow you to plug pre-built functionality into your website. Essentially, its code that other developers have written that accomplish certain things.
Say for instance I wanted to display my Instagram feed on my website and show everyone my awesome desk and delicious plates of food I have been eating. Theres a plugin for that! The complexity would have already been worked out, and it is as simple as installing the plugin and putting it in the config for my site. I never have to visit the Instagram documentation and generate API keys and secrets, which saves time. Oh, so much time. And complexity of course!
This is cool because it allows even the greenest of developers to get up and running with a site that actually achieves things. I always say, the best way to learn is to build, and being able to get something up and running quickly is really rewarding.
As well as a large ecosystem of plugins, Gatsby has a vast amount of 'Starters' and 'Themes' that the community have created.
These are pre-built sites that developers have already created, in some cases styled and added functionality to with plugins. So, if I wanted to create a shop, then I would find a relevant starter or theme that had the required functionality - a cart, a link to Stripe etc. It is, again, really cool, and is something that I have used a lot, not so much professionally but for hacking around and seeing how things work.
Arguably, Gatsby's greatest strengths are also it's greatest flaws.
The fact that it is so opinionated on how you should be fetching your data, and the fact it focuses to intensely on the plugin ecosystem means that it is often hard to diverge from these.
Whilst the plugins get the developer up to a working app quickly, it becomes a repetitive task of installing the same plugins to set up even base functionality. Of course, you could build your own starter, but even then it is an element of complexity that you don't have with other tools.
Often I have found myself wanting to create something there is not a plugin already existing for. Having to create a plugin from scratch to cope with potentially a niche functionality that would be a quick thing to implement in a non-Gatsby app is made more complex. The developer ends up having to poke around in the
gatsby-node.jsfile and create a custom Webpack config and it just doesn't feel intuitive.
Also - GraphQL... Whilst it is undeniably cool, one of the main purposes is lost in this case. As I mentioned earlier in the article, GraphQL is there to cure over-fetching, but Gatsby's bread and butter is Static Sites, which means that fetching all of the data from the API's will cause no extensions to runtime, it would take marginally longer at build time granted, but for flexibility that seems a worthwhile trade.
I made the statement in my last article that Gatsby is better for smaller applications, because if you have a massive amount of data you are going to want to potentially implement Server Side Rendering. GraphQL in that case, is almost like cracking a nut with a sledgehammer (in my own humble opinion).
Thankfully - Gatsby have realised this, and have published in their docs a page on 'Using Gatsby without GraphQL', but this solution is a work around and they try very hard to convince you of the 'tradeoffs' of not using their data layer.
And whilst this doesn't necessarily affect the tool, there has been a handful of controversy around how some of the senior members of the Gatsby team treat their contractors. It kicked up so much mess that the team had to write an open letter to the community apologising - https://www.gatsbyjs.com/blog/open-letter-to-gatsby-community/. Whilst a touching gesture, it glossed over many of the problems that were being spoken about in the community. The community was also a really big deal for Gatsby in the early days, where if you made a contribution in some way to the codebase you would be invited to the community, as a member on their GitHub page and be awarded with Gatsby flavoured swag. The Gatsby team would do knowledge shares and listen to what the software engineers using the tool actually wanted. Its not scalable, I know, but closing that down was a bit disappointing and it certainly leave a sour taste knowing that a handful of their staff were left unhappy from the working conditions.
The main argument for Next this time last year was the fact it was flexible. It didn't force the developer into an ecosystem of plugins and GraphQL. Making Next.js able to Pre-render pages at build time (SSG) or request time (SSR) in a single project and give the developer to choose one or the other and switch between the two is a huge gain for flexibility.
Chances are your project is likely to change over time. You might want to add complexity that you hadn't considered before - and you think that SSR would be the best way of doing it. Thats all good :) That wouldn't be possible in Gatsby, so taking scalability into consideration when starting a project and going with the more flexible solution makes a lot of sense if there is any chance the project could scale.
On hearing that Statically Generated Sites were going to be a feature that the Next team were working on, I was initially worried. This was a step away from what they started with, however arguably the SSG functionality is way better than the SSR functionality ever was.
Working with the filesystem routing is a dream (something that Next did even when they were SSR focused) and there is no GraphQL in sight (unless you want it there of course!). If you export an async function called getStaticProps from a page, Next.js will pre-render this page at build time using the props returned by getStaticProps. There is even a feature called 'Incremental Static Generation' which means you can register new static pages at run time. Everything is just really well thought out, and they haven't forgotten about those who were using the tool for SSR before this new functionality was added.
The Next.js docs are probably some of the best I have ever read anywhere. Getting up to speed is quick and easy, they have also included a section that relies on gamification (collecting points as you progress through the How-To guides by answering quiz questions and completing tasks), which is an excellent addition for people of all ability levels. I would love to see other projects include such focus on getting people up to speed!
The improvements of pain points from the team at Vercel is aggressive. If you mention you are stuck on something on Twitter, you can be pretty certain that one of the team will drop in and offer a solution. Its so nice to feel heard. Many of the larger issues that crop up on Twitter or elsewhere within the community are automatically created as Tickets.
At the time of writing the first article, the company behind Next.JS were called 'Zeit'. They had a number of different products - Now, Next and Hyper where the most popular.
They have undergone a name change and have focused their platform more around deployments and streamlining that process for engineers and engineering teams alike. I have been blown away by the platform itself.
The part of it that first blew my mind was the one-click domain assigning. With a click of a button it took care of everything for me, and removed a process I usually hate. The more I have used the platform, the more I am impressed. Deploying is easy, the analytics they offer to see your projects is incredible. Everything is just so polished and user friendly.
Whilst not necessarily a part of 'Next.js' specifically, Vercel also has an array of 'serverless functions', pieces of backend code that are deployable to your project. These snippets take an HTTP request and provide a response, allowing you to plug and play extra functionality into your frontend codebase. There are functions that handle logic, from user authentication, form submission, database queries, custom slack commands as well as more.
In conjunction with Next.js this is a dream package for a Front End developer. I have moved the majority of my projects across from Netlify (which is equally as awesome), so I could use one 'ecosystem', so to speak, to handle every bit of my development process.
I struggled to write this in all honestly, because without diving into very specific technical features I would like to see, the only thing that comes to mind is the fact that it is harder to get something up and running as quicky as it is with Gatsby. If I browse over to the Gatsby 'Starter' library, I could pick a template for a blog I like the look of, install it locally with one line of code and I am up and running.
Whilst it would undeniably be a shame to rely heavily on an eco-system of themes/starters and sharable plugins like Gatsby does, it is nice, if for no other reason than for learning different pieces of tech, to be able to pick up projects that are already started and have some configuration already too them and a small piece of UI. Of course, there are the serverless functions, but these are backend only and not the same UI building plugins that Gatsby boasts.
More and more templates and starter projects are popping up however, the recent additions of Next.js E-Commerce and Next.js Virtual Event are a great example - and it is 100% worth pointing out 'Nextra' which is a delicious docs generator, but I would love to see some more options that make it quick and easy to get a project up and running.
Both frameworks are absolutely a great choice for any Frontend developer who is looking to build a web app. Both allow for insanely performant websites, and both have good developer experiences.
I definitely think the landscape has changed since last writing my review in 2019. The choice was a little bit more clear cut then, because Gatsby was good for one thing (Static Sites) and Next was good for another thing (Server Side Rendered), as my last article examined.
Next.js is more versatile and flexible. If your project has the potential to grow beyond its current spec, I would go with Next.
But Gatsby makes it easier to get up and running quicker and achieve more with less coding. If you want to build something that is unlikely to diverge much from the current spec, Gatsby is a great choice.
My usage has changed since writing in 2019 as well. I was much more actively writing code and building projects back then, now as a manager my coding time is much more limited. I was an avid Gatsby user in 2019 and as much if anyone had asked me which to use I would have recommended Gatsby.
As a personal preference now however, I will typically choose Next. My reasoning for this is flexibility. It just makes much more sense to me that over time my project might change and I want something that will seamlessly allow that to happen. Also having everything on one platform just makes sense to me. It saves me time and effort, whilst being easier to keep up with updates.