Bootc Extension Development Guide
Extension Lifecycle
Entry Point (packages/backend/src/extension.ts)
activate() runs when Podman Desktop loads the extension. deactivate() cleans
up. Read the file to see the current initialization sequence:
cat packages/backend/src/extension.ts
Architecture
Three packages in packages/:
- Frontend (
packages/frontend/) — Svelte 5 webview UI. Root component:src/App.svelte. Reactive stores insrc/stores/. Builds into../backend/media/. - Shared (
packages/shared/) — Typed API contract (src/BootcAPI.ts), data models (src/models/), and notification messages (src/messages/Messages.ts). Both frontend and backend depend on this package. - Backend (
packages/backend/) — Node.js extension host. Entry:src/extension.ts. Implements the shared API contract insrc/api-impl.ts(BootcApiImpl). Uses@podman-desktop/apifor Podman Desktop integration.
Data flow: Frontend calls bootcClient.method() → RPC MessageProxy serializes the call over webview postMessage → Backend BootcApiImpl handles it and returns the result back through the same channel. Backend pushes notifications to the frontend via Messages enum events.
For detailed UI patterns, see the svelte-ui-design skill. For detailed backend API patterns, see the backend-api skill.
RPC Communication
Frontend ↔ Backend uses a typed RPC proxy over webview postMessage:
- Contract:
packages/shared/src/BootcAPI.ts— abstract class defining every method the frontend can call - Implementation:
packages/backend/src/api-impl.ts—BootcApiImplextends the contract with real logic - Client:
packages/frontend/src/api/client.ts— hand-written file that creates a typed proxy at runtime viarpcBrowser.getProxy<BootcApi>(BootcApi). Any method added to the abstract contract is automatically available onbootcClientwithout modifying this file. - Notifications:
Messagesenum inpackages/shared/src/messages/Messages.ts— backend-to-frontend push events
See the backend-api skill for detailed RPC patterns and examples.
Adding a New Feature (End-to-End)
- Define API — Add abstract method to
packages/shared/src/BootcAPI.ts - Implement — Add implementation to
packages/backend/src/api-impl.ts(see backend-api skill) - Call from frontend — Use
bootcClient.myNewMethod()from/@/api/client(auto-proxied) - Add route — Add
<Route>inApp.svelte, navigation inNavigation.svelte - Add models — Define types in
packages/shared/src/models/if needed - Build UI — See svelte-ui-design skill for layout and component patterns
Build System
Vite Configuration
Backend (packages/backend/vite.config.js):
- Library mode, CJS output →
dist/extension.js - Externals:
@podman-desktop/api,ssh2, Node.js builtins - Aliases:
/@/→src/,/@shared/→../../shared/
Frontend (packages/frontend/vite.config.js):
- Svelte + Tailwind CSS plugins
- Output →
../backend/media/ - Aliases:
/@/→src/,/@shared/→../../shared/
Development Watch
pnpm watch # Watches all packages concurrently
Frontend changes rebuild into packages/backend/media/, which Podman Desktop
picks up when using --extension-folder.
Extension Points (package.json)
Extension Points
Configuration properties, menu contributions, commands, icons, and views are
all defined in package.json under contributes. Read it for the current state:
# See all extension points (configuration, menus, commands, views, icons)
cat packages/backend/package.json | grep -A 200 '"contributes"'
Telemetry
Telemetry example:
telemetryLogger.logUsage('buildDiskImage', { type: 'qcow2', arch: 'arm64' });
telemetryLogger.logError('buildFailed', { error: errorMessage });
Source: podman-desktop/extension-bootc — distributed by TomeVault.