Write F#. See it live.

SageFs is a live development environment that eliminates the edit‑build‑run cycle. Tests run as you type — no save needed. Eval code on demand with Alt+Enter. Results stream to every editor you use, from a single shared daemon.

$ sagefs --proj MyProject.fsproj
Get started in 60 seconds
Requires the .NET 10 SDK
01

Install

SageFs is a .NET global tool. One command, no config files.

$ dotnet tool install --global SageFs
02

Run

Point it at your project. The daemon starts, loads dependencies, and opens the TUI.

$ sagefs --proj MyProject.fsproj
03

Code

Edit any .fs file — tests run on every change. Hit Alt+Enter to evaluate code on demand. Results stream to your editor.

Full documentation →
What happens when you run it
From keystroke to result in under a second
Here's the path your code takes — from the moment you change it to the moment you see results in your editor.
01 — You write code

Change a line

Edit any .fs or .fsx file. Tests start running on every change — no save needed. Hit Alt+Enter to evaluate code on demand. Both modes, all the time.

0 ms
02 — File watcher detects

Change captured

SageFs watches your entire project tree. It sees the change as it happens, classifies it (.fs → reload, .fsproj → soft reset), and routes it to the right handler.

~5 ms
03 — Worker evaluates

Code runs in FSI

A dedicated worker process — already warmed up with your project's dependencies loaded — compiles and executes the changed code. No cold start. No full rebuild.

~100 ms
04 — Tests re-run

Affected tests only

The live testing engine identifies which tests touch the changed code and re-executes just those. Green checkmarks or red failures stream back instantly.

~300 ms
05 — Results everywhere

All editors update

Via Server-Sent Events (SSE), every connected client — VS Code, Neovim, Visual Studio, the GPU GUI, AI agents — sees the results simultaneously. No polling. No refresh.

~500 ms total
Work where you want
Five editors, one live session
Every editor connects to the same running daemon. Switch between them freely — your session, your test results, your eval history all stay in sync.
🧩

Neovim

Lua · 25 modules · 885 tests

Two eval modes: tree-sitter auto-detects the enclosing scope in .fs files (inferred mode), or use ;; delimiters for explicit cell boundaries (manual mode). Virtual text for inline results, SSE-driven live diagnostics, gutter signs for test pass/fail and code coverage.

  • tree-sitter scope eval
  • live diagnostics
  • coverage gutter
  • test panel
  • type explorer
💻

VS Code

F# via Fable → JavaScript · 14 modules

Select code, hit Alt+Enter, see colored annotations inline. Sidebar panels for hot reload file trees, live test status, type exploration, and session switching. Auto-detects or starts the daemon.

  • inline eval results
  • test gutter icons
  • hot reload tree
  • type explorer
⌨️

Terminal (TUI)

F# · ANSI rendering · built-in

A terminal interface with panes for code input, eval output, session management, and live test results. Completion menus, 256-color themes. Works over SSH. Zero dependencies.

  • Alt+Enter eval
  • split panes
  • session picker
  • completions
🖥️

GPU Window (Raylib)

F# · Raylib-cs · OpenGL

A GPU-accelerated rendering of the same UI. Crisp text at any resolution, smooth scrolling, and sub-millisecond frame times. Shares the same layout engine as the terminal — gutter features are still catching up.

  • GPU-rendered text
  • mouse support
  • any resolution
  • same keybindings
🏢

Visual Studio

F# + C# · VS Extensibility · 7 modules

Integration with Visual Studio's tool windows. Eval, CodeLens, and session management — embedded in the IDE enterprise teams already use. Daemon auto-management included. Live testing UI is still in progress.

  • tool windows
  • daemon management
  • session control
  • CodeLens eval
The secret sauce
One daemon. Every client. Always in sync.
SageFs runs a single background daemon that owns all sessions, workers, and state. Every editor — and every AI agent — connects via the same protocol. Crash-proof supervision means it auto-restarts on failure.
Editors — where you write code
Neovim
Cell eval, gutter signs, live diagnostics
VS Code
Inline annotations, sidebar panels
Terminal TUI
Built-in editor, split panes
Visual Studio
Tool windows, daemon auto-start
Raylib GUI
GPU-rendered, same layout engine
AI Agents
Claude, Copilot, any MCP client
↕ SSE push (real-time) + HTTP requests ↕
Daemon — the single process that owns everything
SageFs Daemon
Elm-style state machine. All sessions, all test results, all editor state lives here. Broadcasts every change to every client via SSE. Exposes MCP tools for AI agents. One process, one source of truth.
↕ HTTP to isolated worker processes ↕
Workers — where your code actually runs
Active Worker
Running your FSI session — evals, completions, type checks
Standby Worker
Pre-warmed with your project. Swaps in instantly on reset.
Standby Worker
Another warm spare. Pool auto-heats when .fsproj changes.
Under the hood
What makes it fast, reliable, and smart
Each piece of SageFs exists to solve a specific problem you'd hit building a live F# environment. Here's why each one matters.

