The first Jamify Blog starter was built on Gatsby. At the beginning of 2020, this seemed like a safe bet for a static site builder: A highly acclaimed React framework with a large ecosystem and vibrant open-source community. Looking back, this wasn't a bad choice: we still love the the Gatsby Jamify Blog system with it's plugins and certainly continue to support them:
Many comparisons between Gatsby and Next.js at the time were also making clear recommendations: if you need a static site builder go with Gatsby, if you need on-demand server rendering and serverless functions go with Next.js. With this distinction, a blog would typically better built with Gatsby whereas an e-commerce site with a lot of product changes would better fit to Next.js. Easy!
This simple decision making became more difficult nine months ago, when Next.js released Version 9.3 introducing a novel hybrid approach. Hybrid means that you can choose between server side rendering (SSR) and static site generation (SSG) on a per page basis. Over night, Gatsby's SSG feature became available in Next.js and the above distinction fell apart.
Moreover, Next.js was now able to do what Gatsby was doing, but at the same time providing many more possibilities with SSR and serverless. Would it be worth switching to Next.js for a blog site that mainly uses SSG?
The case for Gatsby
In March 2020, when Next.js Version 9.3 was released, I did not pay too much attention to it. Of course, Next was now also capable of SSG, but Gatsby is certainly more experienced in its core SSG feature, I presumed.
Above all, you do not choose a framework based on one feature alone. Gatsby's main promises seemed still intact:
- Blazing fast sites out-of-the box
- Tools for image optimization
- A plugin API that enables component shadowing
- An integrated GraphQL layer for structured data fetching
Adding to these key Gatsby features are an integrated cache that can be used to make developer life easier and many third-party plugins to choose from that already solve a lot of common use cases.
At the time, Next.js could not compete in any of these areas. Thus, I was holding strongly to Gatsby. Of course, there were some annoyances with the GraphQL layer such as foreign-key linking issues popping up more often than expected. Also, component shadowing is a concept our users had difficulties grasping. But hey, you don't expect a perfect world. At least not as a developer!
Gatsby loosing ground
One of the biggest pain points with Gatsby has always been build times. The reasons for it is also one of its acclaimed features: image optimization. As Gatsby is doing these optimizations during SSG, every image you add to your site will increase build times.
For a blog with many images, these optimizations are absolutely essential for a fast loading site, but it never seemed right to do this during SSG. Image optimizations should be completely decoupled from site generations as you could do this as soon as you add a new image to your content management system, typically way ahead of building your site.
Gatsby is trying to cure these issues with two medicines: (1) utilizing a cache and (2) with incremental builds. The first medicine only works for sub-sequent builds which is a huge drawback and the second has two other downsides: it only works when deploying to Gatsby Cloud and – unfortunately – it turned out to be notoriously unstable.
You may argue that as image optimizations should be better done elsewhere, therefore it is not a Gatsby issue. This may be true, but wasn't Gatsby promising to make developer life easier with some awesome image optimization plugins?
When faith falls apart
While the described pain points could be solved with external solutions, a much more devastating Gatsby performance issue popped up in May 2020 that Gatsby wasn't able to solve until today. With Google changing its page speed rating system in Lighthouse version 6.0, speed scores plunged from formerly given 100 points to mediocre 50 for many sites using images.
This problem erodes Gatsby's core promise which is still advertised as of today: Create blazing fast websites!
Nothing can hurt you more than not delivering to your core value proposition, but the real disaster for Gatsby is its inability to restore out-of-the box fast sites after more than six months.
Sadly, the reason for this is not a lack of willingness, it points towards fundamental design issues of the framework that are hard to rectify. You can read through the issue yourself to get a feeling about the depth of the problem. It is a combination of insufficient bundle size optimizations, deficiencies of the gatsby-image plugin and a conceptional weakness of trying to do everything with SSG.
Next 10 to the rescue
With Gatsby struggling to deliver its core promises and seemingly busy to commercialize its product generate cash for its investors, I was starting to take a closer look at Next.js.
To my surprise, Next was producing smaller bundle sizes out-of-the box in all of my SSG test cases. Unfortunately, images were not addressed at all early October, however, some rumors were spread that something great is coming out with Next 10. What could it be?
I attended the Next Conference on October 27th 2020 and the timing for a brand new built in image component with automatic image optimization couldn't be better. This combination of a React component with a serverless function for image optimization showcases the conceptional advantages of the hybrid approach.
Rather than quenching everything into SSG, make solutions with the tool that best fits your use case!
I am hard to be convinced
While excited about the new possibilities with Next, I was still not fully convinced to start a new version of the Jamify Blog starter with Next.js.
- What am I going to do with all the nice plugins that are delivered with the starter?
- What about the GraphQL tools that come for free with Gatsby, will this be hard with Next,js?
- What about component shadowing? Will a Next version be easily extendible?
I am glad that the spark of the Next conference prevailed the nagging questions above. Sometimes, it's better to simply try things out and conclude after.
In this spirit, I initiated next-cms-ghost with a clear goal: A Next.js variant of the Jamify Blog starter that includes all features of the Gatsby version. So users can choose what ever they like best:
This goal was successfully reached on December 5th, 2020, in less than 4 weeks and with very pleasant results – not only with respect to Lighthouse v6 scores.
Here are some of the lessons that we learned during this fast paced project:
Less is more
First of all, the developer experience with Next.js is superb. It does a lot of the heavy lifting for you, but generally tries to stay out of your way as much as possible. At the same time it gives you great support for fundamental concepts such as TypeScript.
To this end, it also doesn't trick you into something you actually don't need. A great example is the GraphQL layer that Gatsby has been really proud of. It is great if you need it, but you don't always do! The data layer of next-cms-ghost relies entirely on REST interfaces that are far less complex, easier to maintain and play much nicer with TypeScript.
Use GraphQL only when over- and under-fetching is a real problem that you need to solve, but never presume your use case needs to be optimized in that way.
While there is some discussion about a plugin API in Next, it is quite unclear whether this will ever materialize. Thus, I took a practical approach and integrated all functionality that are in separate plugins directly into the Next.js Jamify Starter and made sure that you can enable/disable each feature with configuration options.
While I am generally more in favour of the plugin approach, there are some advantages of this integration: no need to install or uninstall packages. Everything can be switch on or off not only in the config but also with environment variables. No plugins also leads to lesser maintenance work as the need to sync dependencies between many packages quickly becomes a burden. Overall not a bad solution after all.
While I may sound overly critical about Gatsby, I want to stress that it is still one of the best static site generators out there and I am sure that some of the downsides described here, will be tackled in 2021.
I hear from the core team that they are working on serverless and new image plugins. They now also support a file based routing system, obviously inspired by Next.js. Interestingly, they also do not actively advertise the GraphQL feature anymore.
So, if you invested heavily in Gatsby, you may still want to stay with them. Nonetheless, my preference for Next.js is obvious.
My forecast is that Gatsby will not be able to level up with Next.js in 2021, because they have fallen behind not only in features. Gatsby has become too complex to make the fundamental changes it needs.
All this reminds me of the transient nature of software frameworks in general. The following graph from the StackOverflow survey on Backend framworks illustrates this beautifully.
It looks like every framework has it's time until it is superseded by something newer, better, fancier. Let's wait and see what the future brings and always remind yourself that...
With this closing remark, I wish you a happy New Year 2021!
Update on January 13, 2021
When I wrote this article last month, the 2020 survey from StackOverflow was not yet published. It's interesting to see that my views seem to be shared by many fellow developers:
While NextJS was able to gain pole position for the first time, Gatsby plummeted by 18% to an all time low.