Same protocol across every runtime — the CLI wraps any command, the Python and R packages drop into existing code. No accounts, no config file, no services to run.
Single static binary, ~8 MB, no runtime dependencies. macOS (arm64, x64), Linux (amd64, arm64), Windows (amd64) native. Also available as a Docker image.
curl -fsSL https://github.com/MuteJester/Fernsicht/releases/latest/download/install.sh | sh
irm https://github.com/MuteJester/Fernsicht/releases/latest/download/install.ps1 | iex
brew tap MuteJester/fernsicht && brew install fernsicht
scoop bucket add fernsicht https://github.com/MuteJester/scoop-fernsicht; scoop install fernsicht
docker run --rm ghcr.io/mutejester/fernsicht:latest --version
Heads-up: macOS binaries aren't Apple-notarized yet (v0.1.x) — Gatekeeper will warn on the curl path. Use Homebrew to bypass, or run xattr -d com.apple.quarantine after install. Windows SmartScreen may warn on first run; click "Run anyway".
Confirms the binary is on your PATH and that it can reach the signalling service. fernsicht doctor runs a deeper set of checks (DNS, TLS, TCP, proxy detection).
fernsicht --version && fernsicht doctor
→ fernsicht 0.1.x (signalling: https://signal.fernsicht.space, reachable)
Anything that prints progress becomes observable. fernsicht run -- auto-detects common progress formats (tqdm, bracketed [N/M], N of M, bare percent, step/epoch/iter keywords). For anything custom, emit a __fernsicht__ magic-prefix line — see fernsicht magic.
fernsicht run -- python train.py --epochs 1200
→ https://app.fernsicht.space/#room=abc12345&role=viewer share this link — viewers open in any browser, no install
Sensible defaults. Reach for flags when you want a custom label, a cap on viewers, or a self-hosted signalling server. Full reference: fernsicht run --help.
fernsicht run --label "nightly training" -- python train.py
fernsicht run --max-viewers 1 -- make build
FERNSICHT_SERVER_URL=https://signal.my.org fernsicht run -- ./sim
Pre-release — the wheel is not yet on PyPI. Install directly from GitHub for now; a PyPI release is coming with the next minor version.
pip install "git+https://github.com/MuteJester/Fernsicht.git#subdirectory=publishers/python"
uv pip install "git+https://github.com/MuteJester/Fernsicht.git#subdirectory=publishers/python"
Runtime deps: aiortc (WebRTC) and aiohttp. Python 3.9+ on any OS with a modern TLS stack.
Reports progress, rate, and ETA. Works with any sized iterator — lists, generators, DataLoaders, ranges. URL prints once on first iteration.
from fernsicht import blick for epoch in blick(range(1200), desc="Training model"): train_one_epoch(model, epoch)
→ https://app.fernsicht.space/#room=abc12345&role=viewer (shown once on first iteration)
For streams, callbacks, multi-stage pipelines, or async producers — use the manual bar and call update() as progress accumulates. Close it explicitly (or with a with block).
from fernsicht import manual with manual(total=n_files, desc="Preprocessing") as bar: for path in files: handle(path) bar.update(1)
Same link works for everyone. The server caps rooms by default; pass max_viewers= to tighten (single-viewer) or raise (up to the server limit). No accounts, no logins, no roles.
from fernsicht import blick for item in blick(items, desc="Team demo", max_viewers=1): process(item)
Pre-release — CRAN submission comes with the 1.0 line. Pure R, no compiled code. Downloads a small signed helper binary on first use.
remotes::install_github("MuteJester/Fernsicht", subdir = "publishers/r")
pak::pak("MuteJester/Fernsicht/publishers/r")
v0.1.x known issue: the lazy bridge-binary download points at a placeholder release until bridge/v0.1.0 ships. Track the releases page — once the bridge tag lands, blick() works end-to-end. CLI users can observe their R runs today via fernsicht run -- Rscript my-analysis.R.
Returns the collected results, with live progress streamed to any browser.
library(fernsicht) results <- blick(items, process, label = "Sampling chains")
Open a session, tick once per unit of work. The session auto-closes when the calling scope exits. with_session() + tick() are the primitives behind blick().
library(fernsicht) with_session(label = "Bootstrap", total = B, { for (b in 1:B) { resample(data) tick() } })
Drop blick() around any loop in a code chunk — the URL prints once, viewers stay attached as the doc renders.
library(fernsicht) res <- lapply(datasets, function(d) { blick(seq_len(nrow(d)), function(i) fit_row(d[i, ]), label = paste("fit —", d$name[1])) })
Your very first fernsicht run -- prints a URL like https://app.fernsicht.space/#room=…&role=viewer. Open it on any device to watch live — no install, no account, peer-to-peer after the handshake. Share it with teammates who want to follow along.