Library / SDK
element-plus-x/Element-Plus-X avatar
element-plus-x/Element-Plus-X

Element-Plus-X: AI chat components for Vue 3, on a misspelled default branch

Enterprise-level AI component library front-end solution 🤖

1,477 stars196 forksVueMIT

At a glance

What is it?
Element-Plus-X packages the presentation layer of a conversational UI for Vue 3 and Element-Plus: bubble lists, a sender with attachments and voice, thinking and thought-chain components, and streaming hooks. It is MIT licensed and young at 2.0.x, and its README still points badges at a former organisation while the default branch is named updata-2602.
Who is it for?
Adopt Element-Plus-X when chat is central to a Vue 3 product already standardised on Element-Plus, and start from the per-component import of BubbleList and XSender so tree shaking works. Do not adopt it for code-heavy conversations, since neither markdown rendering nor syntax highlighting appears in the component list, and not if you are on another component library.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 32 days ago.
What is it written in?
Mainly Vue, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Chat interface components, and who they are for

Element-Plus-X is described in its own README as a ready-to-use enterprise AI component library based on Vue 3 and Element-Plus. The published package on npm is named `vue-element-plus-x`, which is worth knowing before you search for it.

The scope is the presentation layer of a conversational application and nothing below it. The core features are stated as enterprise AI components with built-in scenario components for chatbot and voice interaction, zero-configuration integration following the Element-Plus design system, and on-demand loading with tree shaking.

That positioning is the useful part. Anyone building a chat interface with Vue has, at some point, written a message bubble, a scrolling list that keeps the newest message in view, an input row with a send button and an attachments menu, and a typing indicator. This library is that set of components, plus the parts specific to model output: a thinking indicator and a thought-chain component.

The audience is a team already on Element-Plus who wants their AI interface to match the rest of their admin tooling instead of looking like a different product bolted on. That is a coherent reason to adopt it and a narrow one.

It is MIT licensed, the repository is not archived, and the last push was on 2026-08-31. Releases are v2.0.3 on 2026-05-15, v2.0.2 on 2026-05-10 and v2.0.1 on 2026-05-07, three releases inside eight days, so the 2.0 line is recent and young.

The default branch is called updata-2602

The default branch of this repository is `updata-2602`.

That is a misspelling of update, and the suffix reads as a date, so the branch name appears to have been created as a temporary working branch for a February 2026 release and then made the default. Whether that was deliberate or an accident, the consequences are concrete.

Anything that assumes a conventional branch name misbehaves. CI configuration, `git clone` defaults, tooling that diffs against `main` or `master`, automation that opens pull requests against the base branch, and release scripts that compute a version bump from commits since a named base all have to be told the real name explicitly. A fork will clone `updata-2602` and treat it as the trunk, which is confusing at best.

It also makes the version history harder to read. The release tags are v2.0.1 through v2.0.3 on the `main` naming convention the README describes, while the branch carrying the work is named for a different month. Anyone trying to work out which commit shipped in which release has to check both.

This is not an argument against the library. It is an argument for looking at the branch before you depend on it, and for pinning your CI to a branch name you control rather than inheriting one that may be renamed.

Installing and mounting, three ways

The install command is the same under any package manager, with pnpm marked as recommended.

bash
pnpm install vue-element-plus-x

The first usage pattern is per-component import, which is what the tree shaking claim is about.

vue
<script setup>
import { BubbleList, XSender } from 'vue-element-plus-x';

const list = [
  {
    content: 'Hello, Element Plus X',
    role: 'user'
  }
];
</script>

<template>
  <div
    style="display: flex; flex-direction: column; height: 230px; justify-content: space-between;"
  >
    <BubbleList :list="list" />
    <XSender />
  </div>
</template>

The message shape is the visible API. A list of objects with `content` and `role`, which is the minimum a chat UI needs and a good sign about how much abstraction is in the way.

The second pattern is global registration through the plugin.

ts
import { createApp } from 'vue';
import ElementPlusX from 'vue-element-plus-x';
import App from './App.vue';

const app = createApp(App);
app.use(ElementPlusX);
app.mount('#app');

