How to Configure gatsby-source-filesystem and How It Differs From Other Gatsby Source Plugins

gatsby-source-filesystem is the core source plugin that converts local files into Gatsby File nodes using a Chokidar-based file watcher, while other source plugins fetch data from remote APIs and create specialized node types like ContentfulAsset or WordPressPost.

The gatsby-source-filesystem plugin serves as the bridge between your local disk and Gatsby's GraphQL data layer. As part of the gatsbyjs/gatsby monorepo, this plugin implements the standard source plugin contract through the sourceNodes API in packages/gatsby-source-filesystem/src/gatsby-node.js, specializing in file system operations rather than remote data fetching.

What Is gatsby-source-filesystem?

gatsby-source-filesystem creates generic File nodes from any file type on your local disk. Each node includes fields such as relativePath, extension, size, and modifiedTime, plus a crucial sourceInstanceName field that identifies which plugin instance created the node.

This plugin uses an XState state machine combined with Chokidar to watch for file changes, enabling incremental builds that only update modified nodes. The core node creation logic resides in packages/gatsby-source-filesystem/src/create-file-node.js.

Key Differences Between gatsby-source-filesystem and Other Source Plugins

While all source plugins implement the sourceNodes API, they differ significantly in data origin, node types, and configuration patterns.

Data Origin and Node Types

gatsby-source-filesystem sources data from your local filesystem, creating generic File nodes that any transformer plugin can consume. In contrast, remote source plugins like gatsby-source-contentful or gatsby-source-wordpress fetch data from external APIs, creating plugin-specific node types such as ContentfulAsset or WordPressPost.

Configuration and Multiple Instances

gatsby-source-filesystem supports multiple plugin instances in gatsby-config.js, each requiring a unique name option that becomes the sourceInstanceName. This enables granular sourcing from separate directories:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images/`,
      },
    },
  ],
}

Remote source plugins typically support only a single instance per service unless they explicitly implement typePrefix or spaceId distinctions.

File Watching and Incremental Builds

gatsby-source-filesystem provides built-in file watching via Chokidar and an XState state machine that tracks file additions, changes, and deletions. This enables true incremental builds where only changed files trigger node updates.

Remote source plugins rely on polling intervals or webhook-based cache invalidation, requiring network requests to detect changes rather than watching local files.

Performance Optimization

gatsby-source-filesystem offers performance-specific options like fastHash (to skip MD5 hashing on large files) and ignore globs (to exclude unwanted paths). These optimizations address filesystem-specific concerns like hashing overhead and directory traversal.

Remote source plugins optimize through pagination settings (pageLimit) and cache TTLs, but do not deal with local file hashing.

How to Configure gatsby-source-filesystem

Basic Single Source Configuration

The minimal configuration requires name and path options:

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
  ],
}

The name option becomes the sourceInstanceName field, enabling GraphQL filtering by source.

Multiple Source Instances

Declare separate instances to organize different content types:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images/`,
        ignore: [`**/*.svg`],
        fastHash: true,
      },
    },
  ],
}

Query specific instances using the sourceInstanceName filter:

{
  allFile(filter: { sourceInstanceName: { eq: "content" } }) {
    nodes {
      relativePath
      extension
      birthTime
    }
  }
}

Advanced Configuration Options

Ignore Patterns

Use the ignore option with glob patterns to exclude files from processing:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/images/`,
    ignore: [`**/*.svg`, `**/thumbnails/**`],
  },
}

Fast Hashing

Enable fastHash to skip MD5 hashing of file contents, improving startup performance:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `media`,
    path: `${__dirname}/src/media/`,
    fastHash: true,
  },
}

Creating URL Slugs With createFilePath

The createFilePath helper from packages/gatsby-source-filesystem/src/create-file-path.js generates URL-friendly paths from file system locations:

// gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`);

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `src/content` });
    createNodeField({
      node,
      name: `slug`,
      value: `/blog${slug}`,
    });
  }
};

This utility automatically handles index files and directory structures, converting src/content/my-post/index.md to /my-post/.

Comparing With Remote Source Plugins

While gatsby-source-filesystem handles local assets, remote plugins like gatsby-source-contentful fetch external data:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `assets`,
        path: `${__dirname}/static/`,
      },
    },
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
        downloadLocal: true,
      },
    },
  ],
}

The downloadLocal: true option in Contentful mirrors gatsby-source-filesystem behavior by storing remote assets locally, creating File nodes that work with gatsby-plugin-image.

Summary

  • gatsby-source-filesystem creates generic File nodes from local disk paths, while remote plugins create specific node types like ContentfulAsset or WordPressPost.
  • Configure multiple plugin instances using unique name options to enable sourceInstanceName filtering in GraphQL.
  • Leverage built-in file watching via Chokidar and XState for incremental builds during development.
  • Optimize performance with fastHash to skip MD5 hashing and ignore globs to exclude unnecessary files.
  • Use the createFilePath helper from packages/gatsby-source-filesystem/src/create-file-path.js to generate URL slugs from file paths.

Frequently Asked Questions

What is the difference between gatsby-source-filesystem and gatsby-source-contentful?

gatsby-source-filesystem reads files from your local disk and creates generic File nodes with fields like relativePath and extension, utilizing a Chokidar file watcher for incremental updates. In contrast, gatsby-source-contentful fetches data from the Contentful API, creates specific node types such as ContentfulAsset and ContentfulEntry, and relies on webhooks or polling for cache invalidation rather than file watching.

How do I query only files from a specific gatsby-source-filesystem instance?

Use the sourceInstanceName field in your GraphQL query, which corresponds to the name option you configured in gatsby-config.js. For example, if you set name: 'content', filter with allFile(filter: { sourceInstanceName: { eq: "content" } }) to retrieve only files from that specific directory.

What does the fastHash option do in gatsby-source-filesystem?

The fastHash option skips MD5 hashing of file contents during node creation, significantly improving startup performance when working with large media files. When enabled, the plugin relies on file metadata like modification time rather than content hashing to detect changes, which is faster but slightly less robust for detecting content changes when timestamps remain identical.

Can I use gatsby-source-filesystem alongside remote source plugins?

Yes, you can combine gatsby-source-filesystem with remote plugins like gatsby-source-contentful or gatsby-source-wordpress in the same project. This hybrid approach allows you to manage static assets locally while pulling structured content from headless CMSs, and some remote plugins even offer downloadLocal options to mirror remote assets as local File nodes compatible with the filesystem plugin's ecosystem.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →