Frontend Development 6 min read

Why Importing Whole Libraries Bloats Your Bundle and How Wrapper Patterns Can Help

This article explains how importing entire libraries like lodash and Framer Motion can dramatically increase bundle size, demonstrates precise import techniques, introduces a wrapper pattern for better maintainability, and offers practical tips for choosing tree‑shakable libraries and tracking import sizes.

Code Mala Tang
Code Mala Tang
Code Mala Tang
Why Importing Whole Libraries Bloats Your Bundle and How Wrapper Patterns Can Help

Problem: Importing Whole Libraries

In a project we saw imports such as:

<code>import _ from 'lodash'; // 71.78KB
import { motion } from 'framer-motion'; // 111.19KB</code>

Importing the entire library adds roughly 180KB to the bundle, which can be about 18% of a 1 MB application.

Solution: Specific Imports

Import only the needed parts:

<code>import methodName from 'lodash/methodName';</code>
<code>import _ from 'lodash'; // 71.78KB
import debounce from "lodash/debounce"; // 3.41KB
import merge from 'lodash/merge'; // 16KB</code>

Even with these changes, managing imports across many files can cause:

Refactoring dozens of files.

Missing updates in some files.

Branch‑merge conflicts due to inconsistent import statements.

More Flexible Approach | Wrapper Pattern

Create a wrapper file, e.g., LodashWrapper.tsx :

<code>import debounce from "lodash/debounce"; // 21KB
const lodashWrapper = {
  debounce
};
export default lodashWrapper;</code>

Use the wrapper anywhere:

<code>import lodashWrapper from './lodashWrapper';
const SearchInput = () => {
  const [query, setQuery] = useState('');
  const handleSearch = useCallback(
    lodashWrapper.debounce((searchTerm) => {
      console.log('Searching for:', searchTerm);
    }, 500),
    []
  );
};</code>
Note: The wrapper pattern is for flexibility and maintainability, not for reducing bundle size. To shrink the bundle, import directly.

Visualization

After switching to direct imports, the build size looks like this (gzip ≈ 13.88 KB):

Bundle size after direct imports
Bundle size after direct imports

Why Use Wrappers?

Developers know what to import: The wrapper defines the optimal import once.

Avoid duplicate imports: Prevents different components from importing varying parts of the same library.

Easy maintenance: Updating the library or its import strategy only requires changing the wrapper.

Drawbacks include added complexity and more files.

Choosing the Right Library

When selecting a chart library, consider import ergonomics. Recharts does not support tree‑shakable imports, forcing you to import the whole library:

<code>import { BarChart } from 'recharts';</code>

Nivo offers tree‑shakable imports, allowing you to import only needed components:

<code>import { ResponsiveBar } from '@nivo/bar';</code>

This makes Nivo a better choice for performance‑sensitive apps. Note that Recharts v3 plans to address this limitation.

Tracking Import Size

You can monitor import sizes with the VS Code Import Cost extension.

Import Cost extension screenshot
Import Cost extension screenshot
frontendJavaScriptBundle Optimizationimport sizewrapper pattern
Code Mala Tang
Written by

Code Mala Tang

Read source code together, write articles together, and enjoy spicy hot pot together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.