Extension Development Overview
The Bible Study app supports a rich extension platform that lets developers add new features, integrate external services, and customize the study experience. Extensions are distributed as self-contained packages with a JSON manifest and JavaScript entry point.
What extensions can do
Extensions have access to a comprehensive API organized into namespaces:
- Read Bible data -- query verses, chapters, ranges, and interlinear token data across any installed module
- Read study resources -- access commentaries, dictionaries, and book content
- Manage user data -- create and edit notes, highlights, and bookmarks (with user consent)
- Add UI panels -- contribute custom panes that appear alongside the built-in study tools
- Register commands -- add entries to the command palette with optional keyboard shortcuts
- Decorate verses -- overlay custom styling, annotations, or hover information on Bible text
- Provide content -- register as a Bible, commentary, dictionary, or book provider so your content appears as a first-class module
- Store data -- use a key-value store, OS keychain secrets, or a per-extension SQLite database
- Make network requests -- call external APIs through a host-mediated fetch with declared allowed hosts
- Run background tasks -- perform long-running work with progress reporting and cancellation
Architecture at a glance
┌─────────────────────────────────────────────┐
│ Main Process (Electron) │
│ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ Extension Host │──▶│ Permission Guard │ │
│ │ (RPC Router) │ └──────────────────┘ │
│ └──────┬────────┘ │
│ │ RPC (MessagePort) │
│ ┌──────▼─────────────────────┐ │
│ │ Utility Process │ ← one per │
│ │ ┌──────────────────────┐ │ extension │
│ │ │ QuickJS realm (WASM) │ │ │
│ │ │ your extension code │ │ │
│ │ └──────────────────────┘ │ │
│ └────────────────────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ Renderer │ │
│ │ ┌───────────┐ │ │
│ │ │ ext iframe │ │ ← sandboxed panel UI │
│ │ └───────────┘ │ ext-ui:// protocol │
│ └───────────────┘ │
└─────────────────────────────────────────────┘
Key design principles:
- Two rings of isolation -- Each extension gets its own utility process (an OS boundary: a crash or a hang is contained), and your code runs inside a QuickJS realm within it (a language boundary: the realm starts with no ambient authority and reaches only what it was handed).
- Curated API, zero ambient authority -- There is no
require, noprocess, nofetch, no filesystem. Theapiobject passed toactivate()is the complete set of things an extension can do. - Permission-gated API -- Extensions declare required permissions in their manifest. The user consents at install time. Every API call is checked in the main process, so there is nothing on the extension's side to tamper with.
- Sandboxed UI -- Extension panels render in iframes loaded via a custom
ext-ui://protocol with strict Content Security Policy headers and origin isolation. - RPC protocol -- Extension code communicates with the host through JSON-serializable RPC messages over a MessagePort.
See How Extensions Run for what this means in practice.
Next steps
| Resource | Description |
|---|---|
| Quick Start | Build and sideload your first extension in minutes |
| How Extensions Run | Read this before writing code -- the sandbox, available globals, resource limits |
| Packaging and Build | The one-bundle rule, CommonJS output, and the esbuild config |
| Manifest Reference | Complete schema for extension.json |
| Core Concepts | Deep dive into lifecycle, permissions, process model, and storage |
| Building Extension UI | How to create panel UIs with iframes and the UI SDK |
| Testing Extensions | Sideloading, mocking, and debugging |
| API Reference | Per-namespace reference for every method and event |