# What Are Gatsby Themes and How Do They Differ from Plugins?

> Explore Gatsby themes and understand their distinction from plugins. Learn how themes offer site skeletons and customization while plugins extend the build process.

- Repository: [Gatsby/gatsby](https://github.com/gatsbyjs/gatsby)
- Tags: deep-dive
- Published: 2026-03-06

---

**Gatsby themes are specialized npm packages that provide complete site skeletons—including pages, components, and configuration—that can be composed and customized through component shadowing, whereas standard Gatsby plugins extend the build pipeline without providing UI layers.**

Gatsby themes represent a powerful abstraction in the `gatsbyjs/gatsby` ecosystem that allows developers to package and reuse entire website architectures. Unlike traditional plugins that modify the build process, themes deliver **composable site layers** that include pre-built pages, React components, static assets, and default configurations.

## What Defines a Gatsby Theme?

A Gatsby theme is technically a **Gatsby plugin** whose package name starts with `gatsby-theme-`. When added to the `plugins` array in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js), Gatsby treats it as a first-class site layer rather than a simple build extension.

Themes reside in the npm registry and can be installed like any other dependency:

```bash
yarn add gatsby-theme-blog

```

Once installed, the theme merges its own [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js), [`gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-node.js), and source files into your site during the bootstrap phase, as handled by [`packages/gatsby/src/bootstrap/load-themes/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/bootstrap/load-themes/index.js).

## How Gatsby Themes Differ from Plugins

While themes are plugins under the hood, they serve fundamentally different purposes in the Gatsby architecture:

| Aspect | Theme | Plugin |
|--------|-------|--------|
| **Purpose** | Full site skeleton (layout, pages, UI) | Extend build pipeline, transform data |
| **Naming convention** | `gatsby-theme-*` | Any name (often `gatsby-plugin-*`) |
| **Provides pages** | Yes – ships `src/pages/` | No – pages added by site or other plugins |
| **Component shadowing** | Supported via internal webpack plugin | Not applicable |
| **Default config** | Merges [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) into site | Exports Node APIs only |
| **Typical use case** | Blog, documentation, ecommerce starter | Source CMS data, image processing, analytics |

**Plugins describe "what the site can do," while themes describe "what the site looks like."**

## Core Capabilities of Gatsby Themes

### Composable Site Layers

Themes stack vertically. You can combine multiple themes in a single [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js):

```javascript
module.exports = {
  plugins: [
    `gatsby-theme-blog`,
    `gatsby-theme-notes`,
    {
      resolve: `gatsby-theme-ecommerce`,
      options: { currency: 'USD' }
    }
  ],
}

```

Each theme adds its pages, components, and configuration on top of the previous layer, as documented in [`docs/tutorial/using-multiple-themes-together.md`](https://github.com/gatsbyjs/gatsby/blob/main/docs/tutorial/using-multiple-themes-together.md).

### Component Shadowing

Component shadowing allows you to override any React component provided by a theme. Create a file in your site at `src/{theme-name}/components/{ComponentName}.js` to shadow the original.

The shadowing mechanism is implemented in [`packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js), which modifies the webpack resolution order to prioritize local shadow files over theme defaults.

### Default Configuration

Themes can export their own [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) that Gatsby merges with the site's configuration before the build starts. This allows themes to:

- Set default plugin options
- Configure `gatsby-source-filesystem` for theme-specific content directories
- Define site metadata and navigation structures

### Static Assets and Pages

Unlike regular plugins, themes can ship complete pages in `src/pages/` and static files in `static/`. These become part of the final site without requiring the consumer to write any code.

## Installing and Configuring a Gatsby Theme

Add a theme to your project and configure it with options:

```bash
yarn add gatsby-theme-blog

```

```javascript
// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-theme-blog`,
      options: {
        basePath: `/blog`,
        contentPath: `content/posts`,
        assetPath: `content/assets`,
      },
    },
  ],
}

```

The theme's [`gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-node.js) will create pages from your content, while its React components render the layout.

## Component Shadowing in Practice

