Hyperextensible runtime for composing tools, plugins, and interfaces in Lua.
Small core. User-owned config. Replaceable everything else.
Think Neovim as a runtime: a programmable core, process plugins, and a Lua
config you own. The engine spawns processes, routes lines, hosts Lua, and stamps
identity. Your init.lua decides what exists, how it talks, what gets
persisted, and which interface sits on top.
Nefor does not require LLMs. Models, scripts, tools, agents, orchestrators, and plain interfaces are composable units when you wire them in. The bundled starter is one distribution, not the product boundary.
Most tools expose selected extension points. Eventually you hit the wall: this part is configurable, that part is not.
Nefor moves the wall into Lua. Plugins are independent OS processes. Interfaces are another composition. Routing, persistence, orchestration, approvals, and protocol semantics live where you can read and rewrite them.
The starter proves the shape with a chat surface, providers, tool gates, sessions, and workflow actors. Keep it, strip it down, or use it as a reference for your own distribution.
- Tools: spawn them as plugins, gate them, wrap them, translate them, or replace them.
- Plugins: run independent binaries over stdio. Rust is common here; the boundary is process + lines.
- Interfaces: put a TUI, CLI, bridge, or custom surface on the same runtime.
- Reasoners: compose LLM calls, scripts, tool calls, agents, orchestrators, or any unit that reads context and produces work.
- Policies: own approval, routing, persistence, replay, provider choice, and dispatch behavior in Lua.
- Distributions: ship a complete
init.luawith plugins and defaults, or keep a private config that only fits your machine.
From source:
git clone https://github.com/amenocturne/nefor
cd nefor
just installjust install builds the engine and plugin binaries, then copies the starter
composition to ~/.config/nefor. Use lower-level targets when needed:
just install-nefor source # source | latest | nightly
just install-starter safe # safe | forceinstall-starter refuses to overwrite an existing config unless you pass
force.
Or install the engine with brew:
brew install amenocturne/tap/nefor
mkdir -p ~/.config/nefor
cp -r $(brew --prefix)/share/nefor/starter/* ~/.config/nefor/The starter ships with a deterministic offline mock provider, plus
openai-provider for OpenAI-compatible APIs and chatgpt-provider for the
ChatGPT Responses API.
Run the starter:
neforThe first run uses the mock provider, so no live model is required. Edit the copied config for real providers, different tools, or different wiring:
$EDITOR ~/.config/nefor/config/init.lua
$EDITOR ~/.config/nefor/init.luaA Nefor composition is an init.lua. Use the starter as the concrete reference
for provider setup, tool gating, session replay, workflow actors, and TUI
wiring.
The engine spawns processes and routes lines through Lua. Everything else is composition.
| Layer | What it owns |
|---|---|
| Engine / bus | Process spawning, line routing, Lua hosting, and identity stamping (origin, ts). It does not parse message bodies. |
Plugins (plugins/) |
Self-contained work over stdio. Each plugin owns one scoped task. |
Lua config / starter (init.lua, starter/) |
Dispatch hooks, actor spawning, policies, persistence, provider/tool wiring, and interfaces. |
| Interfaces | User surfaces composed over the same bus. The starter uses nefor-tui; you can wire another. |
Bash-tool test: a plugin should feel like a self-contained utility you could run from a shell, then compose elsewhere. Plugins should not know their neighbors; composition belongs in Lua.
All commands live in the justfile. Run just to see the full list.
- Architecture and writing principles
- Plugin authoring guide
- Testing
- Glossary
- NCP spec
- Plugins
- Starter composition
- Lua core
Do whatever you want, i.e. MIT.