Skip to content
Vimputer
Esc
↑↓navigate↵open⌘Jpreview
On this page

Architecture

The apps and packages, and the boundary between Electron main and the renderer.

Vimputer has two halves. The editor is where you build layers, bindings, and variables. The runtime receives Karabiner events and shows the HUD.

Apps and packages

Path Owns
apps/desktop Electron main, preload, renderer, plugin runtime, HUD
apps/browser-extension Chrome extension for tab and web-app commands
apps/macos-accessibility-helper Swift helper: menus, displays, windows, Accessibility permission
apps/docs This site
packages/schemas Zod contracts for config, actions, plugins, HUD, and RPC
packages/config Config store, defaults, and Karabiner import
packages/karabiner Generation into Karabiner profile JSON
packages/plugin-sdk The plugin authoring API
packages/integrations Node-safe discovery and parsing of local command sources
packages/shortcuts Re-exports the OpenKeymap SDK for semantic commands
packages/api The external automation API contract
packages/cli The vimputer command-line tool
packages/ui Shared renderer primitives

Code that speaks the product’s language stays in apps/desktop. A reusable primitive, contract, parser, or compiler step goes in a package.

Main and renderer

Electron main owns everything privileged: the filesystem, shell, Karabiner writes, the runtime socket, plugin execution, and the Accessibility helper. The renderer stays platform-agnostic and calls main over typed oRPC through preload and a message port.

State Lives in
Data from main TanStack Query
The working copy of the config The renderer store, autosaved
Shareable view state (?view=, ?binding=) TanStack Router search params
Everything transient Component state

App hotkeys go through @tanstack/react-hotkeys. Keep preload thin and main’s procedures narrow.