Flags top-level side effects in TypeScript code so bundlers can safely tree-shake what you don't use
eslint-plugin-better-tree-shaking
When bundlers like Webpack, Rollup, or esbuild encounter top-level side effects, they can't safely remove unused code. This plugin detects these patterns and suggests annotating them with /* @__PURE__ */ comments to enable better tree-shaking.
The /* @__PURE__ */ annotation tells the bundler this call has no side effects and can be safely removed if result is unused.
Function Calls
Calling a function at the top level is a side effect because the bundler doesn't know if the function modifies global state.
import { createConfig } from './config';
// ❌
export const config = createConfig();
// ✅
export const config = /* @__PURE__ */ createConfig();Method Calls
Same applies to method calls - the bundler can't know if obj.method() has side effects.
import Logger from './logger';
// ❌
export const logger = Logger.create();
// ✅
export const logger = /* @__PURE__ */ Logger.create();Property Access Chains
Accessing nested properties like foo.bar.bazz can trigger getters, which are side effects. Wrap in an IIFE to mark as pure.
import settings from './settings';
// ❌
export const theme = settings.ui.theme;
// ✅
export const theme = /* @__PURE__ */ (() => settings.ui.theme)();Objects with Side Effects
When an object contains multiple expressions with side effects (calls, computed keys), wrap the entire object in a pure IIFE.
import { getDefault, KEYS } from './utils';
// ❌
export const defaults = {
value: getDefault(),
[KEYS.primary]: getDefault('primary'),
};
// ✅
export const defaults = /* @__PURE__ */ (() => ({
value: getDefault(),
[KEYS.primary]: getDefault('primary'),
}))();Usage
Install the eslint-plugin-better-tree-shaking package, add it to the plugins section of your ESLint configuration file, and enable thebetter-tree-shaking/no-top-level-side-effects rule in the rules section.
{
"plugins": ["better-tree-shaking"],
"rules": {
"better-tree-shaking/no-top-level-side-effects": "error"
}
}