npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kiwiproject/vue-desktop

v1.0.1

Published

A Vue 3 + TypeScript desktop-style window manager library (plugin-based).

Downloads

4

Readme

Vue Desktop

CI npm version License: MIT

A lightweight Vue 3 + TypeScript desktop-style window manager library with a plugin-based architecture.

Features

  • Draggable & Resizable Windows — Move windows by title bar, resize from any edge or corner
  • Window States — Minimize, maximize, restore with smooth transitions
  • Focus Management — Click-to-focus, z-order stacking, Alt+Tab window switching
  • Plugin Architecture — Extend functionality without bloating core
  • Session Persistence — Save and restore window state across page reloads
  • Keyboard Shortcuts — Configurable global shortcuts
  • Window Snapping — Snap to edges, other windows, and grid
  • Start Menu & Spotlight — Quick app launching and search

Installation

npm install @kiwiproject/vue-desktop
# or
pnpm add @kiwiproject/vue-desktop

Quick Start

<template>
  <div class="desktop-container">
    <WindowHost />
    <UISlot name="taskbar" />
  </div>
</template>

<script setup lang="ts">
import { defineComponent, h } from 'vue'
import {
  createDesktop,
  provideDesktop,
  WindowHost,
  UISlot,
  TaskbarPlugin
} from '@kiwiproject/vue-desktop'
import '@kiwiproject/vue-desktop/styles.css'

// Create a simple window component
const MyWindow = defineComponent({
  props: { message: String },
  setup(props) {
    return () => h('div', props.message)
  }
})

// Create desktop instance
const desktop = createDesktop()

// Install plugins
desktop.installPlugin(TaskbarPlugin)

// Provide to child components
provideDesktop(desktop)

// Create a window
desktop.createWindow({
  type: 'my-window',
  title: 'Hello World',
  component: MyWindow,
  props: { message: 'Welcome!' },
  initialBounds: { x: 100, y: 100, width: 400, height: 300 }
})
</script>

<style>
.desktop-container {
  width: 100vw;
  height: 100vh;
  position: relative;
}
</style>

Core API

createDesktop()

Creates a new desktop instance that manages windows and plugins.

import { createDesktop } from '@kiwiproject/vue-desktop'

const desktop = createDesktop()

provideDesktop(desktop) / useDesktop()

Vue provide/inject pattern for accessing the desktop instance in child components.

// In parent component
provideDesktop(desktop)

// In child component
const desktop = useDesktop()

Desktop Instance Methods

// Window management
desktop.createWindow(definition)     // Create a new window
desktop.closeWindow(id)              // Close a window
desktop.getWindow(id)                // Get window by ID
desktop.windows                      // Array of all windows

// Focus management
desktop.focusWindow(id)              // Focus a window
desktop.getFocusedWindowId()         // Get focused window ID
desktop.cycleFocus(reverse?)         // Cycle through windows

// Window modes
desktop.minimizeWindow(id)           // Minimize
desktop.maximizeWindow(id)           // Maximize
desktop.restoreWindow(id)            // Restore from min/max
desktop.getMode(id)                  // Get current mode

// Bounds
desktop.getBounds(id)                // Get window bounds
desktop.updateBounds(id, bounds)     // Update window bounds

// Plugins
desktop.installPlugin(plugin)        // Install a plugin
desktop.uninstallPlugin(name)        // Uninstall a plugin
desktop.hasPlugin(name)              // Check if plugin installed

// UI Registry
desktop.registerUI(registration)     // Register UI component
desktop.unregisterUI(id)             // Unregister UI component
desktop.getUIForSlot(slot)           // Get UIs for a slot

// Events
desktop.on(event, handler)           // Subscribe to events
desktop.off(event, handler)          // Unsubscribe from events
desktop.emit(event, payload)         // Emit an event

Window Definition

interface WindowDefinition {
  id?: string                        // Auto-generated if not provided
  type: string                       // Window type identifier
  title: string                      // Window title
  component: Component               // Vue component to render
  props?: Record<string, any>        // Props for the component
  icon?: string                      // Icon (emoji or URL)
  singletonKey?: string              // Unique key for singleton windows
  initialBounds?: Partial<Bounds>    // Initial position and size
  constraints?: WindowConstraints    // Min/max size constraints
  behaviors?: WindowBehaviors        // Draggable, resizable, etc.
  meta?: Record<string, any>         // Custom metadata
}

interface Bounds {
  x: number
  y: number
  width: number
  height: number
}

interface WindowConstraints {
  minWidth?: number
  minHeight?: number
  maxWidth?: number
  maxHeight?: number
}

