Volt LogoVolt
Plugin Development

Plugin Development

Learn how to create plugins to extend Volt's functionality

Plugin Development Guide

Build powerful extensions for Volt

Create plugins that integrate seamlessly with Volt's lightning-fast architecture.

Welcome to the Volt plugin development guide! This guide will help you create your own plugins to extend Volt's capabilities.

Plugin Architecture

Volt features a hybrid plugin system with two layers:

🎨 Frontend Plugins

TypeScript/React - Handle UI and interactions. Perfect for calculators, web searches, shortcuts.

⚙️ Backend Plugins

Rust - Handle system integrations. Perfect for game scanners, system monitors, cloud integrations.

Frontend Plugins (TypeScript/React)

  • Handle UI and interactions
  • Perfect for: calculators, web searches, shortcuts
  • Executed in the application context
  • 500ms timeout per request
Example Frontend Plugin
class MyPlugin implements Plugin {
  id = 'my-plugin';
  name = 'My Plugin';
  enabled = true;

  canHandle(context: PluginContext): boolean {
    return context.query.startsWith('my ');
  }

  async match(context: PluginContext): Promise<PluginResult[]> {
    return [{ id: '1', title: 'Result', type: PluginResultType.Info }];
  }
}

Backend Plugins (Rust)

  • Handle system integrations
  • Perfect for: game scanners, system monitors, cloud integrations
  • Full access to file system and system APIs
  • Native performance
Example Backend Plugin
pub struct MyBackendPlugin;

impl VoltPluginAPI for MyBackendPlugin {
    fn name(&self) -> &str { "my-backend-plugin" }
    fn version(&self) -> &str { "1.0.0" }
}

Architecture Diagram

┌─────────────────────────────────────────────┐
│          Frontend (React/TypeScript)        │
│  ┌────────────────────────────────────┐    │
│  │      Plugin Registry               │    │
│  │  • Manages all plugins             │    │
│  │  • Routes queries                  │    │
│  │  • Handles timeouts                │    │
│  └────────────────────────────────────┘    │
│              ↓                              │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐   │
│  │ Plugin  │  │ Plugin  │  │ Plugin  │   │
│  │   A     │  │   B     │  │   C     │   │
│  └─────────┘  └─────────┘  └─────────┘   │
└─────────────────────────────────────────────┘
               ↕ Tauri IPC
┌─────────────────────────────────────────────┐
│           Backend (Rust/Tauri)              │
│  ┌────────────────────────────────────┐    │
│  │      Plugin API (VoltPluginAPI)    │    │
│  │  • File system access             │    │
│  │  • Configuration management       │    │
│  │  • System integrations            │    │
│  └────────────────────────────────────┘    │
└─────────────────────────────────────────────┘

Plugin Types

Frontend plugins can return different types of results:

Prop

Type

Creating a Frontend Plugin

Create Plugin Structure

Set up your plugin directory:

index.ts
types.ts

Implement Plugin Interface

Create your plugin by implementing the Plugin interface:

index.ts
import {
  Plugin,
  PluginContext,
  PluginResult,
  PluginResultType,
} from "@/types/plugin";

class MyPlugin implements Plugin {
  id = "my-plugin";
  name = "My Plugin";
  description = "A custom Volt plugin";
  enabled = true;

  canHandle(context: PluginContext): boolean {
    return context.query.startsWith("my ");
  }

  async match(context: PluginContext): Promise<PluginResult[]> {
    const query = context.query.replace("my ", "");

    return [{
      id: "1",
      title: `Process: ${query}`,
      subtitle: "Press Enter to execute",
      icon: "🔧",
      type: PluginResultType.Info,
      action: () => console.log("Executed!"),
    }];
  }

  async execute(result: PluginResult): Promise<void> {
    if (result.action) await result.action();
  }
}

export default MyPlugin;

Register Your Plugin

Add your plugin to the registry:

plugin-registry.ts
import MyPlugin from "./my-plugin";

const plugins = [
  new MyPlugin(),
  // ... other plugins
];

Test Your Plugin

Launch Volt and type your trigger phrase to test!

Next Steps

Complete plugin example
class MyAwesomePlugin implements Plugin {
  id = "my-awesome-plugin";
  name = "My Awesome Plugin";
  description = "Does something awesome";
  enabled = true;

  canHandle(context: PluginContext): boolean {
    // Determine if this plugin should handle the query
    return context.query.startsWith("awesome");
  }

  async match(context: PluginContext): Promise<PluginResult[]> {
    // Generate results for the query
    return [
      {
        id: "1",
        title: "Awesome Result",
        subtitle: "This is awesome!",
        icon: "⚡",
        type: PluginResultType.Info,
        action: () => {
          console.log("Executing awesome action!");
        },
      },
    ];
  }

  async execute(result: PluginResult): Promise<void> {
    // Execute the selected result
    if (result.action) {
      await result.action();
    }
  }
}

export default MyAwesomePlugin;

Next Steps

On this page