Scripting Languages
Crucible uses Lua for plugins, tools, and hooks. Fennel (a Lisp that compiles to Lua) is also supported.
Overview
| Language | Best For | Key Feature |
|---|---|---|
| Lua | General use, LLM-generated code | Familiar syntax, simple |
| Fennel | Power users wanting macros | Lisp syntax, compiles to Lua |
Both languages can:
- Define tools in a plugin’s spec table, served to agents and
cru mcpalike - Register event hooks
- Access the Crucible API (search, notes, graph)
- Execute shell commands (with policy controls)
Lua
Lua is a simple, embeddable scripting language with massive adoption. Crucible embeds PUC Lua 5.4 via the mlua crate.
Strengths:
- Familiar syntax (if you know JavaScript/Python)
- LLM-friendly (models generate excellent Lua)
- Simple and easy to debug
See Language Basics for syntax and examples.
Fennel
Fennel is a Lisp that compiles to Lua. It provides:
- S-expression syntax
- Compile-time macros
- Full Lua interoperability
- Pattern matching
Fennel files (.fnl) are compiled to Lua at load time, so they have the same runtime characteristics.
Choosing a Language
Use Lua when…
- You want simple, readable code
- LLMs will generate your plugins
- You’re prototyping quickly
- You prefer familiar syntax
Use Fennel when…
- You love Lisp
- You want compile-time macros
- You’re building DSLs
- You prefer s-expressions
Plugin Discovery
Place files in:
~/.config/crucible/plugins/ # Global personal<runtimepath entry>/plugins/ # Opt-in extra trees, named in config.tomlPlugins are user-scoped: no kiln, project or workspace directory is searched on
its own. See Creating Plugins for why, and for how
runtimepath opts a tree in.
File extensions determine the runtime:
.lua— Lua.fnl— Fennel (compiles to Lua)
Configuration
Crucible also loads configuration from ~/.config/crucible/init.lua. This allows customizing the TUI, defining keybindings, and more.
See Configuration for details.
Oil UI DSL
Both Lua and Fennel can build TUI components using the Oil (Obvious Interface Language) API. Oil provides a functional, React-like model where components are functions that return node trees.
-- Lualocal view = cru.oil.col({ gap = 1 }, cru.oil.text("Hello", { bold = true }), cru.oil.when(loading, cru.oil.spinner()));; Fennel(local oil (require :oil))(oil.col {:gap 1} (oil.text "Hello" {:bold true}) (oil.when loading (oil.spinner)))See Oil Lua API for the full Oil component reference; Scripted UI covers theming and statuslines.
See Also
- Language Basics — Lua reference
- Configuration — Lua configuration
- Oil Lua API — Oil UI DSL reference
- Creating Plugins — Plugin development guide
- Custom Tools — Adding MCP tools
- Event Hooks — Reacting to events