Navi Engine is a high-performance, enterprise-grade Discord bot framework. It pairs a lightning-fast Rust core with a hot-reloadable Lua plugin system and a built-in Terminal UI (TUI) dashboard.
With Navi, you never have to recompile your Rust binary to add new bot features. Simply write a Lua script, drop it in the plugins/ directory, and hit reload.
- ⚡ Rust + Lua Architecture: Uses
poise/serenityfor rock-solid Discord API interactions, andmluato execute Lua scripts at blazing speeds. - 🖥️ Interactive TUI Dashboard: A built-in terminal interface using
ratatui. Features real-time color-coded logs, auto-scrolling, and a dynamic configuration menu with interactive dropdowns. - 🔥 Hot-Reloading: Press
rin the TUI to instantly reload all Lua plugins without disconnecting the bot. - 🗄️ Smart SQLite Database: Includes a built-in, thread-safe SQLite key-value store (
navi.db). Database keys are automatically sandboxed and namespaced to the specific plugin requesting them to prevent data collisions. - 📡 Decoupled Event Bus: Plugins communicate via an inter-plugin event bus (
navi.onandnavi.emit), meaning plugins never directly depend on each other. - 🎛️ Native UI Components: Full support for spawning and handling Discord buttons and select menus directly from Lua.
- Rust and Cargo installed.
- A Discord Bot Token.
- Clone the repository.
- Create a
.envfile in the root directory and add your bot token:DISCORD_TOKEN=your_token_here - Run the engine:
cargo run- The TUI will launch, and the engine will automatically execute any
.luafiles found in theplugins/directory.
Every feature in Navi is a self-contained plugin. A plugin is simply a .lua file placed inside the plugins/ folder. The engine reads these alphabetically and bakes them into the core at runtime.
Here is an example of a simple auto-responder plugin:
print("--- Loading Greeter Plugin ---")
-- 1. Register Configuration for the TUI Dashboard
navi.register_config("greeter", {
{ key = "welcome_message", name = "Welcome Message", description = "What the bot says", type = "string", default = "Hello there!" },
{ key = "log_channel", name = "Log Channel", description = "Where to send the logs", type = "channel", default = "" }
})
-- 2. Create a Slash Command
navi.create_slash("hello", "Says hello to the user", {},
---@param ctx NaviSlashCtx
function(ctx)
local text = navi.db.get("welcome_message") -- Auto-namespaced to 'greeter:welcome_message'!
ctx.reply(text)
end)
-- 3. Listen to Discord Events
navi.register(function(msg)
if msg.author_bot then return end
if msg.content == "ping" then
navi.say(msg.channel_id, "pong!")
end
end)To get full autocomplete, hover documentation, and type-checking in your editor (especially for Neovim/LuaLS or VSCode), you need the engine's EmmyLua annotations.
- Grab the
navi_api.luafile (contains all---@metatags for the engine). - Place it anywhere in your project workspace EXCEPT the
plugins/folder (e.g., in a.types/ordocs/folder). - Your LSP will automatically read the global
naviobject and provide perfect autocomplete for things likectx.reply,navi.send_message, and UI component tables!
q- Shutdown the engine safely.r- Reload all Lua plugins.c- Open the Settings & Configuration Dashboard.l- Return to the Live Logs.i- Open the terminal input buffer.Up/Down/Enter- Navigate and edit plugin configurations.
Click here to view the Wiki Page
-
Implement lists of nested objects as config option and TUI to support it -
Add more Discord features to the engine -
Bolster the amount of built-in core plugins -
Implement handling modal forms -
Implement plugin repo for user-created plugins - Implement ability for lua code to expose custom TUI functionality