Ziewziew

Plugins

Native capabilities for desktop apps. Enable at build time.

How Plugins Work

Plugins are configured in your project's ziew.zon file and compiled at build time.

# Add plugins to your project
ziew plugin add sqlite notify hotkeys

# List available plugins
ziew plugin list

# Build (plugins are loaded from ziew.zon)
ziew build

Only enabled plugins add size to your binary. The base app stays tiny.

Core Plugins

Essential features for desktop applications.

sqlite

Plugin

Embedded SQLite database. Perfect for local storage, caching, and offline-first apps.

Requires:libsqlite3-dev
// Open database
const db = await ziew.sqlite.open('./app.db');

// Create table
await db.exec(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE
  )
`);

// Insert data
await db.exec("INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')");

// Query with parameters
const users = await db.query("SELECT * FROM users WHERE name LIKE ?", ['%ali%']);

// Close when done
db.close();

notify

Plugin

Native system notifications. Supports icons and custom actions.

Requires:libnotify-dev (Linux)
// Simple notification
await ziew.notify.send('Download Complete', 'Your file has been saved.');

// With options
await ziew.notify.send('New Message', 'You have 3 unread messages', {
  icon: 'mail',
  urgency: 'normal'  // 'low', 'normal', 'critical'
});

keychain

Plugin

Secure credential storage using the system keychain. Never store passwords in plain text.

Requires:libsecret-1-dev (Linux)
// Store a secret
await ziew.keychain.set('api_key', 'sk-secret-key-here');

// Retrieve it later
const apiKey = await ziew.keychain.get('api_key');

// Delete when no longer needed
await ziew.keychain.delete('api_key');

tray

Built-in

System tray icon with context menu. Keep your app running in the background.

// Create tray icon
await ziew.tray.create({
  icon: './icon.png',
  tooltip: 'My App',
  menu: [
    { label: 'Show Window', onClick: () => ziew.window.show() },
    { label: 'Settings', onClick: openSettings },
    { type: 'separator' },
    { label: 'Quit', onClick: () => ziew.quit() }
  ]
});

// Update icon dynamically
await ziew.tray.setIcon('./icon-active.png');

menu

Built-in

Native application and context menus with keyboard shortcuts.

// Application menu bar
await ziew.menu.setAppMenu([
  {
    label: 'File',
    submenu: [
      { label: 'New', accelerator: 'Ctrl+N', onClick: newFile },
      { label: 'Open', accelerator: 'Ctrl+O', onClick: openFile },
      { type: 'separator' },
      { label: 'Exit', onClick: () => ziew.quit() }
    ]
  },
  {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'Ctrl+Z', onClick: undo },
      { label: 'Redo', accelerator: 'Ctrl+Y', onClick: redo }
    ]
  }
]);

// Context menu on right-click
element.addEventListener('contextmenu', async (e) => {
  e.preventDefault();
  await ziew.menu.popup([
    { label: 'Copy', onClick: copy },
    { label: 'Paste', onClick: paste }
  ], e.clientX, e.clientY);
});

single-instance

Built-in

Ensure only one instance of your app runs at a time. Focus existing window on re-launch.

// In your app initialization
const isFirst = await ziew.singleInstance.acquire('com.mycompany.myapp');

if (!isFirst) {
  // Another instance is running - it will be focused
  ziew.quit();
  return;
}

// Listen for second instance attempts
ziew.singleInstance.onSecondInstance(() => {
  ziew.window.focus();
});

Input Plugins

Hardware input beyond keyboard and mouse.

hotkeys

Plugin

Global keyboard shortcuts that work even when your app is in the background.

Requires:libx11-dev (Linux)
// Register global hotkey
const id = await ziew.hotkeys.register('Ctrl+Shift+Space', () => {
  ziew.window.show();
  ziew.window.focus();
});

// Unregister when done
await ziew.hotkeys.unregister(id);

// Common patterns
await ziew.hotkeys.register('Ctrl+Shift+V', pasteFromClipboard);
await ziew.hotkeys.register('Alt+Space', showQuickLauncher);
await ziew.hotkeys.register('PrintScreen', captureScreen);

gamepad

Plugin

Game controller input for games and accessible applications.

Requires:No dependencies (uses evdev on Linux)
// Initialize gamepad support
await ziew.gamepad.init();

// Check connected controllers
const count = ziew.gamepad.getConnectedCount();
console.log(`${count} gamepad(s) connected`);

// Poll state in game loop
function update() {
  const state = ziew.gamepad.getState(0);  // First gamepad

  if (state.connected) {
    // Buttons
    if (state.isPressed('a')) jump();
    if (state.isPressed('b')) attack();
    if (state.isPressed('start')) pauseGame();

    // Analog sticks (-1.0 to 1.0)
    player.vx = state.getAxis('left_x') * speed;
    player.vy = state.getAxis('left_y') * speed;

    // Triggers (0.0 to 1.0)
    const accel = state.getAxis('right_trigger');
  }

  requestAnimationFrame(update);
}
update();

serial

Plugin

Serial port communication for Arduino, microcontrollers, and hardware projects.

Requires:No dependencies (uses POSIX termios)
// List available ports
const ports = await ziew.serial.listPorts();
// [{ path: '/dev/ttyUSB0', name: 'USB Serial' }, ...]

// Open port
const port = await ziew.serial.open('/dev/ttyUSB0', {
  baudRate: 9600,
  dataBits: 8,
  parity: 'none',
  stopBits: 1
});

// Send data
await port.write('Hello Arduino!');

// Read data
const data = await port.read(64);  // Read up to 64 bytes

// Close when done
port.close();

AI Plugins

Local AI inference - no cloud APIs required.

ai (llama.cpp)

Plugin

Local LLM inference via llama.cpp. Text generation, chat, and embeddings.

Requires:llama.cpp installed system-wide
// Simple completion
const response = await ziew.ai.complete('Explain quantum computing briefly');

// Streaming response
for await (const token of ziew.ai.stream('Write a haiku about coding')) {
  output.textContent += token;
}

// Chat completion
const messages = [
  { role: 'system', content: 'You are a helpful assistant.' },
  { role: 'user', content: 'What is the capital of France?' }
];
const reply = await ziew.ai.chat(messages);

whisper (whisper.cpp)

Plugin

Speech-to-text transcription. Works offline with local models.

Requires:whisper.cpp installed in ~/.ziew/
// Transcribe audio file
const text = await ziew.whisper.transcribe('./recording.wav');

// Real-time transcription from microphone
const stream = await ziew.whisper.startStream();
stream.onResult((text) => {
  transcript.textContent = text;
});

// Stop streaming
await stream.stop();

piper (TTS)

Plugin

Text-to-speech synthesis. Fast, offline, multiple voices.

Requires:Piper CLI installed
// Speak text
await ziew.piper.speak('Hello, welcome to the application!');

// With options
await ziew.piper.speak('Important alert!', {
  voice: 'en_US-lessac-medium',
  speed: 1.2
});

Building with Plugins

Dependencies by Platform

Ubuntu/Debian
# Core dependencies (always needed)
sudo apt install libgtk-3-dev libwebkit2gtk-4.1-dev

# Plugin dependencies
sudo apt install libsqlite3-dev    # sqlite plugin
sudo apt install libnotify-dev     # notify plugin
sudo apt install libsecret-1-dev   # keychain plugin
sudo apt install libx11-dev        # hotkeys plugin

Build Examples

# Add plugins for different use cases
ziew plugin add sqlite notify             # App with database and notifications
ziew plugin add sqlite notify keychain hotkeys ai whisper  # Full-featured app
ziew plugin add gamepad                   # Game with controller support
ziew plugin add serial                    # Hardware project

# Build (reads plugins from ziew.zon)
ziew build

# Build optimized for release
ziew build --release

Binary Size Impact

Base app (no plugins)~220 KB
+ sqlite+50 KB
+ notify+5 KB
+ keychain+10 KB
+ hotkeys+8 KB
+ gamepad+12 KB
+ serial+6 KB
All plugins~310 KB

Compare: Electron hello world is 150+ MB. Ziew with ALL plugins is still under 400 KB.