> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/react-icons/react-icons/llms.txt
> Use this file to discover all available pages before exploring further.

# Tree-Shaking

> How React Icons optimizes bundle size through ES6 imports and tree-shaking

React Icons is designed for optimal bundle size by leveraging ES6 module imports and tree-shaking. Only the icons you import are included in your final bundle.

## What is Tree-Shaking?

Tree-shaking is a dead code elimination technique used by modern JavaScript bundlers (Webpack, Rollup, Vite, etc.) to remove unused exports from your final bundle.

<Info>
  With React Icons, importing 10 icons from a pack of 5,000+ icons will only include those 10 icons in your bundle, not the entire pack.
</Info>

## How It Works

React Icons uses ES6 named exports, which allow bundlers to determine exactly which icons are used:

```jsx theme={null}
// Only FaBeer and FaHome are included in your bundle
import { FaBeer, FaHome } from 'react-icons/fa';

function App() {
  return (
    <div>
      <FaBeer />
      <FaHome />
    </div>
  );
}
```

### Behind the Scenes

When you import from `react-icons/fa`, the bundler:

1. Analyzes which icons are actually used in your code
2. Includes only those icon components in the bundle
3. Excludes all unused icons from the final output
4. Optimizes the included icons during minification

## Bundle Size Impact

Here's a comparison of bundle sizes:

| Scenario                         | Icons Imported | Approximate Size |
| -------------------------------- | -------------- | ---------------- |
| No icons                         | 0              | \~0 KB           |
| Single icon                      | 1              | \~2-3 KB         |
| Ten icons                        | 10             | \~20-30 KB       |
| One hundred icons                | 100            | \~200-300 KB     |
| **NOT** entire Font Awesome pack | -              | **NOT** \~2+ MB  |

<Note>
  Actual sizes vary based on the specific icons and your bundler configuration. These are approximate gzipped sizes.
</Note>

## ES6 Import Pattern

React Icons v3+ uses ES6 named imports for optimal tree-shaking:

<Tabs>
  <Tab title="Recommended (v3+)">
    ```jsx theme={null}
    // ES6 named imports - enables tree-shaking
    import { FaBeer, FaHome, FaUser } from 'react-icons/fa';

    function App() {
      return (
        <div>
          <FaBeer />
          <FaHome />
          <FaUser />
        </div>
      );
    }
    // Bundle includes: FaBeer, FaHome, FaUser only
    ```
  </Tab>

  <Tab title="Legacy (v2)">
    ```jsx theme={null}
    // Old default imports - NO tree-shaking
    import FaBeer from 'react-icons/lib/fa/beer';
    import FaHome from 'react-icons/lib/fa/home';
    import FaUser from 'react-icons/lib/fa/user';

    function App() {
      return (
        <div>
          <FaBeer />
          <FaHome />
          <FaUser />
        </div>
      );
    }
    // This pattern is deprecated - use v3+ syntax
    ```
  </Tab>
</Tabs>

## Package Configuration

React Icons is configured for optimal tree-shaking:

```json theme={null}
// package.json
{
  "name": "react-icons",
  "module": "lib/index.mjs",    // ES6 module entry point
  "main": "lib/index.js",       // CommonJS entry point
  "sideEffects": false,          // Enables aggressive tree-shaking
  "type": "module"
}
```

### sideEffects: false

The `"sideEffects": false` declaration tells bundlers that:

* No code in this package has side effects
* Unused exports can be safely removed
* Aggressive tree-shaking is safe

<Info>
  This configuration is already set in React Icons - you don't need to configure anything!
</Info>

## Verifying Tree-Shaking

### Using Webpack Bundle Analyzer

Install and configure webpack-bundle-analyzer:

```bash theme={null}
npm install --save-dev webpack-bundle-analyzer
```

```javascript theme={null}
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
};
```

Run your build to see which icons are included in your bundle.

### Using Rollup Plugin Visualizer

For Vite or Rollup projects:

```bash theme={null}
npm install --save-dev rollup-plugin-visualizer
```

```javascript theme={null}
// vite.config.js
import { visualizer } from 'rollup-plugin-visualizer';

export default {
  plugins: [
    visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true,
    })
  ]
};
```

### Manual Bundle Size Check

```bash theme={null}
# Build your project
npm run build

# Check the output size
ls -lh dist/
```

## Common Tree-Shaking Issues

### Issue 1: Large Bundle Size

If your bundle is unexpectedly large:

<Warning>
  **Problem**: Using barrel imports or re-exporting icons

  ```jsx theme={null}
  // Avoid: This may prevent tree-shaking
  import * as Icons from 'react-icons/fa';

  function App() {
    return <Icons.FaBeer />;
  }
  ```

  **Solution**: Use named imports

  ```jsx theme={null}
  // Good: Enables proper tree-shaking
  import { FaBeer } from 'react-icons/fa';

  function App() {
    return <FaBeer />;
  }
  ```
</Warning>

### Issue 2: Dynamic Icon Loading

<Warning>
  **Problem**: Dynamic imports can include unnecessary icons

  ```jsx theme={null}
  // Avoid: May include all icons
  import * as Icons from 'react-icons/fa';

  function DynamicIcon({ name }) {
    const Icon = Icons[name];
    return <Icon />;
  }
  ```

  **Solution**: Create a explicit icon map

  ```jsx theme={null}
  // Good: Only includes specified icons
  import { FaBeer, FaHome, FaUser } from 'react-icons/fa';

  const iconMap = {
    beer: FaBeer,
    home: FaHome,
    user: FaUser,
  };

  function DynamicIcon({ name }) {
    const Icon = iconMap[name];
    return Icon ? <Icon /> : null;
  }
  ```
