Understanding sideEffects: false in package.json
The "sideEffects": false property in
package.json is a configuration flag that tells modern
JavaScript bundlers, such as Webpack, Rollup, and Vite, that a package
contains no code that modifies external state upon import. By declaring
this flag, you allow the bundler’s tree-shaking engine to safely remove
unused imports entirely from the final production bundle. This article
explains what side effects are in JavaScript, how the flag enables
aggressive tree shaking, how to configure it correctly, and how it
drastically reduces bundle sizes.
What is a Side Effect in JavaScript?
A “side effect” occurs when an imported module executes code that affects the global scope or modifies behavior outside of its own exported functions. Even if an application never directly calls an export from that module, running the module itself changes the environment.
Common examples of side effects include: * Modifying global objects
(e.g., window.myCustomProperty = true) * Attaching event
listeners to window or document * Importing
CSS or SCSS stylesheets (e.g., import './styles.css') *
Executing polyfills (e.g., import 'core-js') * Executing
top-level logic or self-invoking functions immediately upon import
Why Bundlers Need the
sideEffects Flag
JavaScript bundlers perform “tree shaking” (dead code elimination) to discard unused exports. However, static analysis tools cannot always determine if evaluating an unused module will trigger necessary side effects.
Without the sideEffects flag: 1. You import a utility:
import { formatDate } from 'large-utility-library'; 2. The
library has 50 other utility files that are not imported. 3. The bundler
must inspect every file to ensure none of them execute global code upon
being loaded. If it cannot guarantee safety, it bundles the unused code,
leading to bloated builds.
Setting "sideEffects": false explicitly guarantees to
the bundler: “If a file’s exports are not consumed, it is 100% safe
to drop the entire file and avoid compiling it.”
How to Configure
sideEffects
You can define sideEffects in your project’s
package.json using either a boolean value or an array of
file patterns.
1. Pure Libraries (No Side Effects)
If your library consists entirely of pure functions and components
with no global mutations or direct CSS imports, set the value to
false:
{
"name": "my-pure-library",
"version": "1.0.0",
"sideEffects": false
}2. Libraries with Specific Side Effects
If your project is mostly pure but includes certain files that must always run—such as CSS files or polyfills—provide an array of relative paths or glob patterns:
{
"name": "my-ui-library",
"version": "1.0.0",
"sideEffects": [
"*.css",
"*.scss",
"./src/polyfills.js",
"./src/global-init.js"
]
}In this scenario, any imported CSS files and the polyfill script will execute as intended, while all other unused JavaScript modules will be eliminated during the build process.
How
sideEffects: false Optimizes Build Sizes
- Eliminates Whole Modules, Not Just Statements:
Standard tree shaking removes unused functions inside an imported file.
The
sideEffects: falseflag allows bundlers to skip parsing, bundling, and executing entire unreferenced files. - Accelerates Build Times: Because the bundler can safely ignore unreferenced dependency files, it spends less time analyzing Abstract Syntax Trees (ASTs) during minification.
- Drastically Reduces Output for Component and Utility
Libraries: In large libraries (like UI component libraries or
large utility toolkits), a consumer might only use one component. With
sideEffects: false, only that specific component and its direct dependencies make it into the final bundle, often reducing library footprint by 80% to 90%.
Best Practices
- Always declare it in published packages: If you
maintain an npm package, adding
"sideEffects": false(or specifying exceptions) is essential for your consumers to achieve minimal bundle sizes. - Keep modules pure: Avoid top-level function calls, global modifications, or immediate initialization logic in source files containing exports.
- Isolate necessary side effects: Place
initialization code, polyfills, or style imports into dedicated files
and list them explicitly in the
sideEffectsarray.