The third is a CDN script tag, and the README annotates it with its own warning.

html
<script src="https://unpkg.com/[email protected]/dist/umd/index.js"></script>

Two things are wrong with that snippet before you run it. The version is pinned to 1.3.0 while the current release line is 2.0.x, and the README marks the method with a comment saying it still needs testing. Use the package manager.

What is actually in the box

The component table lists ten components and four hooks, and the Chinese labels distinguish extended components from new ones, which is a useful signal about where the library's own work is.

For the message area: `Bubble` is a single message bubble, marked as extended, and `BubbleList` is the scrolling list of them, also extended. `Conversations` is a conversation history sidebar, marked extended. `Thinking` is a thinking indicator, extended, and `ThoughtChain` is a thought-chain display, which is the component for rendering a model's reasoning steps when the provider exposes them. `Welcome` is an empty-state welcome panel, and `Prompts` is a set of suggested prompts for the start of a conversation.

For input: `XSender` is the smart input box with voice interaction and mention support, `Attachments` is the upload attachment component, and `FilesCard` is the card shown for an attached file.

The hooks are where the interesting work is. `useXStream` is a streaming interface hook, and `useSend` with `XRequest` is an extended split of it, so you can use one piece without the other. `useRecord` wraps the browser's built-in speech recognition API, which means voice input depends on what the browser provides rather than on a bundled audio model.

That list is the honest scope. There is no markdown renderer, no code-block syntax highlighting, no virtualised list, and no conversation persistence in the table. Those are the pieces you would expect to build or add, and a team shipping a production chat product should check for them before committing.

Badges pointing at a different organisation, and a tag from the 1.x line

The repository is `element-plus-x/Element-Plus-X`. Several README links point somewhere else.

The licence badge, the star badge, the npm badge and the English documentation link all target `github.com/HeJiaYue520/Element-Plus-X`. The links further down the README, in the quick-links table, correctly point at `github.com/element-plus-x/Element-Plus-X`. The template project is hosted under the same other account, as `HeJiaYue520/ruoyi-element-ai` on GitHub and a matching Gitee repository.

The likely explanation is an organisation rename with the badges and the template links left behind. The practical effect is that the licence badge does not take you to the licence in this repository, and anyone who lands on the old path may be looking at a fork rather than the source they installed.

The homepage metadata points at `v2.element-plus-x.com` while the README links `element-plus-x.com` and `v.element-plus-x.com` for the live preview. Three hostnames for one project, which is harmless but adds a step when you are trying to confirm you are reading current documentation.

None of this makes the library untrustworthy. It does mean the README's links are not a reliable guide to where things live now, so check the npm package page and the repository's own file listing rather than following a badge.

Two linters, changesets, and four changelog generators

The workspace is pnpm 10.6.5 with Turborepo, Node 18 or newer, and a changeset directory at the root, so versioning goes through changesets rather than manual tag bumps.

The scripts show how far the release machinery goes. `ci:publish` runs `pnpm changeset publish -r --filter=vue-element-plus-x` and appends the OTP inline.

json
"ci:publish": "pnpm changeset publish -r --filter=vue-element-plus-x --otp=${NPM_OTP:-}"

That inline expansion is worth a second look. It is shell syntax inside an npm script, so it depends on the shell running it, and it places a one-time password on the command line where it can appear in process listings and shell history. The default `${NPM_OTP:-}` does expand to an empty string when the variable is unset, which is the intent.

There is a second publishing path that does not use changesets at all.

json
"publish:core": "cd packages/core && npm publish"

So the package can be published by hand from its own directory or through the changesets flow from the root. Two routes to the same registry is a small inconsistency worth knowing about before you conclude a version was released when it was not.

The changelog side is unusually heavy: `gen:changelog`, `changelog:git`, `changelog:github`, `changelog:auto` and `changelog:full`, each a TypeScript script under `apps/docs/scripts/`, with one wrapping a GitHub API client. Linting runs both oxlint and eslint, and formatting is Prettier across TypeScript, TSX and Markdown, with lint-staged and husky wiring commits through it.

Where Element-Plus-X is the wrong tool

Five reasons, and the first two are structural rather than fixable.

