Write a Husk plugin

Customize

Write a Husk plugin

Use Red's embedded Husk language to register commands, keep private state, and request editor-owned operations.

Create the smallest plugin

Husk is Red's embedded scripting language. Place hello.hk in the plugins directory under Red's configuration directory, then register the filename in config.toml:

[plugins]
hello = "hello.hk"
#[red::command(
    name = "HelloWorld",
    title = "Say hello",
    category = "Example",
)]
fn hello_world() {
    red::execute("Print", "Hello from Husk");
}

The command is available as :HelloWorld and through the command palette.

Keep plugin state

struct PluginState {
    count: i64,
}

#[red::state]
fn initial_state() -> PluginState {
    return PluginState { count: 0 };
}

Read private state with red::state() and update named fields with red::state_patch(...). Use declaration attributes for commands, fixed events, configuration, and lifecycle hooks; keep red::on for event names known only at runtime.

Use the host boundary

FunctionPurpose
red::executeRequest a fire-and-forget editor action
red::requestRequest data and receive one typed callback
red::onSubscribe to an editor event
red::stateRead the plugin's private typed record
red::state_patchUpdate selected state fields
red::logWrite diagnostic information to Red's log

Red remains the owner of buffers, undo history, focus, confirmations, sessions, and filesystem reconciliation. Plugins request attributed operations through the versioned host API rather than changing editor state directly.

Open the complete host API reference

Use the standalone Husk CLI

The Husk CLI is built separately from the Red editor binary:

cargo install --path crates/husk-cli
husk check script.hk
husk run script.hk
husk test path/to/package
husk repl

Standalone Husk grants no ambient filesystem, network, environment, process, clock, or random access. Embedders add capabilities explicitly.