New Course: Creating Plugins, Themes, and Starters with GatsbyJS
7 min read

New Course: Creating Plugins, Themes, and Starters with GatsbyJS

In this course you'll learn how to customize Gatsby by creating a starter, source plugin, transformer, and reusable theme package.
New Course: Creating Plugins, Themes, and Starters with GatsbyJS

I just published my sixth course, Creating Plugins, Themes, and Starters with GatsbyJS: Playbook on Pluralsight! πŸŽ‰

You can watch the course overview for a taste of what you'll learn:

Watch the Course Overview trailer

What's covered

It's about 98 minutes and there's quite a bit of coverage if you're looking to build your own plugins, themes, or starters with Gatsby.js:

  • Creating, customizing, and publishing starters
  • Creating local plugins to output static files
  • Creating a source plugin to fetch data from an API
  • Creating a transformer plugin to handle parent/child and foreign key relationships
  • Customizing GraphQL schemas for custom types
  • Converting a starter to a theme
  • Overriding theme files using shadowing
  • And lots of other little things that you'll encounter building stuff...

Based on my experience creating Gatsby sites and open source plugins, I've tried to represent the best patterns I've encountered throughout the course. I cover gotchas and things not always mentioned in the docs. I explain how to make the code more maintainable with encapsulation, options, and schema validation.

Pluralsight's audience is geared more towards business developers operating in an organization so the scenario I've laid out is building out a reusable theme and starter for an engineering organization to have individual customizable dev blogs.

What isn't covered

Pluralsight courses are targeted at around 90 minutes which isn't enough time to cover everything there is to know so I usually need to focus on essentials. What do I need to know to get a job done? Some things I initially planned to include didn't make the cut but I hope to revive them in the form of free video content or tutorials. They go onto the compost heap.

  • Transforming Markdown with Remark and ASTs
  • Automatic Layouts Using wrapPageElement
  • Customizing HTML Using onRenderBody
  • Debugging Gatsby plugins with VS Code
  • Using TypeScript for Gatsby Plugins
  • Testing Plugins and Themes with Jest and Cypress

The course primarily focuses on Gatsby Node APIs and doesn't cover SSR or Browser APIs as those are more "site dev" related. There was already so much to cover and most plugins use the Node APIs. Gatsby also has great coverage of a lot of these features in the documentation itself. There will be some upcoming courses in the GatsbyJS Learning Path that should cover Browser and SSR APIs.

How it went

I've shared insights into how I develop courses in the newsletter over the past months. You can also read more about some of the systems I have in place from my Testing Progressive Web Apps announcement.

Time spent was higher than I expected:

It's more than I thought it was going to be! πŸ˜…

It didn't feel like 130 hours but maybe that was because it was a little better spread than the crunch to finish Testing PWAs. I still had a crunch there at the end and I ended up pushing out my deadline by a week. This was semi-intentional as I used some extra time to finish a house project instead of working on the course. It was worth the pain!

I was upset a bit at how long some recording sessions went. About 2/3 through the course I needed to upgrade to Gatsby v3 to take up some bug fixes (otherwise I would have needed to use a custom v2 build).

Fixing a Gatsby bug

I shared this in a previous newsletter issue but I had found a bug in local plugin option schema validation and opened a fix for it:

fix(gatsby): validate local plugin options schema by kamranayub Β· Pull Request #29787 Β· gatsbyjs/gatsby
Description Fix for pluginOptionsSchema not being validated for locally resolved plugins.Changes Use resolvePlugins when validating optionsAdd integration test for local plugin loading/validati...

It was soon followed up by another fix for something I missed but that's the beauty of things – a proprietary product may never have fixed the issue in time for my recording. It merged by the time I needed it but it didn't block me because I had a custom fork of Gatsby running.

Soon did the npm come