If you are not on Element-Plus, the value drops sharply. The library's own claim is zero-configuration integration following the Element-Plus design system, so on a project using another Vue component library you get chat components that do not match anything around them, which is the exact problem it was built to solve.

If you need reasoning output rendered, `ThoughtChain` and `Thinking` exist but the table says nothing about how a provider's reasoning trace is parsed. Mapping a specific vendor's stream format onto those components is work the README does not describe.

If your messages contain code, that is a bigger gap than it looks. A chat UI for developers needs markdown rendering with sanitisation, and syntax highlighting inside code blocks, and neither appears in the component or hook list. `Bubble` takes content and a role.

The remaining two are operational. The 2.0 line is three releases old, dated 2026-05-07 to 2026-05-15, and a young major version is exactly when APIs move. And the default branch name described earlier means any automation you write has to name branches explicitly.

What is not a reason: the library is MIT licensed, actively maintained as of 2026-08-31, and free.

Against assembling the same components yourself

The alternative is writing the six or so components yourself against Element-Plus primitives, which is entirely feasible and is what most teams do before they reach for a library.

The difference in approach is ownership. Your version has exactly the API your backend speaks, because you designed both. When the model provider changes its streaming format, you change one adapter. There is no intermediate layer between your fetch call and the component tree, and no `useXStream` contract to work around.

What you give up is the parts that are genuinely tedious. A `BubbleList` that scrolls correctly when a message arrives, keeps the newest item visible, handles an image that loads late and changes the height, and does not lose scroll position when the user has scrolled up is real work. `XSender` with attachments, mentions and voice is more. That is why this library exists and it is a reasonable bet.

The tie-breaker is usually how much of your product is chat. A product that is mostly an admin dashboard with one AI assistant should take the six components. A product where the chat interface is the product should take the library and contribute to it, and note that the roadmap is described as updated weekly from issues and the community group, which is a sign the maintainers want that traffic.

Whichever way you go, keep your message objects behind your own interface rather than passing provider payloads straight to components. That one boundary makes either choice reversible.

Editorial conclusion

Adopt Element-Plus-X when chat is central to a Vue 3 product already standardised on Element-Plus, and start from the per-component import of BubbleList and XSender so tree shaking works. Do not adopt it for code-heavy conversations, since neither markdown rendering nor syntax highlighting appears in the component list, and not if you are on another component library. Verify first that the branch your CI builds is the one you expect, because the default branch is named updata-2602 rather than main, and pin the npm version instead of following the README's CDN snippet, which references 1.3.0.

Frequently asked questions

How do I install Element-Plus-X?

Run npm install vue-element-plus-x, with pnpm or yarn as alternatives and pnpm marked as recommended. The package name is vue-element-plus-x even though the project is called Element-Plus-X.

Which components does Element-Plus-X provide?

Bubble, BubbleList, Conversations, Welcome, Prompts, FilesCard, Attachments, XSender, Thinking and ThoughtChain, plus the hooks useRecord for the browser speech recognition API, useXStream for streaming, and useSend with XRequest as an extended split of it.

How do I register Element-Plus-X globally in a Vue app?

Import the default export and install it as a plugin with app.use(ElementPlusX) before app.mount. The README also shows a per-component import using BubbleList and XSender, which is the tree-shaking friendly path.

Can I load Element-Plus-X from a CDN?

The README includes a script tag pointing at unpkg for vue-element-plus-x, but it pins version 1.3.0 while the current line is 2.0.x, and the README marks the CDN method as still needing testing. Use the package manager instead.

What is the default branch of the Element-Plus-X repository?

The default branch is updata-2602, a misspelled and dated name rather than main or master, so CI, clone defaults and release scripts need the branch named explicitly.

What licence is Element-Plus-X under?

MIT, and the README also states that CDN acceleration and security protection are sponsored by Tencent EdgeOne. Check the LICENSE file in the repository for the terms themselves; this is not legal advice.

Official sources

  1. element-plus-x/Element-Plus-X on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/element-plus-x-element-plus-x.svg)](https://hysenlabs.com/projects/element-plus-x-element-plus-x)