Jesse A. Green / notebook

Gatsby Administrator & Developer Guide

Generated May 2026 from gatsbyjs/gatsby at 47bd906

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Gatsby is a React-based static site generator organized as a monorepo of ~90 packages. At build time, it sources data from arbitrary inputs (filesystems, CMSs, APIs), unifies them into a GraphQL schema, runs user-defined queries, and renders static HTML with embedded React for client-side hydration. The result is a public/ directory of static assets ready for CDN deployment.

High-Level Architecture

┌──────────────────────────────────────────────────────────────┐
│                       gatsby-cli                             │
│  CLI entry point: develop / build / serve / clean / info     │
└──────────────┬───────────────────────────────────────────────┘
               │
┌──────────────▼───────────────────────────────────────────────┐
│                    gatsby (core)                              │
│                                                              │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────────┐ │
│  │ Bootstrap    │  │ Data Layer   │  │ Build Pipeline      │ │
│  │ (initialize, │  │ (sourceNodes,│  │ (createPages,       │ │
│  │  load        │  │  schema,     │  │  extract queries,   │ │
│  │  plugins)    │  │  GraphQL)    │  │  run queries,       │ │
│  └──────┬──────┘  └──────┬───────┘  │  build HTML,        │ │
│         │                │          │  webpack bundle)     │ │
│         │                │          └──────────┬──────────┘ │
│  ┌──────▼────────────────▼─────────────────────▼──────────┐ │
│  │              State Machine (xstate)                     │ │
│  │  Services: buildSchema, createPages, extractQueries,    │ │
│  │  runQueries, buildHTML, graphQLTypegen                   │ │
│  └─────────────────────────────────────────────────────────┘ │
│                                                              │
│  ┌───────────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │ Redux Store       │  │ LMDB Cache   │  │ Worker Pool  │  │
│  │ (pages, nodes,    │  │ (persistent  │  │ (parallel    │  │
│  │  schema, config)  │  │  datastore)  │  │  processing) │  │
│  └───────────────────┘  └──────────────┘  └──────────────┘  │
└──────────────────────────────────────────────────────────────┘
               │
┌──────────────▼───────────────────────────────────────────────┐
│                     Plugin Ecosystem                          │
│  Source: filesystem, WordPress, Contentful, Drupal, Shopify  │
│  Transform: remark, sharp, MDX, JSON, YAML, CSV, XML        │
│  General: image, offline, manifest, sitemap, TypeScript      │
└──────────────────────────────────────────────────────────────┘
               │
┌──────────────▼───────────────────────────────────────────────┐
│                     Output: public/                           │
│  Static HTML, JS bundles, CSS, optimized images, page-data   │
└──────────────────────────────────────────────────────────────┘

Component Inventory

Component Path Role
gatsby-cli packages/gatsby-cli/ CLI entry point, Ink-based reporter, command routing
gatsby (core) packages/gatsby/ Bootstrap, data layer, build pipeline, Redux store, webpack config
create-gatsby packages/create-gatsby/ Interactive project scaffolding wizard
gatsby-plugin-sharp packages/gatsby-plugin-sharp/ Image processing via libvips/sharp
gatsby-plugin-image packages/gatsby-plugin-image/ <StaticImage> and <GatsbyImage> components
gatsby-transformer-sharp packages/gatsby-transformer-sharp/ Creates ImageSharp nodes from image files
gatsby-source-filesystem packages/gatsby-source-filesystem/ Source files from local filesystem
gatsby-source-wordpress packages/gatsby-source-wordpress/ Source WordPress content via WPGraphQL
gatsby-transformer-remark packages/gatsby-transformer-remark/ Markdown to HTML/AST transformation
gatsby-plugin-mdx packages/gatsby-plugin-mdx/ MDX support (Markdown + JSX)
gatsby-link packages/gatsby-link/ <Link> component with prefetching
gatsby-core-utils packages/gatsby-core-utils/ Shared utilities (hashing, CPU count, CI detection, file fetching)
gatsby-plugin-utils packages/gatsby-plugin-utils/ Plugin author utilities, remote file polyfill
gatsby-page-utils packages/gatsby-page-utils/ File-system route API, page path utilities
gatsby-worker packages/gatsby-worker/ Worker pool for parallel build tasks
gatsby-graphiql-explorer packages/gatsby-graphiql-explorer/ Customized GraphiQL IDE
gatsby-plugin-page-creator packages/gatsby-plugin-page-creator/ Automatic page creation from src/pages/
gatsby-plugin-offline packages/gatsby-plugin-offline/ Service worker for offline support
babel-preset-gatsby packages/babel-preset-gatsby/ Default Babel preset for Gatsby projects
babel-preset-gatsby-package packages/babel-preset-gatsby-package/ Babel preset for Gatsby packages (monorepo)
babel-plugin-remove-graphql-queries packages/babel-plugin-remove-graphql-queries/ Strips GraphQL queries from production bundles
gatsby-react-router-scroll packages/gatsby-react-router-scroll/ Scroll position management
gatsby-adapter-netlify packages/gatsby-adapter-netlify/ Netlify deployment adapter
gatsby-dev-cli packages/gatsby-dev-cli/ Local development CLI for Gatsby contributors