npm did not enjoy the Gatsby V3 upgrade much and I had to keep using Yarn behind-the-scenes. I'm hoping it is just a my-machine issue and not a everyones-machine issue. However, yarn was way more stable and I didn't have any issues after I switched to using it (it's my primary package manager at home and work anyway!).

I waited for so many package installations that I had time to make a Wellerman cover to complain about how long it was taking. πŸŽΆπŸŽ™I am not a singer so I apologize in advance.

Watch the video

New stuff I tried

I did actually roll out some new ideas for this course and I'm excited to see how they go.


Video courses are not interactive by default and one thing I really wish is for better platforms to come along and make video/audio learning more hands-on (a merge between self-paced reading tutorials, live demo recording, and audio/video content). Pluralsight is working on hands-on labs and I'm applying to do those for the future.

In this course, I introduced Challenges at the end of some clips.

All the challenges are available in the course repository but most of them are designed to be open-ended slash don't have concrete solutions.

Course repository for Creating Plugins, Themes, and Starters with GatsbyJS: Playbook Pluralsight course - kamranayub/pluralsight-gatsby-starters-themes-plugins

I enjoyed doing them because they allowed me to quickly introduce a more intermediate-to-advanced concept and allow the learner to try it themselves. Things like using inquirer to prompt for the CMS author ID when bootstrapping a starter. It's my way of injecting extra content without explicitly taking up time to demo/cover it.

GitHub Discussions

It's been a sore point since I joined Pluralsight that the "Discussions" feature is just a Disqus integration (not even SSO integrated!) and is like the worst way to interact with learners.

I've been awaiting public roll-out of GitHub Discussions and now we have them so I enabled it for the course:

My hope is that people interact here instead of on the Pluralsight Discussions since they're so lackluster right now.

I did consider starting a Discord community but it's not like I need more time commitments right now – the GitHub discussions have a nice asynchronous workflow that suits my time better for now.

Gatsby Cloud

This was my first time using Gatsby Cloud which is built on Netlify which is what I normally use now for static sites.

You can view the demo starter live:

The demo starter repository reflects the final module state (which is a shadowed theme) but all the work I did is encapsulated in PRs people can go through or check out branches of the repo.

The demo starter for the Creating Plugins, Themes and Starters with GatsbyJS: Playbook Pluralsight course - kamranayub/pluralsight-gatsby-demo-starter

The benefit of taking a course is that even though all this code is public and available for you to browse, I cover it all in 90 minutes which probably isn't even enough time for you to actually get everything up and running and review one branch.

Everything in the course is technically available online in documentation, the source code of Gatsby, myriads of videos (sometimes) but that's part of the problem. A course should provide a polished synopsis of just-in-time learning to save you time – it's the usage, patterns, gotchas, and the how and why that's valuable, not the code really. That's why I have zero issues making all my course code public. Show your work, as Seth Godin would say.

Zipping up course materials

One funny anecdote: I had a PowerShell script I use that zips up individual module folders I normally use. This course is laid out differently and I wanted to zip up all the content into a single exercise files package for Pluralsight.

Because the sub-folders in the repo had folders I didn't want zipped, like node_modules, public, and .cache I had a heckuva time finding some simple package or script to handle that. All the packages/scripts I found either were way too involved (PowerShell, sorry) or didn't ignore things with globs/partial-matching.

I ended up modifying the closest thing I could find, dir-compressor, to support ignore files so I could pass a .courseignore and zip everything up in one fell swoop. It took me a couple hours but I managed to find fstream-ignore and leveraged that. Hooray for 5 year old packages that still work!

I will either wait for a response for my PR or just publish yet-another-fork of this fork-of-a-fork package πŸ˜„

feat: add ignore file support by kamranayub Β· Pull Request #1 Β· obender/dir-compressor
I was looking for a simple package to support an ignore list (e.g. .gitignore) (originally glob patterns but this is even better for my case).Changes Add fstream-ignoreAdd --ignoreFile <filen...

Enjoying these posts? Subscribe for more