Override a theme's Bio component by creating a shadow file:

```jsx
// src/gatsby-theme-blog/components/bio.js
import React from "react"
import { StaticImage } from "gatsby-plugin-image"

export default function Bio() {
  return (
    <div className="bio-container">
      <StaticImage 
        src="../images/custom-avatar.jpg" 
        alt="Site author" 
        width={100}
        height={100}
      />
      <p>Custom author bio written by the site developer.</p>
    </div>
  )
}

```

Gatsby's webpack configuration resolves this local file instead of the theme's original component, as handled by the internal shadowing plugin.

## Key Files in the Gatsby Codebase

Understanding the theme system requires familiarity with these core files:

| File | Purpose |
|------|---------|
| [`packages/gatsby/src/bootstrap/load-themes/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/bootstrap/load-themes/index.js) | Core logic for discovering `gatsby-theme-*` packages, resolving their configurations, and building the theme stack during bootstrap. |
| [`packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js) | Implements component shadowing by modifying webpack's module resolution to prioritize local shadow files over theme components. |
| [`docs/tutorial/what-are-gatsby-themes.md`](https://github.com/gatsbyjs/gatsby/blob/main/docs/tutorial/what-are-gatsby-themes.md) | Official documentation explaining theme concepts, installation, and basic usage patterns. |
| [`docs/tutorial/using-multiple-themes-together.md`](https://github.com/gatsbyjs/gatsby/blob/main/docs/tutorial/using-multiple-themes-together.md) | Guide for composing multiple themes in a single site, demonstrating vertical stacking capabilities. |

## Summary

- **Gatsby themes** are specialized npm packages (prefixed with `gatsby-theme-`) that provide complete site skeletons including pages, components, and configuration.
- Themes function as **composable site layers** that stack vertically, allowing multiple themes to coexist in a single project.
- **Component shadowing** enables developers to override any theme component by creating a file at `src/{theme-name}/components/{ComponentName}.js`, resolved via the internal webpack shadowing plugin.
- Unlike regular plugins that extend the build pipeline, themes provide **UI defaults and content structures** that define "what the site looks like" rather than "what the site can do."
- The theme system is orchestrated during bootstrap by [`packages/gatsby/src/bootstrap/load-themes/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/bootstrap/load-themes/index.js) and supports advanced customization through webpack module resolution modifications.

## Frequently Asked Questions

### Can a Gatsby theme include other plugins?

Yes, themes can declare dependencies on other Gatsby plugins in their [`package.json`](https://github.com/gatsbyjs/gatsby/blob/main/package.json) and configure them in their own [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js). When a site uses the theme, it automatically inherits these plugin configurations without needing to install them separately. This allows themes to provide complete functionality—including image processing, CMS sourcing, and analytics—out of the box.

### How does component shadowing work technically?

Component shadowing is implemented in [`packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/internal-plugins/webpack-theme-component-shadowing/index.js). This internal plugin modifies webpack's module resolution algorithm to check for files in the site's `src/{theme-name}/` directory before resolving imports from the theme's original source. If a matching file exists, webpack uses the local shadow version instead, allowing seamless component overrides without modifying the theme's node_modules.

### Can I use multiple themes in one Gatsby site?

Yes, Gatsby supports composing multiple themes by adding them to the `plugins` array in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js). Themes stack vertically, meaning each theme adds its pages, components, and configuration on top of the previous ones. As documented in [`docs/tutorial/using-multiple-themes-together.md`](https://github.com/gatsbyjs/gatsby/blob/main/docs/tutorial/using-multiple-themes-together.md), you can combine specialized themes—such as `gatsby-theme-blog` for blogging and `gatsby-theme-notes` for documentation—within a single unified site.

### What is the difference between a theme and a starter?

A **starter** is a complete Gatsby site template that you copy once to begin a new project, after which it becomes independent code that you maintain yourself. A **theme** is an npm package dependency that remains external to your site; you import its functionality while maintaining the ability to update it independently and override specific components via shadowing. Themes provide reusable, maintainable architecture, while starters provide one-time scaffolding.