Content has not been updated for more than 2 years, proceed with caution.
How to setup a Gatsby themes monorepo
I manage a Gatsby themes monorepo that currently has 11 themes and 8 starters with over 1500 commits - lots of moving parts to keep organized. At the end of this tutorial you will have a Gatsby themes monorepo setup with automated testing, automated dependency management, automated publishing, continuous integration, and continuous deployment!
Here are the tools (all free) we will be reviewing in this post:
- Yarn workspaces for package management
- Lerna for automated publishing to NPM
- Cypress.io for testing
- GitHub actions for CI
- Netlify for CD
- Dependabot for automated dependency updates
This post assumes you have some basic familiarity with Gatsby, Gatsby themes, NPM and GitHub.
This is a long one so get a fresh cup of coffee and let’s go!
Use a template
Gatsby Theme Empty is a GitHub template repository that is preconfigured with the tools mentioned above so you can quickly get started with your own project and avoid lots of copy/paste. I intentionally kept this repository as “empty” as possible, it is only a hello world, and instead focuses on the tooling for the monorepo itself.
-
Click the
Use This Template
button on GitHub which will prompt you to clone the template into a new repo under your own username. -
Clone your new repo locally and open it in your code editor of choice.
Explore the files and folder structures. Themes and starters are located in their respective folder. There are also folders for Cypress.io and GitHub. You will notice some configuration files for the tools and that is about it. My hope with this template is that there is little, if anything, you need to delete before you can start working.
Find and replace magic
Update naming across your files and folders using find and replace.
-
Do a find and replace for
empty
->your-theme-name
. Click replace all. So for example if your theme was going to be namedgatsby-theme-kickoff
you would find and replaceempty
->kickoff
. -
Update the folder names to properly reflect your new theme and starter. You should have folders that look like
themes/gatsby-theme-your-theme-name
andstarters/gatsby-starter-your-theme-name
.
Update package.json files
Browse to themes/gatsby-theme-monorepo-tutorial/package.json
and starters/gatsby-starter-monorepo-tutorial/package.json
and update any fields you need to like the author, description and repo links. The name field should already be correct if you followed the above steps correctly. Note that the starter’s package.json has a private: true
field set on it so it is not published to NPM. Typically people only publish the theme to NPM.
Setup Yarn workspaces
Run yarn install
in your terminal to start installing all of the packages and creating a lock file.
Yarn workspaces abstracts all of the complicated package management necessary for local theme development. In practical terms this means you can seamlessly work on both your theme and your site at the same time and only push changes to NPM when you are ready.
Yarn workspaces are configured through the root package.json file with a special workspaces
field which tells Yarn where to look for additional dependencies and related packages.
Here is an example package.json, note the use of custom scripts to shorten the workspaces syntax and that private is set to true.
If you are having any issues you can run yarn workspaces info
and you should see something like this if it is properly configured:
Commit to GitHub
At this point you have a minimal working setup of a Gatsby themes monorepo. Now would be a good time to make a commit and push to GitHub.
Develop for the first time
Run yarn develop:your-theme-name
to make sure that the starter is building successfully. So for example if your theme was named gatsby-theme-kickoff
your command would be yarn develop:kickoff
; this script shortens the longer workspaces syntax. You should see a very simple hello world page if it builds correctly.
Congratulations you now have a working Gatsby themes monorepo! But wait there is more!
Setup Lerna
Run lerna init
to set Lerna up to monitor your packages for changes. You can use the command lerna publish
to publish packages to NPM (you need an account). Before you deploy to a host provider the theme will need to be published.
Lerna watches your packages in the background and tracks whether a particular package needs to be published again or not based on changes. It also automatically manages updating versions for all your packages during the publish process. For a smaller repo you could manage this manually yourself however as my monorepo got larger and more inter-connected Lerna has been a huge productivity win.
Note that any packages with private: true
, like your starter, will not publish. Also the publish command will give you a final check before actually publishing anything, so don’t worry you can run lerna publish
and then decide not to publish.
The lerna config is located in the lerna.json
file and looks like this:
Cypress.io and GitHub actions
Run yarn test:your-theme-name
to start Cypress.io. So for example if your theme was named gatsby-theme-kickoff
your command would be yarn test:kickoff
.
Cypress.io is provides excellent, and well documented, end-to-end integration testing for web development. They also maintain a GitHub Action for Cypress.io which allows you to run tests automatically against every PR and Push on the main branch. This CI testing has been tremendously helpful for me in catching errors and preventing merges that contain breaking changes.
The template repository includes a basic smoke test - which simply test whether your site built successfully or not. This smoke test is setup to run against every PR and Push to the main branch of your repo.
There is also a set of tests for accessibilty (a11y) that use cypress-axe to perform a basic accessibility audit of your website. This test needs to be manually run and is not run on every PR and Push although you could configure it to do this.
Here is what a basic Cypress test looks like:
Here is what the GitHub action looks like:
Deploy to Netlify
You don’t have to choose Netlify, you could use any hosting provider. Your theme also needs to be published on NPM for this to work.
Login to Netlify and create a new site with default settings pointed at your new GitHub repo - it will just work which is pretty amazing!
The template monorepo is preconfigured for Netlify using netlify.toml
to build and deploy the starter in your starters folder. Netlify will watch the repo and re-deploy when any changes are pushed to the default branch.
Dependency management with Dependabot
Note that this is referring to Dependabot v2.0 which is an internal GitHub process and not the older version which was accessed via dependabot.com
Dependabot is setup and preconfigured via .github/dependabot.yml
which automatically activates dependabot for your repo. No sign up, sign in or configuration necessary. Dependabot automates dependency management for your monorepo and will make regular PRs against your default branch with updates.
Here is what the included dependabot config looks like:
The included config is set to check for daily updates against your root package.json folder, which because of workspaces will also target all of your sub-folders and dependencies. I have found it helpful to manually manage updates to Gatsby itself so that dependency is being ignored. There is good documentation for these options and other available settings on the GitHub website.
Dependency management is something that in a smaller, and less complicated repo you could probably manage yourself and however on more complicated projects having the dependencies managed automatically is a great feature to have. The other big bonus is that your Cypress.io tests will run against every single PR and allow you to confidently merge updated dependencies after your tests have passed!
End result and next steps
You now have a Gatsby themes monorepo setup with automated testing, automated dependency management, automated publishing, continuous integration, and continuous deployment! Amazing!
One final integration you may want to consider, depending on how you will be using Gatsby themes, is adding a GitHub action to publish your starters to their own repo. Check out actions-push-subdirectory for instructions on how to do this. This is necessary for starters to work properly with the gatsby new
command as they need to be in an indepedent repo at the root level.
If you want to see a more advanced version of this monorepo setup you can checkout Gatsby Theme Catalyst which uses these same tools across a repository with over 10 interlinked themes.
Happy coding!