Volt LogoVolt
Extension Development

API Reference

Complete Volt Plugin API documentation

Plugin API Reference

Complete API documentation for Volt plugins.

VoltAPI - Global API

Essential for Extension Development

The window.VoltAPI object is the primary interface for extensions to interact with Volt. All utilities, types, and communication methods are accessed through this global object.

Extensions access Volt's features through the global window.VoltAPI object:

interface VoltAPI {
  // Plugin types and enums
  types: {
    PluginResultType: typeof PluginResultType;
  };

  // Utility functions
  utils: {
    fuzzyScore(query: string, target: string): number;
    copyToClipboard(text: string): Promise<boolean>;
    openUrl(url: string): Promise<void>;
    formatNumber(num: number): string;
  };

  // Tauri invoke (direct backend access)
  invoke: typeof invoke;

  // Event system
  events: {
    emit(event: string, detail?: unknown): void;
    on(event: string, handler: (detail: unknown) => void): () => void;
  };

  // Notifications
  notify(message: string, type?: "info" | "success" | "error"): void;
}

VoltAPI.types

Access to plugin type definitions:

// Get PluginResultType enum
const { PluginResultType } = window.VoltAPI.types;

// Use in your results
const result: PluginResult = {
  id: "1",
  type: PluginResultType.Info,
  title: "My Result",
  score: 100,
};

VoltAPI.utils

Utility functions available to all extensions:

Prop

Type

Example usage:

async execute(result: PluginResult): Promise<void> {
  const password = result.data?.password as string;

  // Copy to clipboard
  const success = await window.VoltAPI.utils.copyToClipboard(password);

  if (success) {
    window.VoltAPI.notify("Copied to clipboard!", "success");
  } else {
    window.VoltAPI.notify("Failed to copy", "error");
  }
}

VoltAPI.invoke

Direct access to Tauri backend commands:

// Call any Tauri command
const result = await window.VoltAPI.invoke("command_name", { param: "value" });

// Example: Get extension configuration
const config = await window.VoltAPI.invoke("get_plugin_config", {
  pluginId: "my-extension",
});

VoltAPI.events

Event system for communication:

// Emit an event
window.VoltAPI.events.emit("my-custom-event", { data: "value" });

// Subscribe to an event (returns unsubscribe function)
const unsubscribe = window.VoltAPI.events.on("some-event", (detail) => {
  console.log("Event received:", detail);
});

// Later: unsubscribe
unsubscribe();

Available events:

  • plugin-update - Fired when a plugin is updated
  • plugin-enabled - Fired when a plugin is enabled
  • plugin-disabled - Fired when a plugin is disabled
  • plugin-error - Fired when a plugin encounters an error

VoltAPI.notify

Display notifications to the user:

// Info notification (default)
window.VoltAPI.notify("Processing complete");

// Success notification
window.VoltAPI.notify("Password copied!", "success");

// Error notification
window.VoltAPI.notify("Failed to connect", "error");

Plugin Interface

The main interface that all plugins must implement:

interface Plugin {
  id: string;
  name: string;
  description: string;
  enabled: boolean;
  canHandle(context: PluginContext): boolean;
  match(context: PluginContext): Promise<PluginResult[]> | PluginResult[] | null;
  execute(result: PluginResult): Promise<void> | void;
}

Plugin Properties

Prop

Type

Plugin Methods

canHandle(context: PluginContext): boolean

Performance Critical

This method must be fast (target: <1ms). Use simple string checks, not complex parsing.

Determines if this plugin should handle the current query.

canHandle(context: PluginContext): boolean {
  const query = context.query.toLowerCase().trim();
  // Fast prefix check
  return query.startsWith('pass') || query.startsWith('password');
}

match(context: PluginContext): Promise<PluginResult[]> | PluginResult[] | null

Generates results for the query. Can be sync or async.

Timeout

This method has a 500ms timeout. If your plugin takes longer, it will be skipped.

async match(context: PluginContext): Promise<PluginResult[]> {
  const query = context.query.replace('pass ', '');
  const length = parseInt(query) || 16;
  const password = generatePassword(length);

  return [{
    id: 'password-1',
    type: window.VoltAPI.types.PluginResultType.Password,
    title: password,
    subtitle: `${length} characters - Press Enter to copy`,
    icon: '🔐',
    score: 100,
    data: { password }
  }];
}

execute(result: PluginResult): Promise<void> | void

Called when the user selects a result (presses Enter).

async execute(result: PluginResult): Promise<void> {
  const password = result.data?.password as string;
  await window.VoltAPI.utils.copyToClipboard(password);
  window.VoltAPI.notify("Password copied!", "success");
}

Types

PluginContext

Context information passed to plugin methods:

interface PluginContext {
  query: string; // User's search query
  settings?: Record<string, unknown>; // Plugin-specific settings
}

PluginResult

Result object returned by plugins:

interface PluginResult {
  id: string; // Unique result ID
  type: PluginResultType; // Result type (affects display)
  title: string; // Main display text
  subtitle?: string; // Secondary text
  icon?: string; // Emoji or icon path
  badge?: string; // Badge text (e.g., "Plugin")
  score: number; // Ranking score (0-100, higher = better)
  data?: Record<string, unknown>; // Custom data for execute()
  pluginId?: string; // Auto-added by registry
}

Scoring Guidelines:

Score RangeUsage
90-100Exact matches
70-89Strong matches (query is substring)
50-69Partial/fuzzy matches
< 50Weak matches

PluginResultType

Types of results plugins can return:

enum PluginResultType {
  Calculator = "calculator",
  WebSearch = "websearch",
  SystemCommand = "systemcommand",
  FileExplorer = "fileexplorer",
  Timer = "timer",
  SystemMonitor = "systemmonitor",
  Steam = "steam",
  Game = "game",
  Clipboard = "clipboard",
  Emoji = "emoji",
  Info = "info",
  Password = "password",
}