interface WindowBehaviors {
  draggable?: boolean    // Default: true
  resizable?: boolean    // Default: true
  closable?: boolean     // Default: true
  minimizable?: boolean  // Default: true
  maximizable?: boolean  // Default: true
}

Components

<WindowHost />

Renders all windows managed by the desktop instance. Place this inside your desktop container.

<template>
  <div class="desktop">
    <WindowHost />
  </div>
</template>

<UISlot name="slot-name" />

Renders UI components registered to a specific slot by plugins.

<template>
  <div class="desktop">
    <WindowHost />
    <UISlot name="taskbar" />
    <UISlot name="overlay" />
  </div>
</template>

Plugins

TaskbarPlugin

Displays a taskbar showing all open windows with click-to-focus/minimize behavior.

import { TaskbarPlugin } from '@kiwiproject/vue-desktop'

desktop.installPlugin(TaskbarPlugin)

The taskbar automatically appears at the bottom of the desktop. Requires <UISlot name="taskbar" />.

ShortcutsPlugin

Provides global keyboard shortcuts.

import { createShortcutsPlugin } from '@kiwiproject/vue-desktop'

// With default shortcuts
desktop.installPlugin(createShortcutsPlugin())

// Or customize
desktop.installPlugin(createShortcutsPlugin({
  defaults: false  // Disable default shortcuts
}))

// Register custom shortcuts
desktop.shortcuts.register({
  id: 'my-shortcut',
  keys: 'ctrl+shift+n',
  description: 'Create new window',
  handler: (desktop) => {
    desktop.createWindow({ /* ... */ })
  }
})

Default shortcuts:

  • Ctrl+W — Close focused window
  • Ctrl+M — Minimize focused window
  • Ctrl+Shift+F — Toggle maximize

API:

desktop.shortcuts.register(definition)   // Register shortcut
desktop.shortcuts.unregister(id)         // Unregister shortcut
desktop.shortcuts.setEnabled(id, bool)   // Enable/disable
desktop.shortcuts.getShortcuts()         // List all shortcuts

SnapPlugin

Enables window snapping to edges, other windows, and grid.

import { createSnapPlugin } from '@kiwiproject/vue-desktop'

desktop.installPlugin(createSnapPlugin({
  edges: true,           // Snap to viewport edges
  windows: true,         // Snap to other windows
  grid: 20,              // Snap to 20px grid (0 to disable)
  threshold: 10,         // Snap distance in pixels
  getViewport: () => ({  // Custom viewport bounds
    x: 0, y: 0,
    width: window.innerWidth,
    height: window.innerHeight - 48  // Account for taskbar
  })
}))

API:

desktop.snap.setEnabled(bool)     // Enable/disable snapping
desktop.snap.isEnabled()          // Check if enabled
desktop.snap.setOptions(options)  // Update options
desktop.snap.getOptions()         // Get current options

PersistencePlugin

Saves and restores window state to localStorage (or custom storage).

import { createPersistencePlugin } from '@kiwiproject/vue-desktop'

desktop.installPlugin(createPersistencePlugin({
  storageKey: 'my-app-desktop',
  debounceMs: 500,           // Debounce saves
  persistSession: true,      // Save open windows for restore
  windowFactory: (info) => { // Factory for restoring windows
    return {
      type: info.type,
      title: info.title,
      component: getComponentByType(info.type),
      props: info.props
    }
  }
}))

// Restore session on app start
onMounted(() => {
  desktop.persistence.restoreSession()
})

API:

desktop.persistence.save()              // Force save
desktop.persistence.load()              // Load state
desktop.persistence.clear()             // Clear saved state
desktop.persistence.restoreSession()    // Restore windows
desktop.persistence.getWindowState(id)  // Get specific window state
desktop.persistence.setEnabled(bool)    // Enable/disable
desktop.persistence.isEnabled()         // Check if enabled

Custom Storage Adapter:

import { createPersistencePlugin, createChainedAdapter } from '@kiwiproject/vue-desktop'

// Chain multiple adapters (first successful load wins, all get saves)
const adapter = createChainedAdapter(
  myServerAdapter,
  createLocalStorageAdapter('fallback-key')
)

desktop.installPlugin(createPersistencePlugin({
  adapter
}))

StartMenuPlugin

Adds a Start menu button to the taskbar for launching apps.

import { createStartMenuPlugin } from '@kiwiproject/vue-desktop'

desktop.installPlugin(createStartMenuPlugin({
  buttonLabel: 'Start',
  buttonIcon: '🪟',
  apps: [
    {
      id: 'notepad',
      label: 'Notepad',
      icon: '📝',
      category: 'Utilities',
      shortcut: 'Ctrl+N',
      factory: () => ({
        type: 'notepad',
        title: 'Notepad',
        component: NotepadComponent,
        singletonKey: 'notepad'  // Only one instance
      })
    }
  ]
}))

