Nonlinear (SyN) MRI registration entirely in your browser. Pick a moving image and a template, press Go, watch the warped result appear. No upload, no server, no install — the images never leave your machine.
Live demo → https://rordenlab.github.io/edgefire/
The registration is done by FireANTs — by
Rohit Jena, Pratik Chaudhari and James C. Gee — reached through
cfireants, a pure C port of it compiled to
WebAssembly. Files have been changed relative to the original: no FireANTs source is
carried over; the algorithms, the multi-scale schedule, the WarpAdam optimizer and the CC
and MI metrics are C reimplementations of upstream commit 0d13a3f, verified numerically
against the Python reference. This is a derivative work under the FireANTs License
version 1.0 (see LICENSE) and is not endorsed by the FireANTs authors.
If you publish work using this, cite the FireANTs paper:
@article{jena2024fireants,
title = {FireANTs: Adaptive Riemannian Optimization for Multi-Scale
Diffeomorphic Registration},
author = {Jena, Rohit and Chaudhari, Pratik and Gee, James C.},
journal = {arXiv preprint arXiv:2404.01249},
year = {2024},
url = {https://arxiv.org/abs/2404.01249}
}Full attribution, the required bibliography and every other dependency's licence are in
THIRD_PARTY_NOTICES.md.
Three panels: Moving (the image being registered), Template (the fixed reference) and Warped (the output, on the template grid). Choose presets from the dropdowns or drag and drop your own NIfTI onto the first two panels, pick a transform, press Go. Nothing runs until you do — a SyN run is tens of seconds, so it is not live.
The moving image must be brain-extracted, like the template. Registering a skull-on image to a brain-only template does not merely degrade: the optimiser latches onto the scalp (on one 2 mm scan, global NCC 0.67 skull-on versus 0.96 stripped). The skull-on presets are there to be run through Brain Extract first, which strips them with MindGrab on the GPU in a few seconds.
Every stage uses cross-correlation, not the engine's default of mutual information for the linear ones. MI is the robust choice for whole heads, but everything here is brain-extracted, and on such a pair CC is both better and faster — on the bundled 2 mm pair, global NCC 0.9616 against 0.9410, and 2.2x quicker.
Requires a browser with WebGPU (recent desktop Chrome, Edge or Safari) — NiiVue draws with it. The Use GPU (WebGPU) checkbox, off by default, also runs cfireants itself through WebGPU; left off, the automatically selected threaded or single-threaded CPU wasm build does the work. Both paths use the same Gaussian/trilinear image pyramid so their numerical results remain comparable.
The threaded wasm build needs SharedArrayBuffer, which needs a cross-origin isolated
page, which needs COOP/COEP response headers that GitHub Pages will not send. So the site
installs coi-serviceworker, which re-serves
the document with those headers; the first visit reloads once while the service worker takes
control. The toolbar badge says which build is live: mt (threaded), st, or gpu when the
GPU box is ticked. Without the service worker the fallback is silent and expensive: the
default pair takes roughly 55 s threaded and several minutes single-threaded, at the same
quality. Against the 2 mm template, still selectable from the Template dropdown, the same
moving image is about 14 s threaded and 85 s single-threaded.
The 2 mm moving preset is slower than the 1 mm one, and that is not a typo. The default
moving image is T1 brain 2mm at roughly 55 s; T1 brain 1mm is roughly 40 s. Cost tracks
the template, which is 1 mm in both cases — every displacement field, optimiser moment
and correlation buffer lives on the template grid. The 2 mm moving image adds nothing to
that but makes each scale a mismatched-spacing case, where the moving volume is resampled
onto a finer grid than it was sampled at. Pairing a 2 mm moving image with the 2 mm
template is the fast combination.
WebGPU is not the fast path in the browser. Asyncify suspension and the stages still on the CPU (warp inversion, and the downsampling this app forces to trilinear so both backends take the same path) cost more at this size than the GPU saves; natively, where neither applies, WebGPU is the quickest backend cfireants has on this machine. What the browser GPU build does buy is that it needs no cross-origin isolation, so where COOP/COEP cannot be arranged at all it is the fast path by default.
bun install
bun run dev # http://localhost:8092
bun run build # -> dist/
bun run test:e2e # Playwright end-to-end smoke (needs system Chrome)The wasm engine is not on the npm registry; package.json installs it from the tarball
attached to a cfireants GitHub release,
which bun install pins by URL and hash in bun.lock like any other dependency. To move to
a newer engine, change that URL. scripts/copy-*.mjs stage the wasm glue into public/ (Vite cannot
rewrite emscripten's computed-URL loads), and .github/workflows/ghpages.yml builds and
publishes dist/ to the gh-pages branch.
FireANTs License version 1.0 — see LICENSE. Section 4 requires that any
redistribution keep the copyright notices, the licence text and the bibliography; they are
in THIRD_PARTY_NOTICES.md.