Technology Stack

Layer Technology
Language JavaScript / TypeScript
Runtime Node.js >=18, <26
UI Framework React 18
Build Tool Webpack 5
Data Layer GraphQL (custom schema builder, not Apollo)
State Management Redux (internal build state)
State Machine XState (build orchestration)
Persistent Cache LMDB (Lightning Memory-Mapped Database)
Image Processing Sharp (libvips)
CLI Yargs + Ink (React-based terminal UI)
Package Manager Yarn 1.22.19 (workspaces)
Monorepo Management Lerna 3.x
Testing Jest 29
Linting ESLint + Prettier
E2E Testing Cypress
Transpilation Babel 7

Build Lifecycle (Data Flow)

The Gatsby build process follows a deterministic state machine:

  1. Initialize — Load gatsby-config.js, resolve plugins, set up Redux store, initialize LMDB cache
  2. onPreInit — First plugin hook; runs immediately after plugin load
  3. onPreBootstrap — Run before bootstrap sequence
  4. Source Nodes (sourceNodes) — Plugins create data nodes in the Redux store
  5. onCreateNode — Transformer plugins react to new nodes (e.g., Markdown → HTML)
  6. Create Schema (createSchemaCustomization) — Plugins define custom GraphQL types
  7. Build Schema — Gatsby infers types from nodes and builds the GraphQL schema
  8. Create Resolvers (createResolvers) — Plugins add custom field resolvers
  9. Create Pages (createPages) — Plugins create pages from data
  10. Extract Queries — Babel plugin scans components for graphql tagged template literals
  11. Run Queries — Execute all page queries and static queries against the schema
  12. Build HTML — Render each page to static HTML via server-side rendering
  13. Bundle JavaScript — Webpack bundles client-side JavaScript
  14. onPostBuild — Final plugin hook after build completes

Note

In develop mode, steps 10-13 run incrementally. Gatsby uses query-on-demand to only execute queries for pages currently viewed in the browser, significantly reducing dev server startup time.

2. System Requirements

Requirement Minimum Recommended
Node.js 18.0.0 20.x LTS
npm 8.0.0 Latest
Yarn 1.17.3 1.22.x
RAM 2 GB 4+ GB (8+ GB for large sites)
Disk 1 GB free SSD recommended
OS macOS, Linux, Windows Any

Node.js Compatibility

The engines field in the root package.json enforces:

{
  "engines": {
    "yarn": "^1.17.3",
    "node": ">=18.0.0 <26",
    "npm": ">=8.0.0"
  }
}

Warning