Hot Reload

"I saved a file. Why do I have to rebuild everything?"
When you save, SageFs patches method pointers at runtime — no IL instrumentation, no restart. Changed functions are live in ~100ms. The browser auto-refreshes via SSE. Only the changed file recompiles; everything else stays warm.
🧪

Live Testing

"I want to know if my change broke something — before I even save."
Three-speed pipeline: Tree-sitter finds tests in broken code (~50ms), the F# Compiler Service builds a dependency graph (~350ms), then only affected tests execute. Green/red gutter markers in your editor. Tests run on every change by default — no save needed. Configurable per category: unit on every keystroke, integration on save, browser on demand.
🧠

Code Completions

"What methods does this type have? What namespace is that in?"
Type-aware completions powered by the F# Compiler Services, with fuzzy matching. Available everywhere — the TUI and GPU GUI have a built-in completion popup, editor plugins get them via SSE, and AI agents access them through the MCP get_completions tool. Explore any loaded .NET API interactively. Diagnostics (type errors, warnings) stream inline as you type.
🔄

Session Management

"I need multiple contexts — one for my app, one for experiments."
Create, switch, reset, and destroy isolated F# sessions on the fly. Each gets its own FSI worker process with your full project loaded. Sessions persist across daemon restarts. Soft reset clears definitions; hard reset rebuilds from scratch.
🏊

Standby Pool

"Restarting a session takes forever while it reloads my project."
In the background, SageFs pre-warms spare worker processes with your project already compiled and loaded. When you reset, the standby swaps in instantly — no cold start. The pool auto-heats when project files change.
🎨

Rendering Pipeline

"How does the same UI work in a terminal AND a GPU window?"
All UI renders to an abstract Cell[,] grid — a 2D array of characters with colors. The TUI backend emits ANSI escape codes. The Raylib backend draws GPU quads. Same layout engine, same input handling, pixel-perfect parity.
🔁

Elm Architecture

"How does everything stay in sync without race conditions?"
All state lives in a single immutable model. Every event — keystrokes, file changes, test results, SSE messages — dispatches through a pure update function. No shared mutable state. No locks. Side effects execute after the model updates. The UI is always a pure function of the current model.
🛡️

Crash Recovery

"What if a worker crashes? What if the daemon dies?"
Erlang-style supervision. The watchdog monitors every worker process — if one crashes, it auto-restarts with exponential backoff. The daemon itself is supervised at the OS level. State is event-sourced, so nothing is lost. A crashed session resumes exactly where it left off.
📡

Observability

"Something is slow. How do I find out what?"
OpenTelemetry tracing across the entire pipeline — from file save to test result. Frame time displayed in the status bar. Pipeline trace tool shows exactly where time is spent: discovery, compilation, execution, rendering.
Built for AI agents
Give Claude (or any AI) a live compiler
SageFs exposes the Model Context Protocol (MCP) — the same protocol that powers Claude Desktop and GitHub Copilot tool use. AI agents don't just generate code. They execute it, type-check it, run tests, and iterate — against your real project.
send_fsharp_code
Execute F# code in a live session with your project's full dependency graph loaded. Each ;; is an isolated transaction.
check_fsharp_code
Type-check code without running it. Catches errors before execution — the AI equivalent of "does this compile?"
run_tests
Execute tests by name, category, or pattern. Get structured pass/fail results back — not just console output.
get_completions
Code completions at any cursor position. The agent discovers available APIs from your actual loaded assemblies.
explore_namespace / explore_type
Browse the full .NET type system interactively — namespaces, types, members, constructors. No documentation needed.
get_live_test_status
Query the current state of all tests — passing, failing, stale, running. See what broke and what's green.
load_fsharp_script
Load and execute an .fsx script file. Each statement runs independently — partial progress survives failures.
get_pipeline_trace
Diagnose slow test runs. See enabled providers, run policies, and per-test timing to find bottlenecks.
The complete picture
Every module, every layer
SageFs.Core is the shared engine (66 modules). The CLI and GUI projects are thin shells that consume Core's rendering pipeline. Here's the full compilation-order dependency map.
🏗️ Foundation — bootstrapping, configuration, utilities
↓ depends on ↓
🔌 Worker System — isolated FSI process management
↓ depends on ↓
📋 Session Layer — lifecycle, state, operations
↓ depends on ↓
↓ depends on ↓
🖼️ Rendering — abstract grid → any backend
↓ depends on ↓
🔁 Elm Loop — the heart of state management
↓ depends on ↓
🧩 Middleware — FSI compatibility, computation expressions, directives
↓ depends on ↓
🚀 Orchestration — wiring it all together
66
Core modules
~28K
Lines of production F#
2,691
Tests (SageFs)
5
Editor integrations
13
Days to build
490
Commits