Top 5 Vite+Vue3 Micro‑Frontend Solutions for 2025: Pros, Cons & Code
This article reviews five leading micro‑frontend approaches for Vite+Vue3 in 2025, explains why Vite+Vue3 is essential, provides practical configuration examples, compares strengths and weaknesses, offers a selection guide, and highlights common pitfalls to help teams choose the right solution.
The article shares practical experience on selecting and implementing the most popular micro‑frontend solutions within the Vite+Vue3 ecosystem in 2025.
Why Vite+Vue3?
Teams that do not adopt Vite+Vue3 risk falling behind; the stack offers native ES‑module support, Vue 3 Composition API for flexible state sharing, and a mature plugin ecosystem that simplifies style isolation, routing hijacking, and dependency sharing.
Vite's ES‑module advantage : eliminates bundling in dev, enables on‑demand loading and fast HMR.
Vue 3 Composition API : improves state communication and type safety.
Ecosystem maturity : plugins now handle style isolation, routing, and shared dependencies out of the box.
Solution 1: qiankun – Vite‑adapted classic
Core principle
Based on single‑spa routing hijack and sandbox, but automatically detects Vite ES‑module format, removing manual configuration.
<!-- main‑app/src/App.vue --></code><code><template></code><code> <div></code><code> <nav></code><code> <button @click="gotoApp('vue‑app1')">应用1</button></code><code> <button @click="gotoApp('vue‑app2')">应用2</button></code><code> </nav></code><code> <!-- 子应用挂载点 --></code><code> <div id="micro‑app‑container"></div></code><code> </div></code><code></template></code><code><script setup></code><code>import { registerMicroApps, start } from 'qiankun';</code><code>import { useRouter } from 'vue‑router';</code><code>const router = useRouter();</code><code>// Register sub‑apps</code><code>registerMicroApps([</code><code>{ name: 'vue‑app1', entry: '//localhost:5173', container: '#micro‑app‑container', activeRule: '/app1', props: { token: 'main_app_token', onLogin: userInfo => console.log('子应用登录了', userInfo) } },</code><code>// app2 config ...</code><code>]);</code><code>start({ sandbox: { cssVars: ['--primary-color', '--font-size'] } });</code><code>const gotoApp = app => { router.push(app === 'vue‑app1' ? '/app1' : '/app2'); };</code><code></script>Advantages
Mature and stable with rich documentation.
Robust sandbox for JS and CSS isolation, low migration cost.
Supports pre‑loading sub‑apps for faster first‑screen load.
Disadvantages
Still relies on HTML entry, not fully aligned with Vite's ES‑module model.
Configuration is verbose; newcomers often stumble on activeRule and sandbox.
Solution 2: Module Federation – Vite’s native child
Core principle
Shares code as ES modules; the host and remote act like a “module supermarket”, allowing on‑demand import of components, routes, or state without HTML entry constraints.
Practical config (remote)
// app2/vite.config.ts</code><code>import { defineConfig } from 'vite';</code><code>import vue from '@vitejs/plugin-vue';</code><code>import federation from '@originjs/vite-plugin-federation';</code><code>export default defineConfig({</code><code> plugins: [vue(), federation({ name: 'app2', filename: 'remoteEntry.js', exposes: { './App': './src/App.vue', './routes': './src/routes.ts', './store': './src/store/index.ts' }, shared: ['vue', 'vue-router', 'pinia'] })]</code><code>});Host usage
<!-- main‑app/src/views/App2View.vue --></code><code><template></code><code> <div></code><code> <h2>这是来自app2的组件</h2></code><code> <App2Component /></code><code> </div></code><code></template></code><code><script setup></code><code>const App2Component = defineAsyncComponent(() => import('app2/App'));</code><code>import app2Routes from 'app2/routes';</code><code>console.log('app2的路由配置', app2Routes);</code><code></script></code><code><style scoped></code><code>/* style isolation via scoped or CSS Modules */</code><code></style>Advantages
True module‑level sharing, perfectly fits Vite’s ES‑module philosophy.
30%+ performance gain over qiankun in large apps.
Can share any module, not just whole apps.
Disadvantages
Requires strict team conventions; uncontrolled sharing can cause dependency chaos.
Style isolation must be handled manually (scoped/CSS Modules).
Not ideal for legacy migrations; best for fresh Vite+Vue3 projects.
Solution 3: Garfish – ByteDance’s champion
Core principle
Uses an “application container” model with independent sandbox, style isolation, and built‑in Vue3 loader, plus performance monitoring and error tracking.
Host config
// main‑app/src/main.ts</code><code>import { createApp } from 'vue';</code><code>import App from './App.vue';</code><code>import { Garfish } from 'garfish';</code><code>const app = createApp(App);</code><code>const garfish = new Garfish({</code><code> containers: [{ name: 'app‑container', el: '#app‑container' }],</code><code> apps: [{ name: 'vue3‑app', entry: '//localhost:3000', activeWhen: '/vue3‑app', props: { app } }],</code><code> vite: { hmr: true }</code><code>});</code><code>garfish.start();</code><code>app.mount('#app');Sub‑app config
// vue3‑app/src/main.ts</code><code>import { createApp } from 'vue';</code><code>import App from './App.vue';</code><code>import { vue3Adapter } from '@garfish/adapter-vue3';</code><code>const app = createApp(App);</code><code>export const provider = vue3Adapter({ app, mount({ el }) { app.mount(el); }, unmount() { app.unmount(); } });Advantages
ByteDance‑backed stability, used in large‑scale internal systems.
Deep Vue3 integration, can share the app instance and global directives.
Built‑in performance monitoring and error tracking for enterprise teams.
Disadvantages
Ecosystem smaller than qiankun or Module Federation; fewer third‑party plugins.
Documentation primarily in Chinese (advantage for Chinese teams, but a barrier for others).
Solution 4: Wujie – Tencent’s lightweight newcomer
Core principle
Combines a web‑component container with an iframe sandbox, leveraging native iframe isolation and custom elements to embed sub‑apps as reusable components.
Host config
<!-- template --></code><code> <div><wujie‑vue name="sub‑app1" :url="subAppUrl1" :props="subAppProps" :preload="true"></wujie‑vue></div></code><code><script setup></code><code>import WujieVue from 'wujie‑vue3';</code><code>import { ref } from 'vue';</code><code>const subAppUrl1 = ref('//localhost:5174');</code><code>const subAppProps = { someData: 'from main app' };</code><code></script></code><pre><code>// main.ts</code><code>import { createApp } from 'vue';</code><code>import App from './App.vue';</code><code>import WujieVue from 'wujie‑vue3';</code><code>const app = createApp(App);</code><code>app.use(WujieVue);</code><code>app.mount('#app');Advantages
Low integration cost; sub‑apps can be added like ordinary components.
High speed with static resource pre‑loading and pre‑execution.
Supports sub‑app keep‑alive, multi‑app activation, decentralized communication, and Vite compatibility.
Disadvantages
Community and ecosystem still growing; fewer plugins and articles.
Solution 5: micro‑app (JD) – Component‑centric approach
Core principle
Encapsulates each sub‑app as a WebComponent using CustomElement and ShadowDOM, providing strong isolation and component‑style composition.
Host config
// main‑app/src/main.ts</code><code>import { createApp } from 'vue';</code><code>import App from './App.vue';</code><code>import microApp from '@micro‑app/vue3';</code><code>const app = createApp(App);</code><code>app.use(microApp, { apps: [{ name: 'sub‑app‑vue', entry: '//localhost:5175', container: '#sub‑app‑container', activeRule: '/sub‑app' }] });</code><code>app.mount('#app'); <!-- template --></code><code> <div id="sub‑app‑container"></div>Sub‑app config
// sub‑app/vite.config.ts</code><code>import { defineConfig } from 'vite';</code><code>import vue from '@vitejs/plugin-vue';</code><code>import microAppPlugin from '@micro‑app/vite‑plugin';</code><code>export default defineConfig({ plugins: [vue(), microAppPlugin({ name: 'sub‑app‑vue' })], server: { port: 5175, cors: true } });Advantages
Component‑oriented architecture makes integration and management intuitive.
ShadowDOM provides good style and script isolation.
Supports Vite out of the box.
Disadvantages
Sandbox not fully isolated; may not suit high‑security scenarios.
Requires a specific plugin for sub‑apps, adding configuration complexity.
2025 Selection Guide: Which solution to pick?
• For multiple teams with legacy projects needing smooth migration, choose qiankun for its compatibility and mature sandbox.
• For brand‑new Vite+Vue3 projects that prioritize performance and seamless Vite integration, Module Federation is the best fit.
• For ultra‑large back‑office systems that demand enterprise‑grade stability and monitoring, Garfish offers deep Vue3 support and built‑in tools.
• For teams that value lightweight setup and rich features like keep‑alive and decentralized communication, Wujie is a strong candidate.
• For those who prefer a component‑centric micro‑frontend model, micro‑app provides good isolation and composability.
Pitfalls to avoid in 2025 (3 common traps)
Don’t over‑share dependencies. Only share core libraries such as vue and vue‑router; sharing utilities like lodash can cause version conflicts.
Standardize on history mode for routing. Hash routing leads to nesting issues; use history with a base configuration for isolation.
Don’t rely solely on framework‑provided style isolation. Add a unique prefix (e.g., app1‑) to each sub‑app’s CSS to prevent global leakage.
Final thoughts
Micro‑frontends are not a silver bullet. Small teams with simple business logic may stick to a single app and module splitting. When the team grows beyond five developers and the business becomes complex, the Vite+Vue3 micro‑frontend solutions reviewed here are mature enough for 2025, and choosing the right one depends on legacy constraints, performance needs, and architectural preferences.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
