Disabling Source Maps in Gatsby for Production

During a production build, Gatsby does an excellent job of minifying and bundling JavaScript and CSS assets, a key step in their 'blazing fast' claim. One thing that is also enabled by default, even during production builds, is source maps. Source maps are an incredibly useful tool that maps the combined and minified files back to their unbuilt state, making debugging these transformed files much easier. What this also does is leave the structure and contents of your source code open for all to see on your live site, via Developer Tools.
Public source maps can make the original source easier to read, which may be unwanted on a closed‑source project. Removing them does not make the delivered JavaScript private: the browser still receives executable code that a visitor can inspect.
The performance distinction is between external and inline maps. Separate .map files are ordinarily requested by debugging tools, rather than as part of a normal page visit. Inline maps are embedded in the delivered asset and increase its size. Removing external maps is therefore not automatically a page‑load performance improvement.
Fortunately, with a little webpack configuration, it is very straightforward to disable the generation of these source maps during a production build, whilst maintaining them during development.
Customising webpack in Gatsby
The generation of source maps is controlled through the webpack configuration, which lives in gatsby-node.js. Essentially, we want to disable the devtool option during Gatsby's build, but only when we are building for production.
Using Gatsby's onCreateWebpackConfig exposes a number of available configurations that we can use. To remove source maps, there are two different parameters we can query to identify that a production build is occurring:
Stage
Stage returns the current stage of the build from one of develop, develop-html, build-javascript, or build-html. The first two are used during development builds, whilst the last two are production builds. Specifically, our source maps are generated during build-javascript.
Inside of the gatsby-node.js file we can therefore hook into this to turn devtool off like this:
module.exports.onCreateWebpackConfig = ({ actions, stage }) => {
if (stage === 'build-javascript') {
actions.setWebpackConfig({
devtool: false,
});
}
};getConfig()
getConfig() returns the current webpack config. Specifically for us, mode within this will be 'production' if we are undertaking a production build.
Much like the previous solution, we can then query this in gatsby-node.js to turn devtool off:
module.exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
if (getConfig().mode === 'production') {
actions.setWebpackConfig({
devtool: false,
});
}
};Either solution will yield the same results, the only consideration will be whether you are already configuring webpack for another reason, in which case you may well already be using getConfig().

A Note About Cached Files
Do bear in mind that with either of these solutions, if you have already run a build before modifying your webpack configuration, then your public folder may well already contain source maps from those previous builds. You can clear this cache by simply running gatsby clean. This is something I've added to my deploy script within package.json as a way to ensure my latest builds are up‑to‑date.
Postscript
June 2026: This Gatsby configuration remains useful as legacy build advice. In a current review, I would check how maps are delivered and how the team uses them for error reporting. External .map files are normally loaded by debugging tools; inline maps add to the transferred asset. Measure that difference before claiming a performance gain, and remember that removing maps does not hide the JavaScript sent to the browser.