@lucra/mod
v0.2.1
Published
The Mod UI spec: describe what an app can show, the way OpenAPI describes what it can do.
Downloads
923
Readme
mod
OpenAPI for UI. Describe what your app can show — its components, where mods plug in, its theme — so mods built by people (or by Claude Code and Codex) look and feel native, and keep working when you redesign.
mod generate [--check] # write ui.json from exposed components (or fail CI if stale)
mod diff old-ui.json ui.json # what changed for mods, and whether host.version was bumped enough
mod agents --ui ui.json # llms.txt, a Claude skill and AGENTS.md for writing mods for this host
mod init my-mod --id acme.notes --ui ui.json
mod render mod.json nav.page main --ui ui.json [--action send --input '{"message":"hi"}']
mod dev mod.json --ui ui.json # serve over the signed protocol, rebuilding on save
mod build mod.json # bundle server + browser entries and assets
mod conformance mod.json --ui ui.json --url https://… --secret …
mod keygen acme && mod pack mod.json --key acme.key.json && mod verify pkg.json --trust trusted.json
mod validate tree.json --ui ui.json --slot nav.page
mod manifest mod.json --ui ui.json
mod rules | mod spec [ui|tree|manifest|protocol]SPEC.md: the Mod UI spec.spec/ui.schema.json: the document's JSON Schema.packages/mod(@lucra/mod):expose()and the generator, plus:/tree(validation),/react(renderer),/manifest,/protocol,/signing/server(defineMod,serve),/worker(browser mods),/mcp(MCP bridge)/host(createModHost,createModClient),/runtime(HTTP, dispatcher, in-process transports),/storage,/network/install(consent, settings, secrets, uninstall),/diff,/agents,/devtools,/package(signing, registry),/conformance- the
modCLI
examples/basic: a tiny host — two ready components and one that trips every rule.examples/hello-mod: a small mod with a server half (page, action, event + storage, tool) and a browser half (instant clicks, its own updates).examples/host-demo:demo.ts— a host installing and running that mod on every runtime, with a live form, events, limits, MCP and every refusal;tooling.ts— diff, agent kit, init, build, dev, packages, conformance.
Write a mod
export default serve(defineMod({
render: { hello: ({ context }) => ({ type: "List", props: { title: "Hello" }, children: [
{ type: "Button", props: { label: "Say hi", action: "say-hi" } }] }) },
actions: { "say-hi": () => ({ effects: [{ type: "toast", message: "Hi!" }] }) },
}))Use it in a host
Add one line to each component you want mods to use:
export const buttonMod = expose("Button", Button, z.object({ label: z.string(), action: modAction }), { actions: { action: "onClick" } })Add
mod.config.jsonwith your host name and version, component globs, stylesheet and slots (seeexamples/basic/mod.config.json).Run
mod generatenext to your OpenAPI generation, andmod generate --checkin CI.
Develop
Node 24+, no build step (Node runs the TypeScript directly).
npm install
npm run check # schemas and example document are current; example mod validates; host demo passes
npm run typecheck
npm run example # regenerate examples/basic/ui.json
npm run spec # regenerate spec/*.schema.json after changing the schemasLicense
Copyright (c) 2026 On Lucra, Inc. All rights reserved. Proprietary and confidential — see LICENSE. No use, copying, implementation or distribution without a written agreement with On Lucra, Inc. Mod authors build under the Lucra Mod Developer License (draft, pending counsel review).
