Mountain in the distance across a lake in Fujikawaguchiko, Yamanashi, Japan
Evan Stern
Evan Stern
February 18, 202311 min
Table of Contents

Are you looking to create a blazingly fast and secure blog? If so, then you're in the right place. I will walk you through creating a GatsbyJS blog from scratch in this series. I've been using GatsbyJS for some time now and find it an excellent choice for building static sites. It leverages technologies like React and GraphQL, some of my favorite technologies to work with in a project.

This series, titled "Building a GatsbyJS Blog," will be a step-by-step guide from creating a GatsbyJS project to deploying the blog online. We'll go into a lot of depth in each post, so you'll be able to follow along even if you're new to GatsbyJS.

This first post will focus on creating the GatsbyJS project itself. This is a crucial step, as it sets the foundation for your blog. We'll cover everything you need to know, from installation to setting up the project's structure.

NOTE: I have opted not to use any themes or templates for this post. Instead, we're going to set this up from scratch! This gives better fine-grain control over the project and will help promote a better understanding of Gatsby and the surrounding plugin ecosystem. But, if you want to use a starter template, that's great too!

NOTE: This article assumes you have a basic to advanced understanding of Node, React, Git, and JavaScript/TypeScript. So, I won't explain how to set up your development environment. However, if you need a refresher or more information about setting things up, check the official documentation from GatsbyJS for a detailed walkthrough.

NOTE: At the time of writing (Feb. 2023), GatsbyJS is on version 5. Eventually, this series will become outdated as new versions of Gatsby are released. I will update these articles to note any changes to the framework. If you notice something obsolete or wrong, please don't hesitate to let me know in the comments!

Building a Gatsby Blog Series

Install GatsbyJS and create the initial project

Let's get started!

Install gatsby-cli

The very first thing we need to do is install the gatsby-cli globally:

npm install -g gatsby-cli

Create a basic project

Next, we will create a basic project in GatsbyJS. You'll run the gatsby new command and then answer the questions as outlined below.

Select the following options:

  • Name of site: My Gatsby Blog
  • Location of project: (use the default)
  • JavaScript or TypeScript: TypeScript
  • CMS?: No
  • Styling Systems: Emotion
  • Additional Plugins: Responsive Images, Manifest, and Markdown with MDX

I will opt-in to TypeScript and Emotion for styling. You don't have to do this, but it will make following this tutorial much easier if you keep in sync with what I do.

