# Build a mod

> Scaffold a mod, run it locally, and ship it.

Source: https://www.onlucra.com/docs/mods-build

> **Beta: needs approval.** Mods are in beta. You can build and test a mod today; to install one on a Lucra account, ask Lucra for access.

## Scaffold

```bash
npm install -g @lucra/mod
curl -O https://www.onlucra.com/docs/mods/ui.json
mod init my-mod --id acme.notes --ui ui.json
```

`ui.json` is Lucra's contract: every component a mod can use, every slot, the events Lucra sends and its theme. `mod init` aims the mod at Lucra and writes `llms.txt`, a Claude skill and `AGENTS.md`, so a coding agent writes valid mods first time.

## Write it

```ts
import { defineMod, serve } from "@lucra/mod/server"

export default serve(defineMod({
  render: {
    notes: () => ({ type: "Section", props: { title: "Notes" }, children: [
      { type: "TextField", props: { label: "Note", name: "note" } },
      { type: "Button", props: { label: "Save", action: "save" } },
    ] }),
  },
  actions: {
    save: ({ input }) => ({ effects: [{ type: "toast", message: `Saved: ${String(input?.note ?? "")}` }] }),
  },
}))
```

`mod.json` says what the mod is: its ID and name, the permissions its install asks for (`read`, `write`), where it shows (`contributes`), and the only hosts its server may reach (`network.allow`).

## Check it

| Command | |
| --- | --- |
| `mod render mod.json nav.page notes --ui ui.json` | Run it locally and validate what it draws. Add `--action save` to run an action. |
| `mod manifest mod.json --ui ui.json` | Check `mod.json` fits Lucra. |
| `mod dev mod.json --ui ui.json` | Serve it over the real signed protocol, rebuilding on save. |
| `mod build mod.json` | Bundle it for deployment. It refuses code that runs strings as code. |
| `mod conformance mod.json --ui ui.json --url … --secret …` | Check a deployment refuses unsigned calls and answers correctly. |

## Ship it

Deploy the build anywhere that runs JavaScript, then ask Lucra to install it on your account. Once it's installed, it shows in Settings → Developers → Mods and its pages appear under **Mods** in the sidebar.
