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

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 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 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†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.

// 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†L4-L6】:

// 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†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.

<!-- 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:

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 registers all 70+ components unconditionally【src/index.js†L183-L190】.
  • Import from 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†L4-L6】, Input【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 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, which executes a loop registering every component in the library【src/index.js†L183-L190】. Importing from 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†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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →