@kadal/deck-vue
| Install | |
|---|---|
npm install @kadal/deck-vue |
|
| Latest Version: | 0.4.5 |
| Vue: | 3 |
| License: | AGPL-3.0-or-later |
| Last Updated: | Oct 23, 2026 |
| Links: | GitHub · npm |
@kadal/deck-vue
The Vue renderer for Kadal Deck, presentations written in MDX: Vue code as an island on a slide, loaded only when its slide appears.
Vue islands guide · Islands in any framework · Docs · Source
npm install @kadal/deck-vue vue
Vue 3 components on a deck slide.
// once, where the deck is created
import { registerLazyRenderer } from "@kadal/deck";
registerLazyRenderer("vue", () => import("@kadal/deck-vue").then((m) => m.vueRenderer));
<Island
framework="vue"
load={() => import("./chart.ts").then((m) => m.Chart)}
props={{ data }}
client="slide"
/>
Registered by name and loaded on arrival, neither Vue's runtime nor the component is in the deck's first chunk — measured at 64 kB off the showcase deck's opening load, which matters once a deck can reach for ten frameworks and uses one.
A component written as options is recognised on its own. A functional Vue component is a plain function, indistinguishable from a React or Solid one, so it has to say so:
import { deckVue } from "@kadal/deck-vue";
export const Chart = deckVue((props) => h("div", props.label));
or framework="vue" on the island, which the example above already does.
What it does with props
createApp(Component, props) takes its props once; handing it new ones later does nothing. So the
app is mounted around a reactive bag the render function reads, and new props mutate that bag in
place. The island is re-rendered, not rebuilt — a chart keeps its animation, a half-typed form keeps
what you typed. Without this the renderer would have to remount on every click of the slide.
What it does not do
No ssr. It would pull @vue/server-renderer into every deck with a Vue island, and the deck's
print and export paths run a real browser, where islands hydrate like anywhere else. It goes in when
a surface appears that genuinely cannot run JS.
No live cross-framework children. children arrive as HTML and go in as the default slot's
markup. A React subtree cannot keep its state inside a Vue component, and pretending otherwise
produces bugs nobody can explain. Interactivity inside an island belongs to that island.
No .vue files yet. A single-file component needs @vitejs/plugin-vue in the deck's Vite
config; the renderer handles what that plugin produces (it looks for __vccOpts and __file), but
wiring the plugin into the deck's own Vite plugin is still to do.
Licence
AGPL-3.0-or-later, with a commercial licence available — the same terms as the engine. See LICENSING.md.
Related Packages
Fast, Lightweight Vue Carousel With Touch, Mouse, Keyboard, Wheel & SSR support
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.4.5 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.4.4 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.4.3 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.4.2 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.4.1 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.4.0 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.6 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.5 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.4 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.3 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.2 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.1 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.3.0 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.2.2 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.2.1 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.2.0 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.1.1 | ^3.5.0 | AGPL-3.0-or-later | |
| 0.1.0 | ^3.5.0 | AGPL-3.0-or-later |
Pre-releases (1)
| Version | Released | License |
|---|---|---|
| 0.0.0-stage |