Hacker News new | past | comments | ask | show | jobs | submit login
An Honest Review of Gatsby (cra.mr)
181 points by ehfeng 23 days ago | hide | past | favorite | 118 comments



This review nails it. It takes the matrix.org gatsby website 20 minutes to build currently, which is excruciating when trying to do quick fixes for blog content - you just sit there wondering what the graphql is actually doing and what it’s giving you :/

edit: https://github.com/matrix-org/matrix.org/ if any indignant gatsby fans want to tell us what we’re doing wrong


Yeah, SSG build times are certainly an issue in my experience, even for smallish sites. I quite like the incremental regeneration idea in NextJS: https://nextjs.org/blog/next-9-5#stable-incremental-static-r... - sounds like it will rerender pages in the background as traffic comes in to them, while serving a stale version to the original request. I guess there are times when this might not be acceptable though... in which case really you just want to be able to rerender the subset of pages a given change affects, but this isn’t always easy to work out.


It’s kinda funny to see that go around in circles. “Pre-rendering content as requests come in” is exactly the same as having dynamic pages and a layer of caching, as had been standard practice for the last 20 years. Some people just really like to “solve” already solved problems.


In principle, the two are very similar. However, the way we implement it is similar to database replication. Once a static page is produced, we can store it for usage across the entire edge network. This means you get the benefits of traditional static generation too: less backend load, higher availability, lower latency.


Haha, that’s true. I guess the advantage to NextJS is it comes “batteries included” - you don’t have to worry about setting up a cache etc. Obviously for some use cases setting it up yourself will make more sense


As they say, "Get a framework that'll do both."


This totally depends on the SSG. Hugo can generate thousands of pages in a couple of seconds.


If a static site generator put my images in the wrong place and required a gigantic JSON file to be loaded by the client for no reason I would not think twice to get rid of it.

There are literally hundreds of static site generators: https://www.staticgen.com

Most of them should get markdown right too!


> If a static site generator put my images in the wrong place and required a gigantic JSON file to be loaded by the client for no reason I would not think twice to get rid of it.

Incorrect DOM-output is likely caused by common mistakes (e.g. conditional rendering based on `typeof window !== 'undefined'`) which screw up rehydration. Dealt with it in the past and seen a lot of developers struggle with it. This article describes it well:

https://joshwcomeau.com/react/the-perils-of-rehydration/

Gigantic page-data.json files are caused by querying more data than necessary to render a given template/component. Let's say you define a component named `EmployeeCard` that renders a name and photo given an `employeeId`. Now you need to query all employees and render the right one using `.find()`. All this data (including base64 thumbnails) ends up in page-data.json, even if you need to render a only single employee.

This is solved by querying only the relevant employee(s) in the template and provide the data (name + photo) directly to the `EmployeeCard` component as props.

I've developed quite a few websites using Gatsby (mostly backed by various GraphQL API's such as WPGraphQL and Strapi) and while there's lots to learn, it's been an enjoyable experience so far.


You're extremely limited in what you can compile as a GraphQL query, so while yes I agree with you that likely there is some stuff we're simply doing wrong.. good luck doing it right. After all, its a database query language trying to create a giant cache of its results.

For example, we have what roughly amounts to an <Include> component. It uses some contextual information to include language-specific code. That include component pulls in a markdown file from disk based on 1) the includePath you set, and 2) the language selected. In order to make this function, we have to pull in _all_ possible includes within the static query, and then filter it down to the ones we need. There is literally no better way we could do this, because static queries are exactly that - static. There is no fixing this problem because the design of this data layer is broken by default.


You are basically complaining that the client is loading too much data because you are sending them too much data.

You could publish the different languages in different folders/path, thus, using the static queries to build static pages.

If you want them on the same path while loading different language content dynamically, that migh not be the best use case for gatsby. In that case you probably need to load every translation for each of the included paths, but not every path with every language for all of the different pages.


Have you tried using page queries? Page queries can accept arguments passed in via the createPage API. Here's some (admittedly hard to find) documentation about it: https://www.gatsbyjs.com/docs/page-query/#how-to-add-query-v...

The basic idea is your page context just contains identifiers for the content you need to display on the page and then the page query uses those identifiers to query for just those objects and request all the properties of those objects that the page needs.


That only helps when it’s coupled to the page. Doesn’t make a ton of sense in our use case as it’s just an arbitrary component. It would have to support queries based on component props, but that’s even more complexity in an existing nightmare.


I wonder why it seems nobody wants to use Hugo. Smashing Magazine appears to be happy with it and they tooted about their experience with Hugo multiple times.

Instead, everyone chooses Gatsby, Next or another javascript based framework of this week.


I've tried to use Hugo multiple times and absolutely hated it.

It's in a very weird spot in terms of difficulty/productivity.

It's got a very steep learning curve, with a lot of complexity. Things like how it resolves certain values involve following multiple steps that may or many exist in your project and require knowing framework specific rules and terminology. Stuff like which template is used is so complicated. All the other stuff about taxonomy and archetypes, etc also get really confusing.

