Skip to content

Repository files navigation

Vue Summon logo

Vue Summon

Imperatively render Vue components from anywhere — dialogs, toasts, modals, without cluttering your templates.

npm version license

English | 简体中文

Features

  • Imperative API — call summon(Component, props) from event handlers, stores, routers — even outside component setup
  • Promise-based results — every summons returns a Promise; await the user's choice instead of wiring v-model and callbacks
  • Zero template clutter — no hidden dialog blocks in every page; one <SummonHost /> renders everything
  • Live prop updatescontroller.update() patches props reactively, perfect for progress bars, wizards and forms
  • Key-based dedupe — pass a key to guarantee a single instance; re-summoning returns the existing controller
  • Transitions built-in — instances are teleported to body and wrapped in <Transition>, removed safely after leave
  • Multi-manager isolationcreateSummonManager() scopes instances per feature, per test, or per micro-frontend
  • Fully typed — props and results are inferred from your component via vue-component-type-helpers

Installation

pnpm add vue-summon
# or
npm install vue-summon
# or
yarn add vue-summon

Vue Summon has a single peer dependency: vue@3.

Quick Start

1. Mount the host once, near your app root:

<!-- App.vue -->
<script setup lang="ts">
import { SummonHost } from 'vue-summon'
</script>

<template>
  <RouterView />
  <SummonHost />
</template>

2. Build a summoneable componentuseSummoned() gives it a controller:

<!-- ConfirmDialog.vue -->
<script setup lang="ts">
import { useSummoned } from 'vue-summon'

defineProps<{ title: string; message?: string }>()

const { resolve, dismiss } = useSummoned<boolean>()
</script>

<template>
  <div class="overlay" @click.self="dismiss()">
    <div class="dialog">
      <h3>{{ title }}</h3>
      <p v-if="message">{{ message }}</p>
      <button @click="resolve(false)">Cancel</button>
      <button @click="resolve(true)">Confirm</button>
    </div>
  </div>
</template>

3. Summon it from any component, store, or plain module:

import { summon, SummonDismissedError } from 'vue-summon'
import ConfirmDialog from './ConfirmDialog.vue'

try {
  const confirmed = await summon(ConfirmDialog, { title: 'Delete this file?' })
  if (confirmed) {
    await deleteFile()
  }
} catch (error) {
  if (error instanceof SummonDismissedError) {
    // user closed the dialog without choosing
  }
}

That is the whole mental model: summon a component, await its answer.

AI Agent Skill

This repository ships an Agent Skill (skills/vue-summon) that teaches AI coding agents — Claude Code, OpenCode, Codex, Cursor and 70+ more — how to integrate and use Vue Summon correctly in your project.

Install it with the skills CLI:

npx skills add litingyes/vue-summon

See the Agent Skill guide for options and details.

Documentation

Full documentation lives in ./docs (VitePress, English + 简体中文):

pnpm docs:dev

License

MIT

About

Imperatively render Vue components from anywhere — dialogs, toasts, modals, without cluttering your templates.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages