# How to Register Element UI Components Globally vs Locally for Optimal Bundle Size

> Optimize your Element UI bundle size by registering components globally or locally. Learn how to import only needed modules with Vue.use() or the components option.

- Repository: [饿了么前端/element](https://github.com/ElemeFE/element)
- Tags: performance
- Published: 2026-03-07

---

**Register only the components you actually need by importing individual modules from `element-ui/packages/` and applying them globally with `Vue.use()` or locally via the `components` option, bypassing the full installer that pulls every component into your bundle.**

When building Vue applications with the [ElemeFE/element](https://github.com/ElemeFE/element) library, your registration strategy directly impacts final bundle size. The repository provides a convenient global installer that registers all 70+ components at once, but this convenience comes with a significant performance cost.

## Why Full Global Registration Bloats Your Bundle

The file [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js) contains a **global installer** that iterates through every component in the library and registers it via `Vue.component()`. According to the source code, this installer loops over the `components` array and calls `Vue.component(component.name, component)` for each entry【[`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js)†L183-L190】. 

When you call `Vue.use(Element)` in your main entry file, you trigger this entire registration chain. Webpack or Vite cannot tree-shake unused components because the import references a monolithic module that includes every component definition, regardless of whether your templates actually use `<el-date-picker>` or `<el-carousel>`.

## Selective Global Registration

### Importing Individual Component Modules

Each Element UI component lives in its own directory under `packages/` and exposes an `install` method compatible with Vue's plugin system. Importing these files directly enables **tree-shaking**, allowing your bundler to eliminate dead code.

```javascript
// main.js
import Vue from 'vue'
import Button from 'element-ui/packages/button/index.js'
import Input from 'element-ui/packages/input/index.js'

// Register globally but selectively
Vue.use(Button)  // Equivalent to Vue.component(Button.name, Button)
Vue.use(Input)

new Vue({ render: h => h(App) }).$mount('#app')

```

Now `<el-button>` and `<el-input>` are available in every component, but unused widgets like `el-table` or `el-dialog` never enter your bundle.

### How the Component Install Method Works

Individual component files follow a consistent pattern. The Button component exports an `install` method that registers itself with Vue【[`packages/button/index.js`](https://github.com/ElemeFE/element/blob/main/packages/button/index.js)†L4-L6】:

```javascript
// packages/button/index.js
import Button from './src/main';

/* istanbul ignore next */
Button.install = function(Vue) {
  Vue.component(Button.name, Button);
};

export default Button;

```

The Input component uses the identical pattern【[`packages/input/index.js`](https://github.com/ElemeFE/element/blob/main/packages/input/index.js)†L4-L6】. This standardized interface allows `Vue.use()` to work with any single component while ignoring the rest of the library.

## Local Registration for Component Isolation

For applications where only specific views need certain UI elements, **local registration** keeps component scope isolated to the files that actually use them. This approach can improve static analysis and dead-code elimination in complex codebases.

```vue
<!-- ContactForm.vue -->
<template>
  <div>
    <el-input v-model="email" placeholder="Email" />
    <el-button type="primary" @click="send">Send</el-button>
  </div>
</template>

<script>
import Button from 'element-ui/packages/button/index.js'
import Input from 'element-ui/packages/input/index.js'

export default {
  name: 'ContactForm',
  components: {
    [Button.name]: Button,
    [Input.name]: Input
  },
  data() {
    return { email: '' }
  },
  methods: {
    send() { console.log(this.email) }
  }
}
</script>

```

Local registration prevents global namespace pollution and makes dependencies explicit. When you delete this component file, your bundler can confidently remove the associated Element UI code from the production build.

## ES Module Imports and Tree-Shaking

Modern bundlers that respect ES modules can also import from `element-ui/lib`, which provides pre-compiled but separate entry points per component:

```javascript
import { Button, Input } from 'element-ui/lib'

Vue.component(Button.name, Button)
Vue.component(Input.name, Input)

```

While `element-ui/lib` resolves to CommonJS files, the source paths (`packages/*/index.js`) shown in previous examples offer the most aggressive tree-shaking potential because they reference the raw ES6 modules before compilation. For optimal results with Vite or Rollup, prefer importing directly from the `packages` directory.

## Summary

- **Avoid `Vue.use(Element)`** in production unless your application genuinely requires every single component, as [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js) registers all 70+ components unconditionally【[`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js)†L183-L190】.
- **Import from [`packages/component/index.js`](https://github.com/ElemeFE/element/blob/main/packages/component/index.js)** to leverage tree-shaking and ensure only used code enters your bundle.
- **Global selective registration** via `Vue.use(Component)` makes components available everywhere while maintaining a lean bundle.
- **Local registration** via the `components` option isolates dependencies to specific Vue files, improving maintainability and static analysis.
- Each component exports a standard `install` method (e.g., Button【[`packages/button/index.js`](https://github.com/ElemeFE/element/blob/main/packages/button/index.js)†L4-L6】, Input【[`packages/input/index.js`](https://github.com/ElemeFE/element/blob/main/packages/input/index.js)†L4-L6】) that enables both registration patterns.

## Frequently Asked Questions

### Does registering components locally reduce bundle size compared to global registration?

**Both selective global and local registration achieve the same bundle size reduction** as long as you import from individual component files rather than the full library. The critical factor is the import path—[`element-ui/packages/button/index.js`](https://github.com/ElemeFE/element/blob/main/element-ui/packages/button/index.js) versus `element-ui`—not the registration method. Local registration adds scoping benefits but does not inherently produce smaller bundles than selective global registration.

### What is the difference between importing from `element-ui` and `element-ui/packages/button`?

Importing from the root `element-ui` package loads [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js), which executes a loop registering every component in the library【[`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js)†L183-L190】. Importing from [`element-ui/packages/button/index.js`](https://github.com/ElemeFE/element/blob/main/element-ui/packages/button/index.js) loads only that specific component's code plus its dependencies. The latter path enables tree-shaking and prevents unused widgets from entering your production build.

### Can I mix global and local registration in the same project?

**Yes.** You can register frequently used components globally (like Button and Input) while keeping specialized components (like DatePicker or Carousel) registered locally only in the views that need them. This hybrid approach balances developer convenience with bundle optimization, ensuring rarely used widgets do not impact the initial JavaScript payload.

### How does Element UI's `install` method work for individual components?

Each component file attaches an `install` method to its default export that calls `Vue.component(component.name, component)`【[`packages/button/index.js`](https://github.com/ElemeFE/element/blob/main/packages/button/index.js)†L4-L6】. When you pass the module to `Vue.use()`, Vue internally executes this `install` function with the Vue constructor as the first argument. This mechanism allows individual components to register themselves using the same API pattern as the full library installer.