gatsby new
What would you like to call your site?
✔ · My Gatsby Blog
What would you like to name the folder where your site will be created?
✔ blog-related-repos/ my-gatsby-blog
✔ Will you be using JavaScript or TypeScript?
· TypeScript
✔ Will you be using a CMS?
· No (or I'll add it later)
✔ Would you like to install a styling system?
· Emotion
✔ Would you like to install additional features with other plugins?
· Add responsive images
· Generate a manifest file
Thanks! Here's what we'll now do:
🛠 Create a new Gatsby site in the folder my-gatsby-blog
🎨 Get you set up to use Emotion for styling your site
🔌 Install gatsby-plugin-image, gatsby-plugin-manifest, gatsby-plugin-mdx

Start the development server

Change directories into the newly created project directory and run gatsby develop to start the development server.

The development server is fantastic! It will automatically reload your app for you as you make changes (hot reloading) and does some other optimizations on the fly to allow you to develop your project seamlessly.

cd my-gatsby-blog
gatsby develop

And now, you should be able to see the site running by navigating to http://localhost:8000.

Set up Linting and Formatting

Maintaining clean and organized code is crucial for any project, including your blog. To achieve this, I recommend using tools like "prettier" and "eslint" to format and lint your code. Prettier can help ensure consistent formatting across your codebase, while eslint can help catch syntax errors and other issues before they become problematic.

In the following sections, I'll walk you through how to set up these tools for our blog.

Prettier code formatter

Prettier is a code formatter that helps ensure consistent code style and formatting across your entire codebase. It can automatically format code in various programming languages, including JavaScript, HTML, CSS, and more.

Install Prettier dependencies

First, we'll want to install a few dependencies:

npm install -D prettier prettier-plugin-tailwindcss

The prettier-plugin-tailwindcss module will help keep our tailwind classes organized!

Configure Prettier

Next, we need to configure Prettier.


Create a new file named .prettierrc.json in the root folder.

touch .prettierrc.json

Then add the following content to the file:

// .prettierrc.json
"singleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]

If you don't like using single quotes for your quote marks, you can omit the singleQuote setting


We want to ignore a few folders and files. So, create a file named .prettierignore in the root folder.

touch .prettierignore

Then add the following content to the file:

// .prettierignore

Update package.json

It's a good idea to have a script in your package.json file that will execute Prettier formatting on demand.

Open up your package.json file and add a "format" script;

// package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"typecheck": "tsc --noEmit",
"format": "prettier --write ." // <-- Add this

Run Prettier!

Now it's time to run the formatter on the project for the first time. This should clean up the existing codebase.

npm run format

Eslint code linter

ESLint is a code linter that helps identify and report code syntax and style issues. It can catch common errors and enforce coding standards across your entire codebase, helping to ensure that your code is clean and maintainable.

Install Eslint dependencies

We'll need a few dependencies to get eslint working how we want it to for this blog project.

Install the following dependencies:

npm install -D eslint eslint-config-prettier eslint-config-react-app

Next, we must create the main configuration file for Eslint in our project root folder.

touch .eslintrc.js

Then add the following content to that file:

// .eslintrc.js
module.exports = {
globals: {
__PATH_PREFIX__: true,
extends: ['react-app', 'prettier'],

There are some files and folders we want Eslint to ignore, so let's set that up.

Create the ignore file in the project root folder:

touch .eslintignore

And then add the following content to that file:


Update package.json

As with Prettier, having a script in the package.json file is good practice that automates running Eslint for your project.

Open the package.json file back up and add the "lint" and "lint:fix" scripts:

// package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"typecheck": "tsc --noEmit",
"format": "prettier --write .",
"lint": "eslint . --ext ts,tsx,js,jsx", // <-- Add this
"lint:fix": "eslint . --ext ts,tsx,js,jsx --fix" // <-- Add this

The --fix flag will tell Eslint automatically fix any errors it sees if it can.

Add Fonts

Adding fonts to GatsbyJS is reasonably straightforward. In the past, I used some Gatsby plugins to pull assets from Google Fonts directly, but those plugins appear to have become stale and languish without updates. No matter! I found a better way.

Install @fontsource

The '@fontsource' module is an npm module that allows you to easily install and use open-source fonts in your project. It provides a simple way to add custom fonts to your website without needing a third-party provider.

For this blog, we'll use the "Roboto" font. However, feel free to use any other font you like from @fontsource; install the appropriate module and then update your gatsby-browser.ts file appropriately.

First, install the dependency:

npm install @fontsource/roboto

Then we have to create the gatsby-browser.ts file and add the fonts we want to use.

The gatsby-browser.ts provides an entry point to your various pages. It wraps your page components with a global set of imports and API methods. We'll only be taking advantage of it to load global CSS files. But there's a lot it can do.

touch gatsby-browser.ts

Add the following content to the file:

// gatsby-browser.ts
import '@fontsource/roboto/100-italic.css';
import '@fontsource/roboto/100.css';
import '@fontsource/roboto/300-italic.css';
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400-italic.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500-italic.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700-italic.css';
import '@fontsource/roboto/700.css';
import '@fontsource/roboto/900-italic.css';
import '@fontsource/roboto/900.css';

Add Styling

Styling and style systems are essential for any website project. I tend to prefer using tailwindcss for my projects, and I don't think that's a particularly controversial choice, but you can choose whatever style system you like. If you prefer something else, feel free to go off the script!

Tailwind CSS is a utility-first CSS framework that provides a set of pre-designed classes to help streamline the process of styling a website. It aims to simplify the development process by reducing the need for custom CSS and offering a consistent design system that can be easily customized.

I love it.

Install tailwindcss dependencies

The first thing we need to do is install tailwindcss and some associated dependencies.

npm install -D tailwindcss autoprefixer postcss gatsby-plugin-postcss
npm install twin.macro tailwind-merge

The twin.macro utility helps us integrate the Emotion plugin (which we opted to use when creating the project) with tailwindcss. The tailwind-merge plugin is a super helpful utility that lets us merge tailwind classes intelligently and avoids class name collisions; you'll see how we use them later.

Configure Tailwind

Next, we are going to initialize the tailwind configuration:

npx tailwindcss init -p

This will create a tailwind.config.js file and a postcss.config.js file in the project root.

Edit the configuration file

We want to edit that newly created configuration file and set it up to work with Gatsby.

/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
theme: {
extend: {
fontFamily: {
sans: ['Roboto', 'sans-serif'],
plugins: [],

This setup tells Tailwind where to find our source code and sets our application's default "sans" font to the "Roboto" font we added to our gatsby-browser.ts file above.

Create a global CSS file

We will create a global CSS file and import the Tailwind directives.

mkdir src/styles
touch src/styles/global.css

Add the following content to the global.css file:

@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind screens;

Update gatsby-browser.ts

We need to add the global CSS file to gatsby-browser.ts so every page can use the beautiful tailwind styles we love.

// gatsby-browser.ts
// ... (other styles)
import './src/styles/global.css';

Restart the development server

For any of this to take effect, we should restart the development server.

First, kill any existing gatsby develop processes

gatsby develop

You won't notice much difference at this point because the default pages are all styled with CSS in JS by default. But, if you want, you can tinker with the pages/index.tsx page and add some tailwind classes. For example, something like this might be a good test:

We'll be doing something different with this file in the next part of this article, so avoid getting too attached to this basic look.

import type { HeadFC, PageProps } from 'gatsby';
import * as React from 'react';
const IndexPage: React.FC<PageProps> = () => {
return (
<main className="font-sans font-light">
<div className="container mx-auto px-4 lg:px-0">
<h1 className="my-8 text-4xl font-bold lg:text-5xl">My Gatsby Blog</h1>
<span className="text-lg">This is my Gatsby Blog home page!</span>
export default IndexPage;
export const Head: HeadFC = () => <title>Home Page</title>;


This post covered the fundamental steps of setting up a GatsbyJS project. We walked through the process of creating the project, setting up code formatting and linting with "prettier" and "eslint," adding open source fonts using the "@fontsource" module, and configuring Tailwind CSS to simplify the styling process. With these tools in place, we've laid a solid foundation for building our blog.

Stay tuned for the next post in this series, Building a GatsbyJS Blog: Layout and Pages where we'll dive into creating the layout and structure of our blog pages.

And, here is the source code for this post: MachineServant GitHub: Build a Gatsby Blog (part 1)

Building a Gatsby Blog Series

Read Next
Revest-les-Roches, Provence-Alpes-Côte d'Azur, France
Evan Stern
Evan Stern
February 08, 2023

Web application development is a rapidly growing field that offers endless possibilities for creativity and innovation. From online shopping and banking to…

Evan Stern
Evan Stern
February 18, 2023

Welcome back to "Building a GatsbyJS Blog"! In this second part of the series, we'll focus on creating the Layout and pages for our blog. We'll start by…