Docs / Builders
Writing a module
A module adds tools and pages to FrameBuff. You describe a module in one manifest file, framebuff.json, and nothing it asks for runs until the person installing it approves.
Ways to add to FrameBuff
The Modules page adds things in three ways:
- From a link to a module on GitHub, Hugging Face, GitLab or Codeberg. A repo, a folder in it, a release, a commit or a short
owner/nameall work. - From a folder on your machine.
- From a program already installed, such as VLC, registered as a tool. It stays off until you allow it on the Rules page.
FrameBuff's own modules, such as Files and Sync, are built in. You turn them on and off.
The manifest
Every module has a framebuff.json at the top of its folder. This is the smallest useful one. It adds one tool that greets someone, using a script that ships inside the module:
{
"schema": 1,
"id": "hello-module",
"name": "Hello Module",
"version": "0.1.0",
"category": "text",
"summary": "One tool that greets someone, from a script inside the module.",
"runtime": "native",
"nav": true,
"tools": [
{
"id": "hello-module.greet",
"desc": "Greet someone by name",
"params": [
{"name": "who", "type": "string", "desc": "who to greet", "required": true}
],
"out": "text",
"timeout_sec": 10,
"exec": ["./greet.sh", "{{who}}"]
}
],
"permissions": [],
"reach": {"network": [], "disk": [], "hardware": []},
"lifecycle": {"install": []}
}
| Field | What it says |
|---|---|
| schema | The manifest version. Use 1. |
| id, name, version | Who the module is. The id must not clash with a module already installed. |
| runtime | native (a program), docker or wasm. You always say which; FrameBuff never guesses. |
| nav | true gives the module a page in the left bar. |
| tools | Each tool's id (starting with the module id), description, parameters, output type, time limit, and what it runs. |
| exec | The program and its arguments. {{who}} is filled in from the call's parameters. The program is fixed in the manifest, so a caller can only fill in arguments. It must be a program on the PATH or a file inside the module. |
| reach | The network hosts, storage and hardware the module touches. Required. An empty list is a statement: "reaches no network". |
| lifecycle | Install steps ([] for none), and optionally a server to start from the module's card. |
| open_url | Optional. The module's own web page, which must be served on the same machine. |
| docker | Needed for the docker runtime: the image, and its ports, which are bound to the machine itself only. |
FrameBuff fills in nothing for you. A missing or wrong field refuses the install, and the message names the field.
Once installed, the tool works anywhere a tool can be called: a pipeline step, the command line, the command chat or an MCP client. Called with {"who": "nova"}, it answers Hello, nova!.
What happens when someone installs it
- Fetch. The module is downloaded into a staging folder, up to 512 MB by default. Nothing runs.
- Review. An approval screen, drawn from the manifest, shows its tools, what it reaches and its runtime. It also lists anything that stops it running on this machine, such as no Docker or no GPU.
- Approve. What the module asked for becomes permissions, which the Rules page shows and lets you change.
- Install. Install steps and tool calls run as sessions you can watch. A step that fails stays in the list so you can read why. A Docker image is pulled at install, where you see it, and later runs never pull again.
A WebAssembly module runs inside FrameBuff with no file system, no environment and no network of its own. It can only use what its approved permissions unlock. A module that reaches for anything else is stopped, and you get one notification that names what it tried.
Uninstall removes the module's tools, page, permissions, running processes and files.
Build an app with no code
The App builder makes a small app from widgets and tools. Widgets such as text, sliders, dropdowns and buttons feed a tool's input, and a tool's output feeds the next tool. Build it by hand, or type "make a panel that…" and get a draft on the canvas. Test in sandbox runs a draft once under strict checks. Save turns it into an app that opens from the Overview and runs as a job.
Built-in modules in Go
FrameBuff's own modules are Go packages built into the program. Each one returns a manifest describing its pages, settings and schedules, and the core collects them. The contract is four methods:
Manifest() registry.Module
Enable(a *core.App) error
Disable(a *core.App) error
Page(c *core.PageCtx) (core.PageOut, error)
Disable removes a module's tools and pages and never touches files on disk.