API:

desktop.startMenu.registerApp(app)       // Register app
desktop.startMenu.unregisterApp(id)      // Unregister app
desktop.startMenu.getApps()              // Get all apps
desktop.startMenu.getAppsByCategory()    // Get apps grouped by category
desktop.startMenu.open()                 // Open menu
desktop.startMenu.close()                // Close menu
desktop.startMenu.toggle()               // Toggle menu
desktop.startMenu.isOpen()               // Check if open

SpotlightPlugin

Adds a Spotlight-style search dialog (Cmd/Ctrl+K).

import { createSpotlightPlugin } from '@kiwiproject/vue-desktop'

desktop.installPlugin(createSpotlightPlugin({
  placeholder: 'Search apps and windows...',
  maxResults: 10
}))

Requires <UISlot name="overlay" /> in your template.

Built-in providers:

  • Apps from StartMenu plugin
  • Open windows

Custom providers:

desktop.spotlight.registerProvider({
  id: 'my-provider',
  getItems: () => [
    {
      id: 'action-1',
      label: 'Do Something',
      icon: '⚡',
      category: 'Actions',
      description: 'Performs an action',
      keywords: ['action', 'do'],
      action: () => { /* ... */ }
    }
  ]
})

API:

desktop.spotlight.open()                    // Open spotlight
desktop.spotlight.close()                   // Close spotlight
desktop.spotlight.toggle()                  // Toggle spotlight
desktop.spotlight.isOpen()                  // Check if open
desktop.spotlight.search(query)             // Programmatic search
desktop.spotlight.registerProvider(p)       // Add custom provider
desktop.spotlight.unregisterProvider(id)    // Remove provider
desktop.spotlight.getProviders()            // List providers

Creating Custom Plugins

Plugins are objects with a name and install function:

import type { Plugin, DesktopInstance } from '@kiwiproject/vue-desktop'

const MyPlugin: Plugin = {
  name: 'my-plugin',
  install(desktop: DesktopInstance) {
    // Subscribe to events
    desktop.on('window:created', (win) => {
      console.log('Window created:', win.title)
    })

    // Register UI components
    const unregisterUI = desktop.registerUI({
      id: 'my-status-bar',
      slot: 'overlay',
      component: MyStatusBar,
      order: 100
    })

    // Attach API to desktop instance
    ;(desktop as any).myPlugin = {
      doSomething() { /* ... */ }
    }

    // Return cleanup function
    return () => {
      unregisterUI()
      delete (desktop as any).myPlugin
    }
  }
}

// Usage
desktop.installPlugin(MyPlugin)

Available events:

  • window:created — Window created
  • window:closed — Window closed
  • window:focused — Window focused
  • window:blurred — Window lost focus
  • window:moved — Window position changed
  • window:resized — Window size changed
  • window:minimized — Window minimized
  • window:maximized — Window maximized
  • window:restored — Window restored

Keyboard Shortcuts Reference

| Shortcut | Action | |----------|--------| | Cmd/Ctrl + K | Open Spotlight search | | Alt + Tab | Switch between windows | | Ctrl + W | Close focused window | | Ctrl + M | Minimize focused window | | Ctrl + Shift + F | Toggle maximize | | Escape | Close dialogs |

Styling

Import the default styles:

import '@kiwiproject/vue-desktop/styles.css'

All classes are prefixed with vd- for easy customization:

  • .vd-window-shell — Window container
  • .vd-window-header — Title bar
  • .vd-window-body — Content area
  • .vd-window-focused — Focused window state
  • .vd-taskbar — Taskbar container
  • .vd-spotlight-overlay — Spotlight backdrop

TypeScript

Full TypeScript support with exported types:

import type {
  // Core
  Bounds,
  WindowDefinition,
  WindowConstraints,
  WindowBehaviors,
  WindowMode,
  Plugin,
  UIRegistration,

  // Plugins
  ShortcutDefinition,
  SnapOptions,
  StorageAdapter,
  PersistedState,
  StartMenuApp,
  SpotlightItem,
  SpotlightProvider,

  // Extended desktop types
  DesktopInstanceWithShortcuts,
  DesktopInstanceWithSnap,
  DesktopInstanceWithPersistence,
  DesktopInstanceWithStartMenu,
  DesktopInstanceWithSpotlight
} from '@kiwiproject/vue-desktop'

Development

# Install dependencies
pnpm install

# Run demo
pnpm --filter ./examples/demo dev

# Run tests
pnpm test

# Build library
pnpm build

# Lint
pnpm lint

License

MIT