How a build tool finds code an app never needs

Tree shaking happens while an application is being prepared for release. A bundler—the tool that gathers a project’s files into downloadable app code—starts at the app’s entry points and follows the imports that connect files. It can then track which exported functions and values are actually used. Code that cannot be reached from those entry points is a candidate for removal.

The name suggests a useful picture: the tool keeps the branches connected to the trunk and cuts away the rest. But it is not watching the app run and noticing which buttons people never press. It makes a decision ahead of time, from the structure of the code.

Why code structure matters

Tree shaking works best when files use static imports and exports—relationships written plainly enough for a tool to inspect before the app runs. If a module’s contents are loaded dynamically, or its behavior is difficult to predict, the bundler may have to keep more code to avoid breaking the app.

It must also account for side effects: actions that matter even when no function’s return value is used, such as registering a handler or changing shared state. If a file might do something important when loaded, removing it could alter the app’s behavior. Bundlers therefore rely on code patterns and project settings to judge what is safe to discard.

What gets smaller—and what does not

Removing unused code can shrink the JavaScript shipped to a browser or included in an app, which means less code to download or process. It does not automatically eliminate every unnecessary instruction: the tool can only remove what it can identify as unused without changing the program’s intended effects. A tidy import structure can therefore determine whether a library contributes only the feature an app uses—or brings along much of the package with it.