But all that complexity translated to very little productivity (for me at least). I struggled with setting up beautiful templates, and found all the extra configuration cumbersome because the simple things I wanted to do was buried under all this other crap I had to learn about.

And when I did need advanced features, I didn't want to use hugo. Or things that I did need, were core aspects that were difficult to do with hugo because it's core configuration is so bloated.

Not to mention all the problems with versions and documentation that I had when one at least one of the occasions I tried it.


I looked into using Hugo and some other SSGs and eventually decided to hack together my own minimal version in Python.

It doesn't do much, it doesn't handle Markup (because that's not how I want to work), and it probably took less time than really mastering someone else's SSG.


As many other comments are saying, because it's Go.

The majority of developers who use static-site generators professionally are frontend developers. Their language of choice is javascript or typescript. And if many are complaining about the inconvenience of writing graphql plugins — in javascript! — for Gatsby, imagine the annoyance of having to write the logic for your build step in an entirely different language. In Go, or in Ruby for that matter. It isn't fun. You can't easily use the skills you developed in javascript to tweak the behavior of the static site generator to your liking. You can't extend its behavior by writing a custom plugin. You feel constrained, and at the mercy of Hugo maintainers. It's very disheartening.

However. There is a fantastic alternative both to Hugo (by being javascript-based) and to Gatsby/Next (by not requiring React for the simplest hello world). Its name is Eleventy, and it is beautiful!


Hugo is a single executable - it doesn't require any knowledge of Go itself. Granted, you have to be familiar with the templating syntax to add build-time logic to the website, but I believe that syntax is common across many other static site generators as well.

Yes, if you want to add logic in addition to the templating primitives provided by default, then being able to write code into the source pages will be of great help. However I think that when such a level of dynamism is required, then one can start debating the utility of a static generator in the first place.


Hugo is really, really good at what it does. I run a number of static blogs on it, including that of my startup [0] and my personal blog [1]. However, for many purposes, a completely static setup like the one that Hugo offers is surpassed by the reactive capabilities of Next.js/Gatsby/Nuxt, etc.

For larger, more complex sites, javascript frameworks make more sense, and offer far more functionality for building a web-app.

Two different purposes, IMO.

[0]: https://blog.assembl.net [1]: https://blog.slm.space


Plus, you can generally take the the dynamic generators and dial them down to a purely static build for sites that genuinely aren't using client-side features, but you can't go in the opposite direction.


Each time I've looked into the react based static site generators, even late last year this seems not to be true, at least not easy, they always seem to bundle client side js for rehydration, turning that off seemed impossible and wasn't a priority seemingly for many generators because the site would work without js enabled, but for cases where I don't want my sites payload to include a huge bundle of needless js then I was out of luck.


The React SSGs are not very good at this, but as mentioned in my reply to the parent comment, Nuxt.js (based on Vue), is a great option. See https://nuxtjs.org/blog/going-full-static.


I've done the "turning off javascript" thing with next. It involved a minor override in _document.js to avoid generating the script tags. Not officially supported, but not hard either.


This is a good point. I've been very impressed with how well Nuxt works for static builds: https://nuxtjs.org/blog/going-full-static.

I think for a startup with the liberty to choose a new tech stack, Nuxt.js is a great choice. It allows you to start with simple S3 bucket hosting, and move up to Vercel/Docker on ECS/etc. as you grow.

Hugo is a fantastic choice for blogs, but not for much else.


I built a data intensive website with Hugo and it’s horrible. Template engine is very bad. Hard to write reusable small functions (string manipulation, array manipulation, data extraction, mapping one form of data to other, filtering etc.). The fact that statements can’t be multiline is ridiculous.

Coming from Hakyll which just gives you all the power of Pandoc and a programming language, it was really a chore to work with Hugo. I’ll never use it again.


I never tried Gatsby, but I tried Hugo. I like Go, so I searched for a Hugo-template I liked and build some documentation for my project. Then I took a break from the project and when I wanted to update the documentation a few months later (minor changes), I spend about 2 days just bringing my content in sync with the updated template. What a horrible experience.

Maybe I was doing something wrong or the template author, but actually I am thinking about my best options currently, because I am 100% sure, I don't want to go through that mess again. Even building plain HTML pages by hand would have been a lot easier for me than finding out why the updated template didn't compile anymore.


What was the actual issue it did not compile and what was resolve?


If I remember correctly, Hugo wasn't able to process the template-content combination when I tried starting it after a few months of not using it (Hugo had been updated meanwhile). So I updated the template which didn't solve the issue. Then I tried to find out what changed and it wasn't just a few lines of code, but more fundamental things.

In the end, I just took a completely fresh version of the template and rebuild the documentation by copy and pasting the relevant parts.

For context: Initially I build the documentation in November 2018 and the update happened in April 2020.


You could have just used the same Hugo version as initially.

It's a moving project and yeah, there have been a lot of changes, with some breaking ones (usually for good reason).


For what we know 0.x version is not backward compatible as with many other projects, that can break many things. Let wait for a bright release.


For what it’s worth: I tried Hugo and hated the templating language.

I know React and Next let me solve my problems faster.

That’s it.

(Aside: Both Gatsby and Next have been around for a while and will be for the foreseeable future. So not a flavour of the week.)


Hugo has a lot of generation logic so it will always be faster to develop in it than React which has no concept of a website, blog or CMS.


For those who want to like Hugo, but can't stand the templating language: there's also Zola (https://github.com/getzola/zola), a superb static site generator, with built-in Sass compilation, written in Rust.


There is a shit tonne of static site generators that ain't hugo though.


Zola is worth mentioning because it is very similar to Hugo in most ways.


I use two pieces of backend software: Django and Hugo. Django is hugely more complex and I have considerably more experience with Hugo... And yet I run into far fewer problems and get stuff done faster with Django.

Hugo has exactly one thing going for it compared to other static site builders: it's fast. I have about 100 pages now and they build in <1second.

Aside from that, it's a pain to work with. The documentation is sparse but serviceable, but the community on GitHub and Discourse leaves a lot to be desired. Grumpy and unresponsive and much more inclined to close your issue or tersely tell you to read the docs than provide help or admit you have a valid feature request/bug report.


I would disagree with your complexity assessment there. Hugo has so much inferred logic and "magic" that working out why your pages aren't showing correctly can take hours before you notice the silly mistake you made. You're just slapped in the face until it starts working.

Django is of course a lot bigger, with many more moving parts, but it's much more explicit, Nd the documentation is superb; you're running a lot quicker.


Because Hugo doesn’t solve the dynamic problem. It also is not flexible enough for composing content. If you look at the Sentry docs you can see that it depends on the flexibility of the graphql system to feed shared content to different parts of the documentation.


Maybe a static site engine shouldn't be solving any 'dynamic problem'

That has a strong smell of losing focus on your core principles and obsessing over adoption stats at any cost


Dunno, but I'm going to take a stab in the dark at the possible incentive structure:

(1) No amateur is especially proud of setting up a static site, because it either seems easy as expected or it wasn't easy and they don't feel like trumpeting that.

(2) Professional web developers went into web development because they like featureful JavaScript, so they don't really see the appeal of static sites.

(3) Some big % of professional designers went into design because they wanted to design complex user experiences, and so they push for things that require JavaScript.

(4) Website owners like metrics, so they want a bunch of JavaScript to track user engagement and whatnot.

I have seen good results from Hugo. It is easy and typically works. Good for a small business website.


I wrote a frankenstein script to stitch together Hugo + Netlify + GitLab to automate the structure of my 300-something domain names, see e.g. https://awesome.id, https://every.id and https://debut.id.

For the content (not done yet), I want humans to write it, but haven't found a scalable approach.


Gatsby did feel way too much engineered and I went with Hugo. It's not perfect but it works well and I understand it.


After spending two weeks with Gatsby for my current project, I ditched it for Hugo and it was GREAT.

Not only Gatsby feels complicated for simple things, but doesn't offer the same level of flexibility as Hugo does. And it also has the most appreciated benefit of not having to battle with the js ecosystem. Hugo just works.


I use Hugo a lot. I'll admit it does have a learning curve.

Once you figure out how to really effectivity use it you can be productive and build out some huge websites and it's fast as hell.


> Once you figure out how to really effectivity use it you can be productive and build out some huge websites and it's fast as hell.

I don't doubt that, but a site that is a) huge, and b) doesn't require interactivity seems rather niche to me. SSG's really shine to me on small sites, and to some degree mid-sized ones. Code documentation is a good example, where I made some new library at work and now I want to dump some nice documentation somewhere. It's only a few pages, all I need is a way to convert Markdown to HTML in a semi-pleasing format, and have the SSG handle creating an index or ToC sidebar so people can navigate.

Hugo sucks for this. The templating language is Go's, which I don't care for much, and doesn't seem to be very widely used outside of Hugo. So now I have to learn a DSL just to use Hugo, which is unlikely to be useful for anything else, ever.

The templating language also seems to change constantly. I feel like every time I update Hugo, I have to go find a new theme, because now I get 10,000 warnings that they're going to redo the whole template API, and like 7 things my theme is doing aren't compatible with their new API. Of course, someone will say that I can build my own theme. And you're right! If I want to go become an expert in this esoteric DSL so I can figure out how to iterate over pages to build my ToC. Plus now that I'm building a theme, part of me starts wondering if it wouldn't be easier to just hand-write the HTML.

These NodeJS site generators are at least an order of magnitude easier to work with. I get code completion, so I don't have to try to remember all the various built-in and custom macros. I get unit tests, so when I change something in my theme, I can test it. I find that it's easier to genericize things from tutorials as well. If I want to add a navigation sidebar to all my pages, I just need a tutorial that shows me where I hook into the base page template (i.e. add a customizePageTemplate() call when you instantiate the renderer or something). From there I can use code completion and docs to figure out what I have access to to do the things I want. Again, that's because it's a familiar domain. If I want to do the same thing in Hugo, I pretty much need a tutorial specifically dedicated to customizing the base page templates. Even if someone tells me where to customize it, I end up having issues because the things you can access inside Hugo depend on where you are in the rendering pipeline, and Hugo's templating language doesn't make it easy to tell what you have access to at the moment.

I do admire their speed, but I have had effectively no situations where I have a site that is both large enough to be worth learning the DSL, and simultaneously doesn't require anything that Hugo makes difficult.


I like Hugo. I've been using it since 0.17. I've forgotten if I found getting started with it easy or hard. But since then it has been a relatively smooth ride. No node or javascript baggage, fast build times, single executable - what is not to like?


Plenty of people use the "older" options. People just write more about the new stuff - and depending on where you look the audience skews.


Hugo have thousands of users.


Using gatsby is the worst choice I ever made, the build times are infuriatingly slow and GraphQL really is not a good fit for it.

The amount of time that you have to spend just fiddling with Gatsby is insane and then in the end it only barely works.

Their marketing keeps touting fast but I doubt there is something slower when you actually use it for something of consequence.


Their solution is to pay for their hosted build service, which doesnt even fix the problem.


After building a site with Gatsby, it feels like a prank to make the process of getting a bit of html and css on the page as complex as possible.

It’s like you’re not a heroic enough a developer if you haven’t wrestled three build pipelines and ten layers of abstraction before breakfast.


I migrated a couple of sites I look after from react-static (which is a nice, simple library but unfortunately had some fundamental issues that it sounded like we’re unlikely to be solved and gave the impression that it was struggling for maintainers e.g. https://github.com/react-static/react-static/issues/1203), one to Gatsby and the other to NextJS.

I agree largely with the findings described here - Gatsby felt quite slow and the GraphQL part feels like complexity overkill, for my use case I bypassed it using their createPage API but you lose out on eg the ability to reload a page’s data on the fly by doing so (from what I could work out - the documentation was a bit lacking in parts I found).

I was more impressed with NextJS, it feels generally more solid and easier to understand. It has a great preview feature where you can set a cookie and then the site will pull in data at request time rather than from the static site (perfect for CMS previews!) and build times seem alright - I haven’t had cause to look into speeding them up, which is a good sign.

Personally I’d go with NextJS in future based on my experience... that said, I’ve no idea if it would work well for their reasonably specialised use case!


I use createPages and I get hot reloading when running gatsby develop.

I also just figured out how to trigger hot reloading for sources that normally don’t trigger it (markdown files which I was manually processing).

Basically, I discovered that gatsby will hot-reload when it sees a change in code files (.tsx). So I created an essentially empty _rebuild-trigger.tsx file and imported that in my main page template.

Now, to change the page content and trigger a hot-reload:

- I have an observable subscribed in createPagesStateful that calls deletePage and createPage - Then write to the file _rebuild-trigger.tsx file

I need to make a blog post because it works great (and I could tie it to any change source - like file system watcher - during development).


Hmmm, I seem to recall that hot reload didn’t reload the content, but I’ll check again! In any case it’s not as smooth for allowing content editors to preview content as NextJS’s preview unless I’ve missed something - with Next it will reload the content on every page load if you have the preview cookie set


Please do share!


This commit has the important pieces. Look for the createPage call and rebuild-trigger.

I’ll try to put together a blog post when I can.

https://github.com/ricklove/rick-love-master/commit/8eebd4f9...


This looks very promising. I've given it a like, will take a deeper look when I get on the laptop. :)

Thanks a lot for sharing Rick!


Surprised they didn’t try Eleventy. I was just reading how a Mozilla team converted their extension documentation to it from Jekyll because it has support for Jekyll’s template language via a plugin.

https://hacks.mozilla.org/2020/10/to-eleventy-and-beyond/


Compared to 11ty, I would call Gatsby a bloated framework and that's how the developers also describe it "much more than just a SSG". Gatsby is a hidden minefield though, maybe my use cases weren't aligned but I didn't get why it's got so much hype for trying to find the problems that it would become a solution to.


I moved my website to Eleventy recently and it's been a fantastic experience.


What does it do that build time from Jekyll of 10mins+ was reduced to 3 secs?


Is it wrong to suggest and admit that I write on my blog in plain HTML? How often do people refactor their designs and links? In PyCharm, I can do Regex search/replace and it gets the job done if I ever need to change the template (which hasn't happened in last 4 years). Not a single minute spent on searching for the right framework, reading docs, setting it up, dockerizing the app, and perhaps even building CI/CD for automatic deployment.

Simple is better IMO. Just calculate the ROI and time spent on it and in next 10 years how often you'll be changing stuff in terms of template or links (Neither should change - Design is not fashion and links should be relative).

I also have complete 100% control over the page. I adapt it for a particular content if its got more pictures and less text for example. It's so easy and beautiful. There is a kind of zen-like aspect to it.


It is not wrong if you are the sole author of a blog. It might start to become wrong once you involve additional authors like a technical writer, someone in marketing, etc. And if you intend to pull data from a spreadsheet, github repo, or other source then you're going to either want a framework or start building your own similar build utilities.


Sounds like it works great for you!

However, scale that out to 3000 pages with a bunch of dynamic features, with many other developers and authors. You might find it a bit harder to manage then.


The first complaint in this is review is that markdown isn't rendered in custom MDX components, using this example:

``` <Alert level="warning" title="Note"> PUT/DELETE methods only apply to updating/deleting issues. Events in sentry are immutable and can only be deleted by deleting the whole issue. </Alert> ```

And goes on to shiw their ugly hack to make it work.

Well, markdown in custom MDX components is rendered. You only need to leave a line break to signal to the parser that this needs further processing. Like this:

``` <Alert level="warning" title="Note">

    **PUT/DELETE** methods only apply to updating/deleting issues.
Events in sentry are immutable and can only be deleted by deleting the whole issue.

</Alert> ```

Which I really don't find to be a deal breaker.

I stopped reading after that because I was hoping for a somewhat more informed opinion.

From my experience, build time/build complexity is Gatsby's achilles heel. But I've built some stuff that looking back I don't think I could have done without Gatsby, as I came yo it being new to React.

It's simple enough on the surface and as you dif deeper, there's plenty of knobs to turn.

My one wish is if they'd let you bypass image processing in the development environment. Apart from that, I can't recommend it enough.


> Which I really don't find to be a deal breaker.

If my content requires two extra line breaks that do not serve any purpose beyond dealing with the vagarities of the generator (where there is absolutely no reason it should work that way), that does not bode well for my further experiences.


Bleh, if you really want to mix JSX and Markdown you should expect at least some syntactic idiosincrasies


Advice on the "A Broken DOM" section: it sounds exactly like a hydration mismatch. Hydration is the process of React correlating existing DOM nodes from server-rendered HTML (SSR) with the initial render of the React app on the browser-side. (As opposed to what happens without SSR, which is almost always the app being rendered into an empty DOM node – no content exists yet.)

Satisfying hydration constraints is by far the hardest part of doing React server-side rendering. The basic requirement is: whatever HTML you rendered on the server, the initial render of the browser app MUST output that exact same DOM structure. Otherwise, it won't be able to correlate them correctly, and will get confused about which DOM nodes to update. You can seriously mangle your entire page this way – but usually, it looks like nearby content stuck in the wrong place, or incorrect updates.

Some things that lead to hydration mismatches:

- Time-based rendering. Time passes between when the server rendered the HTML and the browser initializes the app. So any component using `new Date` to make decisions can potentially have a hydration mismatch.

- Randomization. Let's say you wanna choose a random promo image to show. The `Math.random()` result is going to be different on the server and client.

- Anything involving browser APIs, like the browser window size, or checking `typeof window`, etc. The server has no access to this info, so it either needs to skip rendering that content, or fallback to a default.

Once in the browser, here's the important part: you need the app's components to make all the same rendering decisions that they made on the server, on the first pass specifically (when hydration occurs). Then, using the component lifecycle, you can make them update to take the latest client-side info into account.

In other words, it's not enough to simply detect `typeof window` and render different content – you're only "allowed" to render that different content after the app has done its initial mount.

The somewhat-reassuring aspect of all this is that it's almost certainly your components at fault, not Gatsby or React, so it can always be fixed without too much effort. But it's an annoying foot-gun to have to worry about nonetheless.


Seems insane that these kind of quirky bugs are an issue in a modern system. Why isn’t there some kind of checksum to catch them immediately?


React does detect and warn you about mismatches in dev mode. It can be tricky to track down if it only happens in prod, though (due to different data – like start/end times for content coming from a CMS).

React could do better in both dev and prod though, IMO. It doesn't tell you where/which component had the issue, just the type of DOM node with a mismatch.


Yeah, that's quite similar with my experience. The idea is really nice and when it works, it's great. But debugging those GraphQL queries without any intellisense and writing monstrous config files eg gatsby-node.js makes me wish for something better.

I understand that because the API gets so complicated it's better to use something flexible like GraphQL. But the magic breaks down too easily in places and then you end up trying to fix some really peculiar bug (I had one where you had to put blank .eslintrc to the root to prevent the linter from linting local linked npm libraries).

I think parts of Gatsby core should probably be rewritten or done in different language to make it faster. The compilation shouldn't take that long. But I'm not sure what are the remedies for the other problems. Maybe if they focused really hard to simplify the library into its very basics, following the Unix philosophy, it could help with the creeping complexity headache that Gatsby brings.


I think alot of folks share this view. When we switched our marketing site over to Gatsby it was a godsend, but once we hit over 400 static pages on our site, the build times were killing us.

Our devs complained that even on local, building took forever, and because it had to refetch all of our WordPress CMS media library each time, sometimes it would just crash during build.

Also we grew the need for good SEO support for dynamically generated pages (of which we have thousands), and we had to write our own prerendering lambda function to handle bots (and embed tools) that couldnt run js on their own

After Next announced their support for static site generation and the release of next-serverless, we took the next three weeks to get our site ported over and haven't looked back since.


"building took forever" -> That's how they make money (which is fine). https://www.gatsbyjs.com/cloud/


I tried using their build tools to improve our build times but they didn't work and they never got back to me in a timely fashion so I gave up on it.


The creator of Lektor (https://www.getlektor.com/), aka @the_mitsuhiko, works for Sentry, and as I got from David Cramer himself over Twitter, Lektor is used for various secondary or internal websites at Sentry.

Has it been a contender for the rewrite of their documentation?

Shameless plug: I'm in the middle of a rewrite of my company's website (https://abilian.com/) using Lektor myself. So far so good, for someone used to Python and Flask it's the obvious choice for a static website generator.


Static site generators are a weird bunch. A vast majority of the projects never leave the beta phase and only a select few are relatively stable and regularly updated. That aside, the community aspect is even more vital in my experience. Unless you're an expert and understand the inner workings of the project, you're going to have to rely on documentation and community tutorials and starter projects.

I wouldn't for example know if something is even possible to achieve with a project unless someone had a repository showcasing how it is done, which has made me wary of betting on anything too immature. I just don't have the skills to bridge the gap myself.

Personally, I've stuck with Jekyll up to last year for these reasons, but right when COVID hit I started to delve into 11ty. I can say that it has been nothing short of a delight and the community is pretty stellar as well. I'm currently experiencing build times measured in milliseconds instead of minutes or so. I've been impressed and the project is developed actively and each update brings very concrete upgrades every time. Currently, I have the honor of sitting on top of the performance leaderboard for 11ty. Over half of the 400 sites there scores full marks in Google Lighthouse scores which should tell you something.


Gatsby is a mountain of unnecessary complexity. I've built a few Gatsby sites that I'm still maintaining and I will never use Gatsby for a new project again.


Gatsby is a great idea, with a questionable execution. Being able to build your entire site with React, make all of it statically rendered, and then opt into interactive/dynamic parts as needed is really great. Pulling in data sources at build time can be excellent. Overall I like the ideas behind Gatsby a lot.

But with real websites, I struggled to get Gatsby to be performant both at build and runtime. Gatsby really wants to preload other pages on your site in an attempt to speed things up, and you can't opt out of it. Whether this preloading is a benefit is a real mixed bag, and I have found myself spending a lot of time tweaking things to try and make it a net plus across the site. Mostly with bad results. gatsby-plugin-no-javascript can really improve things here a lot. It allows you to opt into JS only on pages that really need it, kill off the preloading entirely, and gain more control over the end result of your site. It's very strange that to get something like Gatsby in the ballpark you want you need to strip out JS, but well, it's true.

gatsby-plugin-no-javascript is not a perfect solution. It's too coarse. But I have found overall it can be a net positive. What I really want is the ability to say "this part of the page/site/whatever is truly static, please don't rehydrate it at runtime".

Gatsby's plugin system is nice. I like being able to handle things like robots.txt, sitemaps, favicons in a well defined, easily managed part of my app. The downside being you gotta accept what the plugin gives you. For example the favicon plugin generates favicons that are over 30kb. In my case, the favicon is often larger than the entire rest of the page combined. So I still find even here Gatsby is a good idea with questionable execution at times.

Gatsby has strict caching requirements -- https://www.gatsbyjs.com/docs/caching/ -- and if you can't meet them, your site will have subtle bugs. This means Gatsby is not compatible with Github Pages, and is a major downside to Gatsby.

This article spent a long time complaining about MDX. I agree, I think MDX is quite bad. But of the 4 complex Gatsby sites I have built, none of them used MDX. I don't think it's fair to conflate MDX's short comings with Gatsby.

I'm currently playing with Svelte's Sapper. It might possibly become what I always wished Gatsby was.


When I found gatsby, I immediately stripped everything out and hooked into the dynamic createPages so I could just give it a list of components to turn into pages. (I thought the graphQL parts were horribly bloated boilerplate, so I didn’t want to even touch it.)

It also works well with async import for runtime loading of components.

Other then that, I don’t use any of it’s features. (I found a markdown react on npm and manually move the images to the public folder and use normal image tags.)

I’m quite happy with the runtime results, and develop re-render works pretty quickly. However, the production build takes about 30 secs which is pretty slow and I also ran into “out of heap memory“ on node during build and had to increase node’s heap size.

So I’m sure I’ll end up needing to build my own SSR eventually, but it should be easy to do.


Gatsby's one saving grace feature is the createPages API - it lets you programatically create pages at a specific URL with a specific template (React component), with context passed to the template that's not present in the URL. The benefit of this is you're able to render multiple difficult templates at the same URL pattern.

Gatsby does, however, suffer from huge scale problems, I think mostly due to the data type inference it needs for GraphQL. Once you start ramping up the number of models and records, it will churn forever ingesting them. There are hacks and ways to particially mitigate some of this, but still Gatsby continues to have problems once you're working with a medium amount of content.


Yes, I see the scale issues and I don’t have much yet (I assume because I am using createPages it doesn’t use any caching).

At runtime it’s excellent - perfect scores for performance - and using the website is perfect, so I’m thankful that gatsby let me get started quickly and see how good runtime performance can be.

I’m planning to replace it with React’s built in ReactDOMServer (and I can do a simple change detection and rebuild only changed content easily).

Honestly, it will probably be easier then all the hacking I had to do to get gatsby to work the way I wanted.


> I assume because I am using createPages it doesn’t use any caching

It's not this - we only used createPages and ran into these issues. It's the ingesting content from contentful or any database that'll continue to grow where gatsby lets you down.


I tend to agree with a lot of this article, having done a fair few Gatsby sites. I'd love to ditch GraphQL entirely and use proper SQL. But keep in mind this is all build-time complications, and at the end of the day you have static data sourcing all your pages.


I've honestly found that the learning curve for Gatsby is too high. I've been using Next.js and I absolutely love it!


Not mentioned here, and rarely mentioned anywhere is marko.js as a good alternative. Its not static site generation, but it's faster than most static site generated even though it processes templates on the server. The markup does not even need to learn: its pure JavaScript in the markup, it makes it so intuitive to create templates.


I do wonder: where was the point of no return? Maybe scrapping it and starting anew would have been better.

I wish the article mentioned that.


Are all non-trivial systems just so many Rube Goldberg devices?


This mirrors my experience as well. Extremely slow build times, a lot of complexity that is hidden at first but is going to rear its head sooner or later, and GraphQL everywhere for very unclear reasons. Also, surprisingly easy to misconfigure something and get very poor TTI and other Lighthouse scores.


It's amazing to me that there's still not a super simple create react app option out there that builds a react app based on markdown sources for pages. You can get close to it with gatsby et al., but they're all twiddly or fragile in their own ways.


For Vue, Nuxt recently got a content API which I've been using and it is great. If there really isn't an equivalent for React I'd be very surprised.


Elder.js for Svelte looks like a great "pure SSG" alternative for larger SEO sites:

https://github.com/Elderjs/elderjs


The last time I had to work on a Gatsby project, it had build times of approximately nine hours.

Last thing I heard from them, is that when faced with the need to update news on the site more quickly (not on realtime, but "sooner"), the development team had to make a separate mechanism to query the news from the backend when the site was running on the browser, instead of doing it at build time, using the builtin GraphQL database. This defeats the central idea that everything on Gatsby comes from a central data source.


For those of us not familiar with these systems - can someone please link to something more introductory?

I literally thought this was an item about the Australian stand-up comic (but that's Gadsby with a D).


Gatsby build times are getting slower especially for images. Just started using Gatsby using a starter theme ( https://www.bobbydreamer.com ). I am just imagining, if I continue to use this theme and add more posts and pictures for next 10 years. How slower can it become. Gatsby is fast and site starters are really sleaky. If builds are faster/optimized, it can help.


I had a bad experience with Gatsby too. I am fond of the Gatsby-Image plugin for an image heavy website because it will generate all the images you need for responsive sizes, plus webp, plus a blurry preview.

The downside of this is that the lighthouse profiler currently does not score this setup properly and the blurry placeholder results in a lower score. There was an open bug to fix this last I checked.

The other major issue I faced was to setup netlify CMS for my own hosting. This ecosystem seems to very forcefully nudge you to use their infrastructure like Netlify or Gatsby cloud. I didn't want that for a number of reasons. The documentation to set it up for your own server is in an absolutely pathetic state. All the steps described are cryptic and I ran across multiple questions and issues filed by confused users. I finally found a blog post which covered a large number of gotchas and I was able to set it up.

My customer manages the content on their site on their own. They were happy with the performance upgrade but the prospect of waiting a few minutes for the site to recompile everytime they make an update felt like a big step back to them.

I was not happy with seeing enormous json files being generated for what is essentially a website with a homepage and multiple categories with large photo galleries in them.

The other thing I was not prepared for is the hardware required to build the site. Small servers were running out of memory to do the build so I had to setup CircleCI to do the builds for me and then copy everything back to my server.

Another weird scenario I ran into was that the development version and build version had different outputs. I eventually solved this by noticing an issue with the DOM which didn't get picked up by anything in the build tools. Took me a day or two to finally figure it out.

In hindsight I am now wondering if I should just roll my own image resizing scripts, switch to a crud web app and cache all the generated htmls on first load and delete the cache when a change is made and prime it. This has been my approach prior to Gatsby, but I was sold on their marketing about how I get all the speed benefits for free and not have to worry about sizing images, setting up webpack for performance and splitting for routes, setting up metatags for prefetching/preloading etc. Turns out you're better off doing all that on your own.

Broadly I probably wouldn't use this framework again unless it was for a simple blog or something. The experience has left me quite annoyed. I am probably not going to follow this JAM stack philosophy in the future either. I don't really see the benefit. Are people really that afraid of managing servers?

I am also considering redoing the entire site in Sinatra the next time I add features to it.


> and the blurry placeholder results in a lower score

I do not like it when people use these images. I think you get a better result when you use the now supported loading=lazy attribute on images https://web.dev/browser-level-image-lazy-loading/


Those are triggered for before the fold images, I primarily use them for above the fold content to try and get as close to immediate loading for the user. That way they can interact with the site quickly if they aren't interested in the image - maybe click a menu item, etc.

In the third world we have to be especially sensitive to these things because mobile data is often incredibly slow, even on 4G.


"Modern" is a term that should be reserved for improvement and progress. Are Gatsby users experiencing net gains from the alleged modern tooling?


I wonder... If Jekyll worked better, wouldn't have been better to just invest some time in learning enough ruby to make jekyll fit their needs?


I thought the same thing. I would like to know more about why they wanted to switch.

I use Jekyll for a few sites that benefit from gitflow around markdown collaboration and it’s pretty solid. I read about other generators and if something is easier or better I’m interested.

But for me, it seems Jekyll solved this problem years ago. And it has good docs, active development, etc.

The few people I know who switched off of it did so for what seems like arbitrary reasons to me. A group I collaborate with switched to gatsby because they said some of their developers couldn’t run Ruby on their workstations. And I guess switching their generator to gatsby was easier than figuring out that problem :)


Probably JS developers didn't feel like learning anything else because "JS THE BEST"... That's the sad reality.


> gigabyte-sized Sentry frontend app

Mr. Nolan, please invert me, I have to fix an awful mistake called "frontend frameworks" back in time.


It's an interesting experiment in switching between various frameworks but honestly, looking at the docs, they could just use WordPress.. but regardless of backend, I'm not sure I see a need for a React frontend here https://docs.sentry.io/


The page that was there before was an ungodly jquery mess. There are some dynamic parts like the API key selection, code snippet toggles, copy/paste support where react made the overall code and user experience significantly better.


I just wonder how much time had to be spent trying to get a static site generator to build quickly and correctly, and how much time it would have taken to deploy a CMS and a caching layer, or wire up a UI over a headless CMS.


> approximately 0% of the engineering team knows Ruby

I found this surprising. I once worked somewhere that used Sentry heavily (liked it a great deal, it was pretty important to us). We had about a hundred projects and were encountering quota problems, the worst of which were usually from misbehaving queue workers on staging or perf the would consume our entire event budget if left unchecked. If we didn't shut it off in time we'd end up losing meaningful prod events.

Our solution was to switch to a YAML based config for rate limits and per project quotas. This would ensure every project was capped, central prod services were allocated more events like they deserved, etc. Sentry staff sent us a helpful starter script for utilizing their project configuration REST API. It was written in Ruby.


Gatsby was amazing for getting a landing page with a blog off the ground. It's much less compelling as we expand what we want our landing page to do .


Wes Bos released his 'Master Gatsby' course a few days ago: https://mastergatsby.com/


Isn’t it beautiful? You create an open-source community, grow it, get donations, start selling the product, sell cloud services, and finally sell content and training to actually be able to understand the complexity.

All to deploy static websites, something you can do for free with near zero complexity by simply choosing another option. The JS world has become a marketing machine.


I don't think the abovementioned course creator works in Gatsby, Inc, or contributes significantly (I see a few small pull requests) to the Gatsby open source project.


Serious question: Why generate a static site at all instead of running next.js behind a CDN? Now a publish is really just a publish instead of a rebuild.


It's a fair question that everyone should ask themselves in our shoes. If we did it again maybe we'd rethink.

That said, the entire goal was to allow a non-engineer to more easily enable our end-users with documentation. We didn't anticipate the amount of engineering hours it'd take to actually get this functioning well given its adoption and ecosystem. Even the investment into MDX though was to service the core goal: create clean abstractions for the complexity where possible.


If the goal was easier content authoring you can tie Gatsby (or next) to a CMS. Something like Prismic is pretty inexpensive. You can easily tie publishes to trigger a site rebuild.


Perl's Template Toolkit has provided everything I've needed in a SSG for the last 20 years.


Thanks for the blog post. I thought about trying Gatsby out, but now I know to stay away from it.


"gigabyte sized app" WTF


Argh, I thought this was a (potential) new take on "The Great Gatsby" but it turns out to be some web framework I haven't heard of. Could we maybe name things so that tech things sound like they are tech?


All that useless effort for just some static pages. Can't believe how much money, time and resources are wasted by these hipsters. Why don't they solve actual problems that could help our race, instead of resume driven hipsterness.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: