webcake-ui-kit

UI Kit for Vue 2 && 3 - Pure Options API
19,775 8
Install
npm install webcake-ui-kit
Latest Version:1.3.23
Vue:2 · 3
License:MIT
Last Updated:Oct 19, 2026
Links: GitHub  ·  npm
Maintainer: huyanh

webcake-ui-kit

The Vue UI kit that doesn't make you choose.

One library. Two Vue versions. Zero build step. Ship the same components to Vue 2.7 and Vue 3 — from a single source, with one import.

npm version Vue 2 & 3 No build License

📖 Live Docs & Storybook → ui.webcake.io

Browse every component, prop, slot, and variant — running live in the browser.


👋 Welcome

Migrating from Vue 2 to Vue 3 is painful enough — your UI library shouldn't make it worse.

Most Vue component libraries force you to pick a side. Choose Vue 2 → you're stuck. Choose Vue 3 → you have to rewrite the app first. Either way, you carry the cost.

webcake-ui-kit refuses that tradeoff. Every component is hand-authored under strict dual-compatibility rules so the same import compiles, renders, and behaves identically on Vue 2.7 and Vue 3.4+ — from a codebase you can grep, fork, and theme as if it were your own.

import { WkButton, WkDialog, WkInput } from 'webcake-ui-kit'
// ✅ Vue 2.7 — works
// ✅ Vue 3.x — works
// ✅ Same API. Same styles. Same behavior. One source of truth.

No -vue2 package. No -vue3 package. No build artifact gymnastics. Just .vue files, the way the framework intended.


⚡ Quick start

Get a button on screen in under 60 seconds.

1. Install

npm install webcake-ui-kit
pnpm add webcake-ui-kit
yarn add webcake-ui-kit

Peer dependency: vue ^2.6.0 || ^3.0.0. That's it.

2. Import the styles once

import 'webcake-ui-kit/styles'

3. Register components

Vue 3

Vue 2.7

// main.js
import { createApp } from 'vue'
import { WkButton, WkDialog, WkInput } from 'webcake-ui-kit'
import 'webcake-ui-kit/styles'
import App from './App.vue'

const app = createApp(App)
app.component('WkButton', WkButton)
app.component('WkDialog', WkDialog)
app.component('WkInput', WkInput)
app.mount('#app')
// main.js
import Vue from 'vue'
import { WkButton, WkDialog, WkInput } from 'webcake-ui-kit'
import 'webcake-ui-kit/styles'
import App from './App.vue'

Vue.component('WkButton', WkButton)
Vue.component('WkDialog', WkDialog)
Vue.component('WkInput', WkInput)

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

4. Use it

<template>
  <div>
    <WkButton variant="primary" @click="open = true">Open dialog</WkButton>

    <WkDialog v-model="open" title="Hello from webcake 👋">
      <WkInput v-model="name" placeholder="Your name" />
    </WkDialog>
  </div>
</template>

<script>
export default {
  data: () => ({ open: false, name: '' })
}
</script>

🎉 That's it. The same .vue file works on both runtimes — no #ifdef, no wrapper, no shim.


✨ Why teams pick webcake

🎯 True dual-compat

One source. Vue 2.7 and Vue 3.x. Tested on both runtimes in CI — every PR, every component.

📦 Ships raw SFC

No pre-compiled artifacts. Your bundler compiles .vue files once, alongside your app. Zero version lock.

🎨 Token-driven theming

Override --color-primary and the whole kit rebrands. No SASS, no providers, no JS theme objects.

♿ Accessible by default

Semantic HTML, :focus-visible rings, ARIA where it matters. Not retrofitted — designed in.

🪶 Tree-shakable

Named exports only. Import Button, leave the rest behind. No Vue.use(KitchenSink).

📖 Storybook included

Every component, every variant, every prop — browsable before you npm install.


🧩 Components

All exports are prefixed with Wk to avoid global name collisions and to be greppable across consumer apps.

Forms Overlays Layout Display
WkButton WkDialog WkAccordion WkBadge
WkButtonGroup WkAlertDialog WkAccordionItem WkTag
WkInput WkTooltip* WkTabs WkDivider
WkCheckbox WkBreadcrumb WkSpinner
WkCheckboxGroup WkPagination WkTypography
WkRadio / WkRadioGroup WkSidebarItem
WkSelect / WkSelectOption WkSidebarGroupLabel
WkSwitch / WkSwitchGroup
WkToggle / WkToggleGroup
WkSlider
WkRichCheckboxGroup
WkRichSwitchGroup

* coming soon · more on the way

All components follow the same conventions: validated props, declared emits, BEM-style hooks (ui-button--primary), and v-model where it makes sense.

👉 Want to see them in action? Browse the live Storybook →


🎨 Theming

Every component reads from CSS custom properties. Drop them on :root and the whole kit rebrands:

:root {
  --color-primary: #ff6b9d;
  --color-primary-hover: #ff4d8a;
  --radius-md: 12px;
  --font-sans: 'Inter', system-ui, sans-serif;
}

Dark mode? Already wired — every color token has a .dark companion. Toggle a class on <html> and you're done.

.dark {
  --color-bg: #0b0b0f;
  --color-fg: #f4f4f5;
  /* …everything else cascades */
}

No SASS variables. No JS theme provider. No runtime patching. Just CSS, the way the platform meant it.


🛡️ The dual-compat guarantee

Every component compiles cleanly on both runtimes — enforced by a strict authoring contract:

  • ✅ Pure Options API — no <script setup>, no setup(), no Composition API imports
  • ✅ Single root template (Vue 2 has no fragments)
  • ✅ emits always declared (Vue 3 needs it for $attrs separation)
  • ✅ No Vue-3-only features (<Teleport>, <Suspense>, multi v-model)
  • ✅ No Vue-2-only features (filters, .native, $listeners)

And every commit runs through four parallel build lanes:

Runtime Bundler What it catches
🟢 Vue 3.4 Vite + @vitejs/plugin-vue Modern compile errors, fragment leaks
🟣 Vue 2.7 webpack 4 + vue-template-compiler Legacy compile errors, banned APIs
🟡 Vue 3.2 Storybook 6.5 Story-side regressions
🧪 Both Vitest × 2 lanes Runtime + behavior parity

If a PR doesn't build on either side, it doesn't ship. Period.


🏗️ Why ship raw SFC?

Most Vue libraries publish pre-compiled .js artifacts targeting one Vue runtime. That's how the ecosystem ended up fragmented into -vue2 and -vue3 packages.

webcake-ui-kit publishes the source .vue files directly. Your app's bundler — Vite, webpack, whatever you use — compiles them against your Vue version. One source, two outputs, zero version lock-in.

The tradeoff: you need a bundler that handles .vue. (You already do.)

This is the entire reason the kit exists. Everything else — the components, the tokens, the Storybook — is downstream of that decision.


🚦 Compatibility

Version Status
Vue 2 2.7.x ✅ supported
Vue 3 3.0+ (tested on 3.4) ✅ supported
Bundlers Vite, webpack 4/5, Rollup, esbuild ✅
Node (consumer) any version your bundler supports ✅
Node (contributor) 14.x (Vue 2 sandbox uses webpack 4) ⚠️ pinned

🧪 Local development

npm run preview        # Vue 2 + Vue 3 dev servers side by side (HMR on both)
npm run test:build     # Compile-check everything (Vue 2, Vue 3, Storybook) — ~16s
npm test               # Unit suite on both runtimes, in parallel

Visit localhost:8001 (Vue 3) and localhost:8080 (Vue 2) side-by-side to spot dual-compat regressions in real time.

Full contributor workflow — including the 10-file checklist for adding a component — lives in CLAUDE.md.

Environment: Node 14 · Python ≤ 3.10 (the Vue 2 playground uses webpack 4 with native deps).


🌐 Resources

🌍 Docs & Storybook ui.webcake.io
📦 npm npmjs.com/package/webcake-ui-kit
🐙 GitHub pancake-vn/webcake-ui-kit
🐛 Issues Report a bug
💬 Discussions Ask a question

🤝 Contributing

PRs welcome — especially new components, accessibility fixes, and Vue 2/3 parity bug reports.

Before opening one:

  1. Read CLAUDE.md — it documents the dual-compat rules and the 10-file checklist for adding a component.
  2. Run npm run test:build && npm test — both must pass on Vue 2 and Vue 3 lanes.
  3. Add a Storybook story and a unit spec. New components without both are not accepted.

📜 License

MIT © Webcake Team — use it, fork it, ship it.


Related Packages

yn-components

Advanced and highly reusable Mobile UI Components built on Vue2 & You can define...

3,128 6
vue-login-test

Componete vue kt

708
tinymce-vue-2

A vue 2 component for TinyMCE

27,768 48
@zeit-ui/vue

A popular UI framework for Vue

4,030 704
@fect-ui/vue

Minimalist UI components built on Vue

3,280 330

Version History

Version Released License
1.3.23 MIT
1.3.22 MIT
1.3.21 MIT
1.3.20 MIT
1.3.19 MIT