---
title: Running Gatsby.js Sites with Craft CMS
description: The advantages and disadvantages of using Gatsby.js and Craft CMS in production. Includes alternative solutions for the more cautious developer.
pubDate: 2020-08-13
---

import Notice from "../../components/Notice.astro";

<Notice>
  If you're interested in a more general post about the value of a simpler tech stack, check out "**[Keep your stack short](/keep-your-stack-short)**".
</Notice>

We recently developed and launched a couple [Gatsby.js](https://www.gatsbyjs.com/) websites at [TrendyMinds](https://trendyminds.com/) that are sourced by [Craft CMS](https://craftcms.com/) as the back-end. Because this is a _relatively_ new way to build websites I wanted to discuss some technical learnings from this pairing.

I won't get into the general "pros" of Gatsby.js. There are [much better articles](https://www.freecodecamp.org/news/why-you-should-use-gatsbyjs-to-build-static-sites-4f90eb6d1a7b/) explaining why you might utilize a static site generator and the benefits they yield.

Instead, I'll be focusing more on what it was like using Craft CMS and Gatsby.js together.

## Front-end unification

One of the best, most immediate advantages of Gatsby.js is the opinionated front-end and first-class support for React components.

When developing a Craft CMS website your templating is done server-side using Twig and it's common to "sprinkle in" JavaScript. For instance, adding a React component might be handled by creating an HTML entrypoint:

```html
<div data-modal></div>
```

Then inject your React component:

```jsx
import { render } from "react-dom";

render(
  <Modal />,
  document.querySelector("[data-modal]")
);
```

And, while this _does_ allow you to utilize React within your Craft CMS templates, it lacks interoperability and you effectively "**hand off**" templating responsibilities between two parties.

Instead, Gatsby.js provides the ability to unite the front-end under React:

```jsx
import Modal from "./components/Modal";

export default function About() {
  return (
    <>
      <h1>The About Page</h1>
      <Modal />
    </>
  )
}
```

## Larger debugging surface

Gatsby.js has an immediate effect on site speed and gives developers the benefit of using React everywhere and GraphQL queries. **However**, the additions of these layers increases _where_ you might run into bugs.

If you're using Craft for your back-end and front-end the scope of problems is much smaller. It's limited to a reduced stack.

Consider the following architecture.

### A standard Craft CMS stack

<div class="bg-zinc-700 rounded-lg text-white text-center p-2 text-sm md:text-xl font-semibold mb-0.5">Craft Data</div>
<div class="text-center text-base md:text-2xl font-semibold mb-0.5 text-zinc-500">&darr;</div>
<div class="bg-zinc-700 rounded-lg text-white text-center p-2 text-sm md:text-xl font-semibold mb-20">Template</div>

### A Gatsby.js site sourced by Craft

<div class="grid grid-cols-9 gap-1/2 mb-20">
  <div class="col-span-4">
    <div class="text-zinc-300 text-center font-semibold mb-0.5 text-sm md:text-base">api.domain.com</div>
    <div class="bg-zinc-700 rounded-lg text-white text-center p-2 text-sm md:text-xl font-semibold mb-0.5">Craft Data</div>
  </div>
  <div class="col-span-1 text-center text-base md:text-2xl text-zinc-500 mt-8">
    &rarr;
  </div>
  <div class="col-span-4">
    <div class="text-zinc-300 text-center font-semibold mb-0.5 text-sm md:text-base">domain.com</div>
    <div class="bg-zinc-700 rounded-lg text-white text-center p-2 text-sm md:text-xl font-semibold mb-0.5">Gatsby GraphQL</div>
    <div class="text-center text-sm md:text-2xl font-semibold mb-0.5 text-zinc-500">&darr;</div>
    <div class="bg-zinc-700 rounded-lg text-white text-center p-2 text-sm md:text-xl font-semibold mb-0.5">Template</div>
  </div>
</div>

Our standard Craft CMS stack—while modest and lacking the benefits of separating your back-end and front-end—is simple.

The shorter stack allows for the scope of bugs to also remain shallow.

However, in our Gatsby.js and Craft CMS stack we've **expanded** the surface area where bugs may lurk.

#### On scaling

It's worth noting that there can be a benefit in this level of separation.

You might find separating the front-end and the back-end is _better_ because you now have the ability to scale the environments separately and prevent back-end outages from affecting your front-end.

This gives you more flexibility than the shorter, less sophisticated stack. But you'll need to calculate the cost of taking the bad as well as the good.

## Alternatives

Maybe you're considering Gatsby.js because you primarily want performance and better interoperability between templates and reactive JavaScript.

If that's you, I might recommend a combination of:

- [Blitz](https://putyourlightson.com/plugins/blitz): The wonderful full-page static caching plugin by [Ben Croker](https://putyourlightson.com/) that everyone should be using
- [Alpine.js](https://github.com/alpinejs/alpine): A fantastic, build tool-less, reactive, **~8kB** 😱 library that let's you handle reactive UI in your Twig templates
- [Sprig](https://putyourlightson.com/plugins/sprig): A [Livewire](https://laravel-livewire.com/)-inspired plugin to create complex views using AJAX and Twig templates (also by Ben Croker; what _can't_ this guy do?)

I think the three of these tools are well-built, designed for performance, and have fantastic interoperability with the server-side rendered templates that Craft CMS provides natively.

This helps eliminate the overhead of solving Gatsby.js problems like Live Preview, incremental builds, running server-side code without reaching for serverless functions (further increasing your stack). And it grants your server-rendered site the performance and (some of the) templating benefits of Gatsby.js.

## Closing thoughts

None of this is to dissuade you from using Gatsby.js and Craft CMS together.

In fact, you might be on the brink of a project that is **perfectly** suited for this setup and the separation of the front-end and the back-end is icing on the cake.

However, it's worth considering if this—along with _all_ programming choices—strikes the right balance of cost and complexity.