</Warning>

### Issue 3: Re-exporting Icons

<Warning>
  **Problem**: Re-exporting all icons from a module

  ```jsx theme={null}
  // icons.js - Avoid
  export * from 'react-icons/fa';
  export * from 'react-icons/md';
  ```

  **Solution**: Re-export only what you need

  ```jsx theme={null}
  // icons.js - Good
  export { FaBeer, FaHome } from 'react-icons/fa';
  export { MdEmail, MdPhone } from 'react-icons/md';
  ```
</Warning>

## Best Practices

### 1. Import Only What You Use

```jsx theme={null}
// Good: Specific imports
import { FaBeer, FaHome } from 'react-icons/fa';

// Avoid: Namespace imports
import * as FaIcons from 'react-icons/fa';
```

### 2. Group Imports by Pack

```jsx theme={null}
// Good: Organized and tree-shakeable
import { 
  FaHome, 
  FaUser, 
  FaCog,
  FaBell 
} from 'react-icons/fa';

import { 
  MdEmail, 
  MdPhone 
} from 'react-icons/md';
```

### 3. Use Explicit Icon Maps

For dynamic icon selection:

```jsx theme={null}
import { FaHome, FaUser, FaCog } from 'react-icons/fa';

// Explicit map enables tree-shaking
const ICONS = {
  home: FaHome,
  user: FaUser,
  settings: FaCog,
};

function Icon({ name, ...props }) {
  const IconComponent = ICONS[name];
  return IconComponent ? <IconComponent {...props} /> : null;
}
```

### 4. Avoid Conditional Imports

```jsx theme={null}
// Avoid: Both icons included in bundle
import { FaSun, FaMoon } from 'react-icons/fa';

function ThemeIcon({ isDark }) {
  return isDark ? <FaMoon /> : <FaSun />;
}
// Both FaSun and FaMoon are in the bundle

// This is actually fine! Both icons are imported intentionally.
// Tree-shaking removes unused icons, not conditionally rendered ones.
```

### 5. Code Splitting for Large Icon Sets

For pages with many icons, use dynamic imports:

```jsx theme={null}
import { lazy, Suspense } from 'react';

// Split icon-heavy components into separate chunks
const IconGallery = lazy(() => import('./IconGallery'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <IconGallery />
    </Suspense>
  );
}
```

## Bundler Compatibility

React Icons works with all modern bundlers that support ES6 modules:

| Bundler   | Tree-Shaking Support | Configuration Required |
| --------- | -------------------- | ---------------------- |
| Webpack 5 | ✅ Yes                | No (automatic)         |
| Webpack 4 | ✅ Yes                | Mode: production       |
| Rollup    | ✅ Yes                | No (automatic)         |
| Vite      | ✅ Yes                | No (automatic)         |
| Parcel 2  | ✅ Yes                | No (automatic)         |
| esbuild   | ✅ Yes                | No (automatic)         |
| Turbopack | ✅ Yes                | No (automatic)         |

<Info>
  Most modern bundlers enable tree-shaking automatically in production mode.
</Info>

## Measuring Impact

### Before and After Example

```jsx theme={null}
// Before: Inefficient imports
import * as Icons from 'react-icons/fa';

function App() {
  return (
    <div>
      <Icons.FaBeer />
      <Icons.FaHome />
    </div>
  );
}
// Bundle size: ~2MB (entire Font Awesome pack)
```

```jsx theme={null}
// After: Optimized imports
import { FaBeer, FaHome } from 'react-icons/fa';

function App() {
  return (
    <div>
      <FaBeer />
      <FaHome />
    </div>
  );
}
// Bundle size: ~4KB (just two icons)
// Savings: ~99.8% reduction! 🎉
```

## Alternative: Per-Icon Imports

For specific build systems (Meteor, older Gatsby), use `@react-icons/all-files`:

```jsx theme={null}
import { FaBeer } from '@react-icons/all-files/fa/FaBeer';
import { FaHome } from '@react-icons/all-files/fa/FaHome';

function App() {
  return (
    <div>
      <FaBeer />
      <FaHome />
    </div>
  );
}
```

<Warning>
  This approach is **not recommended** for most projects. Use standard imports with tree-shaking instead.
</Warning>

## Debugging Tree-Shaking

### Enable Webpack Stats

```javascript theme={null}
// webpack.config.js
module.exports = {
  optimization: {
    usedExports: true, // Enable tree-shaking
  },
  stats: {
    usedExports: true, // Show which exports are used
  },
};
```

### Check Bundle Contents

```bash theme={null}
# View bundled files
ls -lh dist/

# Search for icon references
grep -r "FaBeer" dist/
```

## Performance Tips

1. **Use production builds**: Tree-shaking is most effective in production mode
2. **Enable minification**: Minifiers remove dead code after tree-shaking
3. **Use code splitting**: Split icon-heavy components into separate chunks
4. **Lazy load icon packs**: Use dynamic imports for rarely-used icons
5. **Monitor bundle size**: Use tools like Bundle Analyzer regularly

<CardGroup cols={2}>
  <Card title="Icon Imports" icon="download" href="/core-concepts/icon-imports">
    Learn the import patterns that enable tree-shaking
  </Card>

  <Card title="TypeScript" icon="code" href="/core-concepts/typescript">
    See type-safe imports and tree-shaking
  </Card>
</CardGroup>
