Dev Tools

Copy Markdown

Mooncore includes a built-in development dashboard for real-time observability of your running application. The dashboard is a full-featured single-page app with live VM metrics, action execution, developer tools, and more.

Security: Never enable mooncore_dev_tools in production. The dashboard provides full access to eval, action execution, and file system browsing.

Enabling Dev Mode

Dev tools require two gates to be open:

  1. Config gatemooncore_dev_tools: true in your application config
  2. Environment gateMOONCORE_DEV_TOOLS=true environment variable

Both must be set. This two-gate system ensures dev tools can't accidentally be enabled in production through a misconfigured config file alone.

# config/dev.exs
config :mooncore,
  mooncore_dev_tools: true,
  mcp_port: 4040   # default, can be changed
# Set the environment variable before starting the app
export MOONCORE_DEV_TOOLS=true
mix run --no-halt

Or inline:

MOONCORE_DEV_TOOLS=true mix run --no-halt

When both gates are open, a dedicated HTTP server starts on mcp_port (default 4040). Open http://localhost:4040/ in your browser.

When either gate is closed, nothing dev-related starts — no server, no watcher, no overhead.

Dashboard Screens

The dashboard has a left sidebar with eight sections. Below is a detailed walkthrough of each.


Dashboard

The main overview of your running BEAM VM. Auto-refreshes every 2 seconds.

Overview tab shows four metric cards with sparkline history charts:

  • Total Memory — current total memory used by the VM
  • CPU Runtime — runtime ratio percentage (how busy the VM is)
  • Processes — number of active Erlang processes
  • Reductions — total reduction count (measure of work done)

Below the cards:

  • Memory Breakdown — horizontal bar chart showing memory split across processes, binary, ETS, atom, and code
  • Scheduler Utilization — per-scheduler CPU percent with color coding (green < 50%, yellow < 80%, red > 80%)
  • VM Limits — gauge bars for processes, atoms, ports, and ETS tables vs their limits
  • Quick Stats — runtime, CPU runtime ratio, ETS table count

Processes tab — table of the top 20 processes sorted by memory:

ColumnDescription
Name / PIDRegistered name (if any) and PID
MemoryProcess heap memory
MQMessage queue length (amber > 0, red > 100)
ReductionsWork done by this process
Statusrunning / waiting / suspended
Current FunctionWhat the process is currently executing

ETS tab — all ETS tables sorted by memory, showing name, row count, memory, and type (set, ordered_set, bag, etc.).

Apps tab — all started OTP applications with name, version, and description.


Api

Lists all registered actions across all your apps, grouped by app.

Each app group shows:

  • App name and action module
  • Defined roles
  • Action count

Each action row shows:

  • Action name (e.g. task.create)
  • Handler function (e.g. MyApp.Action.Task.create)
  • Access level — public (green badge, no roles required) or protected (violet badge listing required roles)

Actions (Runner)

Execute any action directly from the browser.

Fields:

  • Action — action name string (e.g. task.create)
  • Params (JSON) — JSON object of parameters to pass
  • Auth (JSON, optional) — auth context with roles, user, app, etc.

Buttons:

  • Run — executes the action through the full pipeline and shows the JSON result below
  • → To Eval — converts the action call to an Elixir Mooncore.Action.execute(...) expression and sends it to the Console

When the Actions page is active, the right panel shows the Action Logs panel (see below).


Tools

A collection of developer utilities, organized in sub-tabs:

JSON ↔ Elixir — bidirectional converter between JSON objects and Elixir map syntax. Paste JSON and get %{"key" => "value"} map notation, or vice versa. Has a Copy button.

JWT Token — two modes:

  • Create Token — enter claims as JSON (user, app, roles, etc.), generates a signed JWT using your configured RS256 key. Shows the raw token with copy support.
  • Decode Token — paste a JWT, verify it against your key with Verify & Decode, or just decode the payload without verification using Decode Payload (no verify). Shows expiry info (_expired, _exp_human).

Base64 — encode/decode with standard and URL-safe variants. Four buttons: Encode, Decode, URL-safe Encode, URL-safe Decode.

Timestamps — convert between Unix timestamps and ISO 8601 dates. Auto-detects seconds vs milliseconds. Shows a live "Now" counter. Use now button fills both fields with the current time.

Inspect — evaluate any Elixir expression and get inspect/1 output with pretty-printing. Also has a Type Info button that shows the type, byte_size (for binaries), and length (for lists/maps).


Guides

A Livebook-style markdown editor for your project's guides/ directory.

Guide list — shows all .md files from your project's guides/ folder with name and filename.

Guide editor — split-pane view:

  • Left pane — CodeMirror editor with markdown syntax highlighting. Supports Ctrl+S / Cmd+S to save.
  • Right pane — live rendered preview of the markdown content.

Code blocks with elixir, ex, exs, or iex language tags get a ▶ Run button (appears on hover) that evaluates the code in the running application and shows the result inline. You can edit the code in the block before running.

Changes are saved back to the actual file on disk.


Clients

Real-time view of WebSocket connections, grouped by pool/group.

Header shows total connection count and total channel count. Auto-refreshes every 3 seconds (toggleable with ⏸/▶ button).

Groups — each group is expandable (default: expanded) showing:

  • Group name
  • PID count
  • Channel count

Channels — each channel shows its name with an icon:

  • @ prefix (cyan) — user channels
  • # prefix (violet) — room/topic channels

Click a channel to expand and see individual member PIDs with green connection dots.


Console

An IEx-like REPL running against your live application.

Features:

  • Type Elixir expressions and press Enter (or click Run) to evaluate
  • Results show in green, errors in red, input in violet
  • Command history — press ↑/↓ arrows to navigate previous commands
  • Shift+Enter for multi-line input

Everything evaluates via Code.eval_string/1 in the running application — treat it like a full IEx session.

Other pages can send code here: the Actions page has a → To Eval button, and the Tools/Inspect page evaluates directly.


Files

A file browser for your project directory.

  • Navigate directories by clicking folders
  • Click files to open them in the right panel editor
  • Shows file sizes
  • ↑ Up button to go to parent directory
  • Hides dotfiles and _build, deps, node_modules, .git directories

Right panel file editor:

  • CodeMirror editor with syntax highlighting (Elixir, Erlang, JavaScript, HTML, CSS, Markdown, YAML, Shell, etc.)
  • Shows language label and file path
  • Save button (also Ctrl+S / Cmd+S) — writes changes to disk
  • Eval button — appears for .ex and .exs files, evaluates the entire file content
  • Dirty indicator (amber dot) when there are unsaved changes

Action Logs Panel

The right panel shows Action Logs whenever the Actions page is active and no file is open. This is a live feed of all action executions across HTTP, WebSocket, and MCP sources.

Features:

  • Auto-refresh every 2 seconds (toggleable)
  • Filter by action name
  • Clear button to wipe the log buffer
  • Each log entry shows: action name, source badge (ws/http), error indicator (✗), and duration in ms

Expanded entry shows:

  • IP address and timestamp
  • Params — with Copy JSON and Copy Map (Elixir syntax) buttons
  • Auth — authentication context used
  • Response — action result with Copy buttons
  • Load in Runner — pre-fills the Actions page with this action's name, params, and auth for re-execution