Extension Manifest

Every extension must have a manifest.json file at the root:

{
  "id": "password-generator",
  "name": "Password Generator",
  "version": "1.0.4",
  "description": "Generate cryptographically secure passwords",
  "author": {
    "name": "VoltLaunchr Community",
    "github": "VoltLaunchr",
    "email": "contact@volt.dev"
  },
  "main": "index.ts",
  "icon": "assets/icon.png",
  "category": "utilities",
  "keywords": ["password", "security", "generator"],
  "repository": "https://github.com/VoltLaunchr/volt-extensions",
  "license": "MIT",
  "minVoltVersion": "0.4.0",
  "permissions": ["clipboard"]
}

Manifest Fields

Prop

Type


Backend API (Rust)

For advanced system integrations, you can create Rust backend plugins.

VoltPluginAPI Trait

pub trait VoltPluginAPI {
    fn name(&self) -> &str;
    fn version(&self) -> &str;
    fn scan(&self) -> Result<Vec<PluginResult>, PluginError>;
    fn execute(&self, action: &str) -> Result<(), PluginError>;
}

Example Backend Plugin

use volt_plugin_api::{VoltPluginAPI, PluginResult, PluginError};

pub struct SteamPlugin;

impl VoltPluginAPI for SteamPlugin {
    fn name(&self) -> &str {
        "Steam Games"
    }

    fn version(&self) -> &str {
        "1.0.0"
    }

    fn scan(&self) -> Result<Vec<PluginResult>, PluginError> {
        // Scan Steam library for installed games
        let games = scan_steam_library()?;

        Ok(games.into_iter().map(|game| PluginResult {
            id: game.app_id.to_string(),
            title: game.name,
            subtitle: Some("Steam Game".to_string()),
            icon: Some(game.icon_path),
            result_type: String::from("game"),
        }).collect())
    }

    fn execute(&self, action: &str) -> Result<(), PluginError> {
        // Launch game via Steam
        std::process::Command::new("steam")
            .args(["steam://rungameid/", action])
            .spawn()?;
        Ok(())
    }
}

Tauri Commands

Available Tauri commands for extension management:

get_plugin_config(pluginId: string)

Get configuration for a specific plugin.

const config = await window.VoltAPI.invoke('get_plugin_config', {
  pluginId: 'my-plugin'
});

set_plugin_config(pluginId: string, config: any)

Save plugin configuration.

await window.VoltAPI.invoke('set_plugin_config', {
  pluginId: 'my-plugin',
  config: { enabled: true, apiKey: 'xxx' }
});

install_extension(extensionId: string, downloadUrl: string)

Install an extension from a URL.

uninstall_extension(extensionId: string)

Uninstall an extension.

toggle_extension(extensionId: string, enabled: boolean)

Enable or disable an extension.

get_installed_extensions()

Get list of all installed extensions.

get_extension_details(extensionId: string)

Get detailed information about an extension.

fetch_extension_registry(url: string)

Fetch the extension registry from a URL.

check_extension_updates()

Check for available updates for installed extensions.

update_extension(extensionId: string, downloadUrl: string)

Update an extension to a new version.


Complete Extension Example

Here's a complete, production-ready extension:

index.ts
// Password Generator Extension
// manifest.json: { "id": "password-generator", "main": "index.ts", ... }

interface Plugin {
  id: string;
  name: string;
  description: string;
  enabled: boolean;
  canHandle(context: PluginContext): boolean;
  match(context: PluginContext): Promise<PluginResult[]> | PluginResult[];
  execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
  query: string;
  settings?: Record<string, unknown>;
}

interface PluginResult {
  id: string;
  type: any;
  title: string;
  subtitle?: string;
  icon?: string;
  score: number;
  data?: Record<string, unknown>;
}

const TRIGGERS = ["pass", "password", "pwd"];

function generatePassword(length: number): string {
  const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
  const array = new Uint32Array(length);
  crypto.getRandomValues(array);
  return Array.from(array, (num) => charset[num % charset.length]).join("");
}

class PasswordGeneratorPlugin implements Plugin {
  id = "password-generator";
  name = "Password Generator";
  description = "Generate cryptographically secure passwords";
  enabled = true;

  canHandle(context: PluginContext): boolean {
    const query = context.query.toLowerCase().trim();
    return TRIGGERS.some((trigger) => query.startsWith(trigger));
  }

  match(context: PluginContext): PluginResult[] {
    const query = context.query.toLowerCase().trim();

    // Parse length from query (e.g., "pass 20" → 20)
    const parts = query.split(/\s+/);
    const lengthArg = parts.find((p) => /^\d+$/.test(p));
    const length = lengthArg ? parseInt(lengthArg, 10) : 16;

    // Clamp length to reasonable bounds
    const finalLength = Math.max(8, Math.min(128, length));
    const password = generatePassword(finalLength);

    const { PluginResultType } = window.VoltAPI.types;

    return [
      {
        id: "generated-password",
        type: PluginResultType.Password,
        title: password,
        subtitle: `${finalLength} characters - Press Enter to copy`,
        icon: "🔐",
        score: 100,
        data: { password },
      },
    ];
  }

  async execute(result: PluginResult): Promise<void> {
    const password = result.data?.password as string;

    if (password) {
      const success = await window.VoltAPI.utils.copyToClipboard(password);

      if (success) {
        window.VoltAPI.notify("Password copied to clipboard!", "success");
      } else {
        window.VoltAPI.notify("Failed to copy password", "error");
      }
    }
  }
}

export default PasswordGeneratorPlugin;

For more examples, check out the Plugin Examples section. For publishing your extension, see the Publishing Guide.

On this page