Node.js 23 and 24 have a known buffer bounds issue on macOS (#39223). Use Node.js 18 or 20 for production builds.

3. Configuration Reference

Configuration Files

File Format Location Purpose
gatsby-config.js JS/TS Project root Site metadata, plugin list, path prefix, trailing slash
gatsby-node.js JS/TS Project root Node API hooks (createPages, sourceNodes, onCreateWebpackConfig)
gatsby-browser.js JS/TS Project root Browser API hooks (wrapRootElement, onRouteUpdate)
gatsby-ssr.js JS/TS Project root SSR API hooks (wrapRootElement, onRenderBody)
.env.development dotenv Project root Environment variables for gatsby develop
.env.production dotenv Project root Environment variables for gatsby build
.babelrc.js JS Project root Custom Babel configuration (extends babel-preset-gatsby)

gatsby-config.js Options

Option Type Default Description
siteMetadata object {} Arbitrary site-wide data queryable via site.siteMetadata in GraphQL
plugins array [] Plugin declarations: strings (name only) or {resolve, options} objects
pathPrefix string "" URL path prefix; used when site is served from a subdirectory
trailingSlash string "always" "always", "never", or "ignore"
graphqlTypegen boolean|object false Generate TypeScript types from GraphQL queries
jsxRuntime string "automatic" "automatic" (React 17+ new transform) or "classic"
jsxImportSource string "react" JSX import source for automatic runtime (e.g., "@emotion/react")
polyfill boolean true Include core-js polyfills in the client bundle
flags object {} Feature flags for experimental features
adapter function — Deployment adapter (e.g., gatsby-adapter-netlify)

Environment Variable Reference

The following environment variables are recognized by Gatsby core and official plugins. Variables prefixed with GATSBY_ are embedded in the client-side bundle.

Core Build Variables

Variable Default Description
NODE_ENV development Build mode
GATSBY_ACTIVE_ENV — Override env file selection (loads .env.{value})
GATSBY_CPU_COUNT auto CPU core count override. Accepts number or logical_cores/physical_cores
GATSBY_CONCURRENT_DOWNLOAD 200 Max concurrent remote file downloads
GATSBY_WEBPACK_PUBLICPATH — Override webpack output.publicPath
GATSBY_WEBPACK_LOGGING — Enable webpack logging
PREFIX_PATHS — Enable path prefix from CLI
REACT_PROFILE — Enable React profiling in production build
VERBOSE — Enable verbose build output
NO_COLOR — Disable colored CLI output
GATSBY_LOGGER — Logger selection

Experimental Feature Flags

Variable Description
GATSBY_EXPERIMENTAL_PARALLEL_SOURCING Run source plugins in parallel
GATSBY_EXPERIMENTAL_DEV_SSR Enable SSR in development mode
GATSBY_EXPERIMENTAL_FAST_DEV Enable fast dev optimizations
GATSBY_EXPERIMENTAL_DISABLE_SCHEMA_REBUILD Skip schema rebuild on refresh
GATSBY_EXPERIMENTAL_ENABLE_ADMIN Enable Gatsby Admin UI
GATSBY_EXPERIMENTAL_PRESERVE_FILE_DOWNLOAD_CACHE Keep file download cache across builds
GATSBY_EXPERIMENTAL_CLOUD_CLI Enable Gatsby Cloud CLI commands

Cache and Data Variables

Variable Description
GATSBY_DISABLE_CACHE_PERSISTENCE Disable persistent LMDB cache
PRESERVE_FILE_DOWNLOAD_CACHE Keep file download cache
GATSBY_DETECT_NODE_MUTATIONS Enable mutation detection for debugging
GATSBY_SKIP_WRITING_SCHEMA_TO_FILE Skip writing GraphQL schema to .cache

Development Server Variables

Variable Default Description
GATSBY_HOST localhost Dev server host
ENABLE_GATSBY_REFRESH_ENDPOINT — Enable /__refresh webhook endpoint
GATSBY_REFRESH_TOKEN — Auth token for the refresh endpoint
GATSBY_QUERY_ON_DEMAND true (dev) Run queries only when pages are visited
GATSBY_QUERY_ON_DEMAND_LOADING_INDICATOR — Show loading indicator for on-demand queries
GATSBY_SOCKET_IO_DEFAULT_TRANSPORT — Override Socket.IO transport

Important

ENABLE_GATSBY_REFRESH_ENDPOINT is required for CMS preview integrations (e.g., Drupal, Contentful). When set to true, a POST to /__refresh triggers a full data refresh in development.

Image Processing Variables

Variable Description
GATSBY_JPEG_ENCODER JPEG encoder override for gatsby-plugin-sharp
GATSBY_ENABLE_LAZY_IMAGES_IN_CI Enable lazy image processing in CI environments
ENABLE_GATSBY_EXTERNAL_JOBS Enable external job processing for images
IMAGE_CDN_ENCRYPTION_SECRET_KEY Encryption key for Image CDN URLs
IMAGE_CDN_ENCRYPTION_IV Initialization vector for Image CDN encryption
IMAGE_CDN_HOSTNAME Hostname for Image CDN URLs
IMAGE_CDN_ROUTE_PREFIX Route prefix for Image CDN
GATSBY_SCREENSHOT_PLACEHOLDER Placeholder for screenshot transformer

Plugin-Specific Variables

Variable Plugin Description
HTTPBASICAUTH_USERNAME gatsby-source-wordpress HTTP Basic Auth username
HTTPBASICAUTH_PASSWORD gatsby-source-wordpress HTTP Basic Auth password
GATSBY_CONTENTFUL_OFFLINE gatsby-source-contentful Enable offline mode for Contentful
NETLIFY_IMAGE_CDN gatsby-adapter-netlify Enable Netlify Image CDN
GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE gatsby-adapter-netlify Exclude LMDB datastore from function bundle

Benchmark and Internal Variables

Variable Description
BENCHMARK_REPORTING_URL URL for benchmark data reporting
BENCHMARK_REPORTING_SECRET Auth secret for benchmark reporting
CI_NAME CI provider name for benchmark identification
BLUEBIRD_DEBUG Enable Bluebird promise debugging
BLUEBIRD_LONG_STACK_TRACES Enable long stack traces for promises
GATSBY_OPEN_TRACING_CONFIG_FILE OpenTracing configuration file path
GATSBY_NODE_GLOBALS Enable experimental Node.js globals

CLI Flags Reference

gatsby develop

Flag Short Type Default Description
--host -H string localhost Dev server host
--port -p number 8000 Dev server port
--open -o boolean false Open browser on start
--https boolean false Use HTTPS with self-signed cert
--cert-file string — Custom SSL certificate file
--key-file string — Custom SSL key file
--ca-file string — Custom CA certificate file
--graphql-tracing boolean false Enable GraphQL tracing
--open-tracing-config-file string — OpenTracing config file
--inspect number 9229 Enable Node.js inspector
--inspect-brk number 9229 Enable inspector with break

gatsby build

Flag Short Type Default Description
--prefix-paths boolean false Build with pathPrefix from config
--no-uglify boolean false Skip JS minification
--profile boolean false Enable React profiling
--graphql-tracing boolean false Enable GraphQL tracing
--log-pages boolean false Log generated pages
--write-to-file boolean false Write page data to files
--functions-platform string — Target platform for serverless functions
--functions-arch string — Target architecture for serverless functions

gatsby serve

Flag Short Type Default Description
--host -H string localhost Server host
--port -p number 9000 Server port
--open -o boolean false Open browser on start
--prefix-paths boolean false Serve with path prefix

4. Deployment & Scaling

Build Output Structure

After gatsby build, the public/ directory contains:

public/
├── index.html                    # Homepage
├── 404.html                      # 404 page
├── page-data/
│   ├── index/page-data.json     # Page data for homepage
│   ├── 404.html/page-data.json  # Page data for 404
│   └── sq/d/                    # Static query results
├── static/                       # Static assets (copied from src/static/)
├── chunk-map.json               # Webpack chunk mapping
├── webpack.stats.json           # Webpack build statistics
└── [page-paths]/                # Static HTML for each page

Deployment Targets

Gatsby produces static files deployable to any static hosting platform:

Platform Adapter Notes
Netlify gatsby-adapter-netlify Native adapter support, Image CDN
Vercel — Auto-detected from framework
GitHub Pages — Use --prefix-paths with pathPrefix config
AWS S3 + CloudFront — Upload public/ to S3, configure CloudFront
Docker (nginx) — Serve public/ with nginx

Adapter System

Gatsby 5 introduced adapters for platform-specific optimizations:

// gatsby-config.js
const adapter = require("gatsby-adapter-netlify").default

module.exports = {
  adapter: adapter({
    excludeDatastoreFromEngineFunction: false,
  }),
}

The adapter hooks into the build pipeline to:

  • Configure server-side rendering routing
  • Optimize function bundling for the target platform
  • Set up CDN cache headers
  • Configure redirects and rewrites

Note

The GATSBY_CONTINUE_BUILD_ON_ADAPTER_MISMATCH env var allows builds to proceed when the detected deployment platform doesn't match the configured adapter.

Scaling Large Builds

For sites with thousands of pages:

  1. Increase Node.js heap:

    NODE_OPTIONS="--max-old-space-size=8192" gatsby build
    
  2. Maximize CPU utilization:

    GATSBY_CPU_COUNT=logical_cores gatsby build
    
  3. Enable parallel sourcing:

    GATSBY_EXPERIMENTAL_PARALLEL_SOURCING=true gatsby build
    
  4. Preserve download cache:

    GATSBY_EXPERIMENTAL_PRESERVE_FILE_DOWNLOAD_CACHE=true gatsby build
    

Tip

The gatsby-worker package provides a custom worker pool (not Node.js worker_threads directly) that serializes tasks via IPC. The WorkerPool class in packages/gatsby-worker/src/index.ts manages lifecycle, task queuing, and error propagation. Configuring GATSBY_CPU_COUNT directly controls pool size.

5. Operations

Cache Management

Gatsby uses multiple cache layers:

Cache Location Purpose Invalidation
LMDB datastore .cache/data/ Persistent node storage gatsby clean
Webpack cache .cache/webpack/ Module compilation cache gatsby clean
Query results .cache/ Compiled query results Automatic on data change
Image cache .cache/caches/gatsby-plugin-sharp/ Processed image variants gatsby clean
File download cache .cache/caches/gatsby-source-filesystem/ Downloaded remote files Configurable via env
# Full cache clear
gatsby clean

# Selective cache management
rm -rf .cache/webpack  # Clear only webpack cache

Tip

In CI environments, persist .cache/ and public/ between builds for incremental builds. This can reduce build times by 50-80% for sites that primarily add/update content.

Monitoring Build Performance

Enable verbose output to diagnose slow builds:

VERBOSE=true gatsby build

This reports per-lifecycle timing:

success open and validate gatsby-configs - 0.058s
success load plugins - 0.284s
success source and transform nodes - 12.345s  ← bottleneck
success building schema - 0.265s
success createPages - 1.234s
success run page queries - 45.678s  ← bottleneck
success Building production JavaScript and CSS bundles - 23.456s
success Building static HTML for pages - 8.901s

For distributed tracing, use OpenTracing:

GATSBY_OPEN_TRACING_CONFIG_FILE=./jaeger-config.js gatsby build

Note

The gatsby-plugin-benchmark-reporting package in the monorepo provides automated build performance reporting. It captures onPostBuild data and sends it to a configurable endpoint via BENCHMARK_REPORTING_URL.

Health and Diagnostics

The gatsby info command outputs environment diagnostics:

gatsby info --clipboard
System:
  OS: macOS 14.0
  CPU: (8) arm64 Apple M1
  Shell: /bin/zsh
Binaries:
  Node: 20.10.0
  npm: 10.2.3
  Yarn: 1.22.19
npmPackages:
  gatsby: ^5.13.0 => 5.13.3
  gatsby-plugin-image: ^3.13.0 => 3.13.1
  gatsby-plugin-sharp: ^5.13.0 => 5.13.1

6. Performance

Webpack Configuration

Gatsby's webpack configuration (packages/gatsby/src/utils/webpack.config.js) supports four stages:

Stage Purpose
develop Dev server with HMR
develop-html SSR during development
build-javascript Production JS bundles
build-html Static HTML rendering

Key webpack behaviors:

  • Code splitting — automatic chunk splitting per route
  • Asset hashing — content-based filenames for long-term caching
  • Polyfills — core-js included by default (disable with polyfill: false)
  • Public path — configurable via GATSBY_WEBPACK_PUBLICPATH or pathPrefix
// Custom webpack config via gatsby-node.js
exports.onCreateWebpackConfig = ({ stage, getConfig, rules, loaders, plugins, actions }) => {
  // Access current config
  const config = getConfig()

  // Modify via setWebpackConfig (merged with existing)
  actions.setWebpackConfig({
    resolve: {
      alias: {
        '@components': path.resolve(__dirname, 'src/components'),
      },
    },
  })

  // Or replace entire config (use with caution)
  actions.replaceWebpackConfig(config)
}

Image Processing Pipeline

gatsby-plugin-sharp wraps the Sharp library (libvips) for image transformations:

  • Formats: JPEG, PNG, WebP, AVIF, TIFF
  • Operations: resize, crop, rotate, duotone, blur, grayscale
  • Lazy processing: In development, images are processed on-demand when requested by the browser
  • Worker pool: Image operations run in parallel worker processes
  • Error handling: SharpError class wraps failures with file context

The image CDN subsystem (packages/gatsby-plugin-utils/src/polyfill-remote-file/) supports encrypted URL generation for CDN-optimized image delivery:

Variable Purpose
IMAGE_CDN_ENCRYPTION_SECRET_KEY AES encryption key for CDN URLs
IMAGE_CDN_ENCRYPTION_IV Initialization vector
IMAGE_CDN_HOSTNAME CDN hostname
IMAGE_CDN_ROUTE_PREFIX URL route prefix

Query-on-Demand

In development, Gatsby defers query execution until a page is viewed:

  • Only 404 pages, currently active browser tabs, and pending websocket requests run immediately
  • Static queries (sq-- prefix) and slice queries (slice-- prefix) always run
  • Controlled via GATSBY_QUERY_ON_DEMAND (default: true in develop)
  • GATSBY_ENABLE_QUERY_ON_DEMAND_IN_CI overrides for CI environments

7. Security

Client-Side Data Exposure

Caution

All GATSBY_* environment variables are embedded in the webpack bundle and visible in client-side JavaScript. Never use this prefix for secrets, API keys, or credentials.

  • .env.development and .env.production files should be in .gitignore
  • Server-only variables (without GATSBY_ prefix) are safe for secrets during build
  • GraphQL data is serialized to page-data.json files in public/ — any data queried is publicly accessible

Authentication Patterns

Gatsby supports client-side authentication via client-only routes:

// gatsby-node.js — mark routes as client-only
exports.onCreatePage = async ({ page, actions }) => {
  if (page.path.match(/^\/app/)) {
    page.matchPath = "/app/*"
    actions.createPage(page)
  }
}

The SSR build will render a shell for these routes; client-side React handles authentication checks.

Serverless Function Security

Functions in src/api/ receive standard Node.js req/res objects. Platform-specific middleware (e.g., Netlify Identity, Vercel auth) provides authentication for serverless endpoints.

Refresh Endpoint

When ENABLE_GATSBY_REFRESH_ENDPOINT=true:

  • The /__refresh endpoint accepts POST requests to trigger data refresh
  • GATSBY_REFRESH_TOKEN provides optional bearer token authentication
  • The initial webhook body can be passed via GATSBY_INITIAL_WEBHOOK_BODY

Warning

The refresh endpoint is intended for development and CMS preview integrations only. Do not expose it in production without authentication.

Supply Chain

The monorepo uses:

  • Yarn 1.22.19 with workspaces for deterministic resolution
  • lint-staged + husky for pre-commit checks
  • ESLint + Prettier for code quality enforcement
  • TypeScript strict mode for type safety in core packages

8. Developer Internals

Repository Structure

gatsbyjs/gatsby/
├── packages/                    # ~90 npm packages
│   ├── gatsby/                  # Core framework (5.8M chars)
│   │   ├── src/
│   │   │   ├── commands/        # CLI command implementations
│   │   │   ├── services/        # Build lifecycle services (21 files)
│   │   │   ├── utils/           # Core utilities (89 files, 350K chars)
│   │   │   ├── schema/          # GraphQL schema builder
│   │   │   ├── redux/           # Redux store, actions, reducers
│   │   │   ├── query/           # Query extraction, planning, execution
│   │   │   ├── datastore/       # LMDB-backed data storage
│   │   │   ├── state-machines/  # XState state machines
│   │   │   └── internal-plugins/ # Built-in plugins (dev-404, partytown)
│   │   └── cache-dir/           # Client-side runtime (loader, navigation)
│   ├── gatsby-cli/              # CLI entry point
│   ├── create-gatsby/           # Project scaffolding
│   ├── gatsby-plugin-sharp/     # Image processing (75K chars)
│   ├── gatsby-source-filesystem/ # File sourcing (23K chars)
│   ├── gatsby-source-wordpress/ # WordPress sourcing (50K chars)
│   ├── gatsby-transformer-remark/ # Markdown transformation (31K chars)
│   ├── gatsby-core-utils/       # Shared utilities (35K chars)
│   ├── gatsby-worker/           # Worker pool (22K chars)
│   └── [60+ more packages]
├── starters/                    # Starter templates
│   ├── blog/
│   ├── default/
│   ├── gatsby-starter-minimal-ts/
│   ├── gatsby-starter-plugin/
│   └── gatsby-starter-wordpress-blog/
├── examples/                    # Example projects (~50)
├── e2e-tests/                   # Cypress E2E test suites
├── integration-tests/           # Integration test suites
├── benchmarks/                  # Performance benchmarks
├── deprecated-packages/         # Deprecated packages (recipes, telemetry, admin)
├── scripts/                     # Monorepo tooling (changelog, publish)
└── peril/                       # GitHub bot (Danger.js)

State Machine Architecture

Gatsby uses XState to orchestrate the build pipeline. The state machines in packages/gatsby/src/state-machines/ define:

  • Data Layer Machine — Sources nodes, builds schema, creates pages
  • Query Running Machine — Extracts queries, calculates dirty queries, executes them
  • Waiting Machine — Handles the develop-mode idle loop (listens for file changes, webhooks)

Services (in packages/gatsby/src/services/) are invoked by the state machines:

Service File Purpose
buildSchema build-schema.ts Build GraphQL schema from nodes
calculateDirtyQueries calculate-dirty-queries.ts Identify queries needing re-execution
createPages create-pages.ts Execute createPages API, track page changes
customizeSchema customize-schema.ts Execute createSchemaCustomization API
extractQueries extract-queries.ts Scan JS/TS files for GraphQL queries
graphQLTypegen graphql-typegen.ts Generate TypeScript types from schema
initialize initialize.ts Bootstrap: load plugins, initialize cache, setup config
rebuildSchemaWithSitePage rebuild-schema-with-site-page.ts Add SitePage type after page creation
recompile recompile.ts Webpack recompilation on file changes
runQueries run-queries.ts Execute page and static queries
startWebpackServer start-webpack-server.ts Launch webpack dev server
writeOutRedirects write-out-redirects.ts Write redirect configuration

Redux Store Shape

The internal Redux store (in packages/gatsby/src/redux/) tracks:

  • pages — Map of all pages (path → page object)
  • nodes — All data nodes (internal, backed by LMDB)
  • schema — GraphQL schema object
  • config — Resolved gatsby-config.js
  • components — Map of page component paths
  • staticQueryComponents — Static query definitions
  • status — Build status flags
  • queries — Query tracking and dirty state
  • slices — Gatsby Slice components

Node API Reference

These hooks are exported from gatsby-node.js:

Hook Phase Purpose
onPreInit Bootstrap First hook, runs immediately after plugin load
onPluginInit Bootstrap Per-process initialization (v3.9+)
onPreBootstrap Bootstrap Before bootstrap sequence
onPostBootstrap Bootstrap After bootstrap complete
sourceNodes Data Create data nodes from sources
onCreateNode Data React to node creation (transform/extend)
shouldOnCreateNode Data Filter which nodes trigger onCreateNode (v5+)
createSchemaCustomization Schema Define custom GraphQL types
setFieldsOnGraphQLNodeType Schema Add fields to inferred types
createResolvers Schema Add custom field resolvers
createPages Pages Create pages from data
createPagesStatefully Pages Stateful page creation (for plugins managing own state)
onCreatePage Pages Modify page after creation
onCreateBabelConfig Build Extend Babel configuration
onCreateWebpackConfig Build Extend webpack configuration
preprocessSource Build Process compile-to-JS source
resolvableExtensions Build Add resolvable file extensions
onPreExtractQueries Queries Before query extraction
onPreBuild Build Before production build
onPostBuild Build After production build
onCreateDevServer Dev After dev server starts (Express app)
pluginOptionsSchema Config Define plugin options schema (Joi)

Browser API Reference

These hooks are exported from gatsby-browser.js:

Hook Purpose
onClientEntry Called when browser runtime starts
onInitialClientRender After initial React render
onPreRouteUpdate Before route change begins
onRouteUpdate After route change (including initial load)
onRouteUpdateDelayed When route change takes >1 second
shouldUpdateScroll Control scroll behavior on navigation
wrapPageElement Wrap each page (persists across navigations)
wrapRootElement Wrap root React element (context providers)
onPrefetchPathname When prefetching is triggered
onPostPrefetchPathname After prefetch completes
disableCorePrefetching Disable built-in prefetching
replaceHydrateFunction Custom ReactDOM.createRoot/render
registerServiceWorker Enable service worker registration
onServiceWorkerInstalled Service worker installed
onServiceWorkerUpdateFound Service worker update available
onServiceWorkerUpdateReady Service worker update ready to apply
onServiceWorkerActive Service worker activated
onServiceWorkerRedundant Service worker became redundant
onCaughtError React 19 caught error handler
onUncaughtError React 19 uncaught error handler

Node API Helpers

Every Node API hook receives a helpers object with:

Helper Type Description
actions Actions Functions to modify Gatsby state (createNode, createPage, etc.)
cache GatsbyCache Key-value cache (.get(), .set(), .del()) backed by LMDB
createNodeId function Generate stable, globally unique node IDs
createContentDigest function Create content hash for change detection
reporter GatsbyReporter Logging (.info(), .warn(), .error(), .panic(), .verbose(), .activityTimer())
getNodes function Get all nodes
getNode function Get node by ID
getNodesByType function Get nodes of a specific type
loadNodeContent function Get content from node's source plugin
store Redux.Store Internal Redux store (private API)
emitter Emitter Internal event emitter (private API)
tracing GatsbyTracing OpenTracing integration (.tracer, .parentSpan, .startSpan())
graphql function Run GraphQL queries (available in createPages)
getCache function Get cache for a specific plugin
pathPrefix string Resolved path prefix
basePath string Base path (without asset prefix)

Client-Side Runtime

The packages/gatsby/cache-dir/ directory contains the client-side runtime:

Module Purpose
loader.js Page data loader (BaseLoader, ProdLoader, DevLoader). Manages prefetching, caching, and loading of page-data.json and component chunks
navigation.js Client-side router integration, RouteAnnouncer for a11y, history management
production-app.js Production app entry point, hydration setup
root.js Development app entry point, React Fast Refresh integration
static-entry.js SSR entry point for gatsby build (HTML generation)
ssr-develop-static-entry.js SSR entry point for gatsby develop
ensure-resources.js <EnsureResources> component — blocks rendering until page data is loaded
query-result-store.js PageQueryStore, StaticQueryStore, SliceDataStore — manage query result state
slice.js Gatsby Slice component for shared layout sections
static-query.js useStaticQuery hook and <StaticQuery> component

Key Utility Modules

The packages/gatsby/src/utils/ directory (89 files, 350K chars) contains the core utility layer:

Module Purpose
api-runner-node.js Executes Node API hooks across all plugins with proper ordering
api-browser-docs.ts Browser API documentation and type exports
api-node-docs.ts Node API documentation and type exports
webpack.config.js Webpack configuration factory for all four build stages
babel-loader.ts Custom Babel loader with caching (BabelConfigItemsCacheInvalidatorPlugin)
gatsby-webpack-stats-extractor.ts Webpack plugin to extract build stats (GatsbyWebpackStatsExtractor)
gatsby-webpack-virtual-modules.ts Virtual module injection (GatsbyWebpackVirtualModules)
websocket-manager.ts WebSocket server for dev mode hot reload (WebsocketManager)
start-server.ts Express dev server setup (serves pages, handles refresh endpoint)
page-data.ts Page data JSON file management
page-mode.ts Determine page rendering mode (SSG/DSG/SSR)
node-manifest.ts Node manifest for CMS preview (limited by NODE_MANIFEST_FILE_LIMIT)
detect-port-in-use-and-prompt.ts Port conflict resolution
get-ssl-cert.ts Self-signed SSL cert generation for HTTPS dev
loading-indicator.ts Loading indicator for query-on-demand
feedback.ts User feedback prompt (disable with GATSBY_FEEDBACK_DISABLED)
cache-lmdb.ts LMDB cache implementation
detect-node-mutations.ts Debug tool for detecting illegal node mutations
adapter/ Adapter system (7 files) for deployment platform integration

Worker Pool Architecture

packages/gatsby-worker/ provides a custom worker pool:

  • WorkerPool class manages child processes via child_process.fork()
  • TaskQueue implements FIFO task scheduling with priority support
  • Workers are identified by GATSBY_WORKER_ID env var
  • In-flight task state can be dumped to disk via GATSBY_WORKER_IN_FLIGHT_DUMP_LOCATION
  • Error: "There is no worker with ..." indicates a worker process crashed

Plugin Architecture

Each Gatsby plugin is an npm package that can implement:

  1. gatsby-node.js — Node.js build-time hooks
  2. gatsby-browser.js — Client-side browser hooks
  3. gatsby-ssr.js — Server-side rendering hooks
  4. package.json — with "keywords": ["gatsby-plugin"]

Plugin options are validated via pluginOptionsSchema using Joi:

exports.pluginOptionsSchema = ({ Joi }) => {
  return Joi.object({
    path: Joi.string().required().description(`Path to source directory`),
    name: Joi.string().default(`default`).description(`Source instance name`),
    ignore: Joi.array().items(Joi.string()).description(`File patterns to ignore`),
  })
}

Theme System

Gatsby themes are plugins that can:

  • Define their own gatsby-config.js (merged with site config)
  • Provide pages, components, and data
  • Support component shadowing — the site can override any theme component by placing a file at src/{theme-package-name}/{original-path}

Theme resolution follows the webpack theme component shadowing system in packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/.

9. Integration Points

Source Plugin Contract

Source plugins implement sourceNodes to create nodes:

exports.sourceNodes = async ({ actions, createNodeId, createContentDigest }) => {
  const { createNode } = actions

  // Fetch data from external source
  const data = await fetchDataFromAPI()

  data.forEach(item => {
    createNode({
      ...item,
      id: createNodeId(`my-source-${item.id}`),
      parent: null,
      children: [],
      internal: {
        type: `MySourceType`,
        contentDigest: createContentDigest(item),
      },
    })
  })
}

Transformer Plugin Contract

Transformer plugins implement onCreateNode to transform source nodes:

exports.onCreateNode = async ({ node, actions, loadNodeContent, createNodeId, createContentDigest }) => {
  if (node.internal.mediaType !== `text/markdown`) return

  const { createNode, createParentChildLink } = actions
  const content = await loadNodeContent(node)

  const markdownNode = {
    id: createNodeId(`${node.id} >>> MarkdownRemark`),
    children: [],
    parent: node.id,
    internal: {
      type: `MarkdownRemark`,
      content,
      contentDigest: createContentDigest(content),
    },
  }

  createNode(markdownNode)
  createParentChildLink({ parent: node, child: markdownNode })
}

gatsby-source-filesystem

Creates File nodes from local filesystem paths:

Function Purpose
createFileNode Create a File node from a local file path
createFileNodeFromBuffer Create a File node from an in-memory buffer
createRemoteFileNode Download and create a File node from a remote URL

gatsby-source-wordpress

Sources WordPress content via WPGraphQL:

  • Hooks: onPluginInit, createSchemaCustomization, sourceNodes, onCreatePage, onCreateDevServer
  • State management: Rematch (Redux-like) with async local storage
  • Browser hook: onRouteUpdate hydrates inline WordPress images
  • Auth: HTTP Basic Auth via HTTPBASICAUTH_USERNAME/HTTPBASICAUTH_PASSWORD
  • Preview: Integrates with GATSBY_IS_PREVIEW and ENABLE_GATSBY_REFRESH_ENDPOINT
  • Error handling: Validates GraphQL responses, detects empty strings, redirects, and connection failures

gatsby-transformer-remark

Transforms Markdown files to MarkdownRemark nodes:

  • Processor: Unified/remark with GFM and footnotes support
  • Output types: MarkdownRemark (HTML, excerpt, headings, table of contents, word count, time to read)
  • Caching: AST, HTML, headings, and TOC are cached by content digest
  • Sub-plugins: Supports remark sub-plugins via createSchemaCustomization
  • Heading extraction: Generates IDs and extracts {id, value, depth} tuples

Deprecated Packages

The following packages are in deprecated-packages/:

Package Status Replacement
gatsby-recipes Deprecated Manual setup / create-gatsby
gatsby-admin Deprecated None (experimental)
gatsby-telemetry Deprecated Removed from core
gatsby-plugin-gatsby-cloud Deprecated gatsby-adapter-netlify or platform-specific adapters
gatsby-plugin-remove-trailing-slashes Deprecated trailingSlash: "never" in gatsby-config
gatsby-plugin-guess-js Deprecated None
gatsby-image Deprecated gatsby-plugin-image
gatsby-plugin-create-client-paths Deprecated matchPath in onCreatePage
gatsby-transformer-javascript-static-exports Deprecated None

Testing Strategy

Type Framework Location
Unit tests Jest 29 packages/*/src/__tests__/
Integration tests Jest integration-tests/
E2E tests Cypress 12 e2e-tests/
Benchmarks Custom benchmarks/

Running tests:

# All tests
yarn jest

# Specific package
yarn jest packages/gatsby-plugin-sharp

# Integration tests
yarn test:integration

# Type checking
yarn typecheck

Contributing

The monorepo uses:

  • Yarn workspaces (packages/*) for dependency management
  • Lerna for versioning and publishing
  • ESLint with Google style base + custom rules (backtick quotes, camelCase, file naming)
  • Prettier for formatting
  • Husky for pre-commit hooks (lint-staged)
  • TypeScript for core packages (.ts/.tsx)

Development workflow:

# Bootstrap all packages
yarn bootstrap

# Watch for changes
yarn watch

# Run tests
yarn jest

# Lint
yarn lint

# Format
yarn format

The changelog is automatically generated by scripts/gatsby-changelog-generator/ during Lerna version bumps.

Error Classes

Error Class Module Description
SharpError gatsby-plugin-sharp/src/sharp-error.js Image processing failure
BuildHTMLError gatsby/src/commands/build-html.ts HTML rendering failure
StringInterpolationNotAllowedError babel-plugin-remove-graphql-queries Template literal in GraphQL tag
EmptyGraphQLTagError babel-plugin-remove-graphql-queries Empty graphql tag
GraphQLSyntaxError babel-plugin-remove-graphql-queries Invalid GraphQL syntax
ExportIsNotAsyncError babel-plugin-remove-graphql-queries Non-async config export
SlicePropsError gatsby/cache-dir/slice.js Invalid Slice component props
OperationError gatsby-source-shopify Shopify API operation failure
HttpError gatsby-source-shopify Shopify HTTP request failure