# webR: the R statistical language compiled to WebAssembly

> webR compiles R to WebAssembly through Emscripten, with a set of patches to R's own source so that it can run in a browser environment, and it ships a web based IDE built on xterm.js and CodeMirror. Building it from source is a serious undertaking, because R is C, C++ and Fortran, and the README is unusually candid about which toolchain versions have to line up.

**r-wasm/webr** — The statistical language R compiled to WebAssembly via Emscripten, for use in web browsers and Node.

- Repository: https://github.com/r-wasm/webr
- Website: https://docs.r-wasm.org/webr/latest/
- Stars: 1,102 · Forks: 101
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/r-wasm-webr

## R with patches, not a reimplementation

webR aims to compile the statistical language R into WebAssembly for use with a browser, via Emscripten, and the repository includes patches to R's source code so that it can work in the browser environment provided by Emscripten. It also includes a web based IDE through the use of xterm.js and CodeMirror.

The distinction in that last sentence matters. webR is not a JavaScript library that reimplements a statistical language, and it is not a remote R service that the browser calls. It is R itself, compiled to WebAssembly, with the changes needed to survive in a browser tab. That is why the package list in the ecosystem, the semantics of R's lazy evaluation and its copy on modify behaviour, and the exact numeric results are the same as on a native build.

The cost of that fidelity is that you inherit R's whole build, which is C, C++ and Fortran, and you inherit R's assumptions about a POSIX system that a browser does not have. The patches are the record of how much of that had to change.

The project is MIT licensed according to the repository metadata, the documentation lives at docs.r-wasm.org/webr/latest, and the last push was on 2026-10-13. The releases are v0.6.0 from 2026-05-19, v0.5.9 from 2026-04-17 and v0.5.8 from 2025-12-08, so the version line is still in the pre one range.

## Three ways to get it, and a demo that tells you to wait

The distribution section lists three routes, and the demo is worth trying before any of them.

The demo of the webR IDE is at webr.sh, and the README asks you to be patient as the Wasm runtime downloads and executes, noting that R will display a banner message when it is ready to use. That banner is the whole startup model in one sentence: the runtime is a large binary that has to be fetched before anything happens, which is the main thing to understand about running R in a browser.

For real use, the webR JavaScript package is on npm and on a CDN, and the download documentation has a page for each. For self hosting, complete release packages including the R WebAssembly binaries are in the GitHub Releases section, and for a development environment there are Docker images containing a pre-built webR setup in the GitHub Packages section.

So there are three distinct artefacts here and they are not interchangeable. The npm package is the library, the release packages include the R WebAssembly binaries so you can serve them yourself, and the Docker images are build environments rather than runtime images.

The project is also built on the assumption that you might want to run it in Node rather than a browser, since the repository description says the language is compiled for use in web browsers and Node.

## Fortran is the part that makes the build hard

The build section opens with the reason this project is not a weekend project. R's source code and supporting libraries are written in both C and C++ and Fortran, and the sources can be compiled with either a custom development version of LLVM flang, which is the default, or with gfortran and Dragonegg using the --with-dragonegg configure option.

The default toolchain is a fork of LLVM's Fortran frontend maintained for this project, which tells you that the stock compilers do not do what R needs in a WebAssembly target. Dragonegg is the escape hatch, and it comes with its own cost, described later in the README.

The prerequisites for the default toolchain are a specific list: the Emscripten SDK at 3.1.35 or newer, cmake, gperf, liblzma, libpcre2, node at 17.0.0 or newer, quilt and wget. Quilt is there because the build applies patches to R's source, which is what quilt is for, and gperf is there because R generates some of its parsers.

The build itself is the familiar configure and make.

```bash
./configure && make
```

You can configure make variables in a ~/.webr-config.mk file, and the result is a dist directory containing the R Wasm files and an index.html file ready to serve the included webR IDE.

The Makefile in the repository shows the same structure in code: the default target builds the R part with cd R and make and make install, then builds the JavaScript side with cd src and make, and the libs target compiles the supporting libraries in the libs directory.

## The Node and Emscripten version trap, spelled out

There is a section on Node and Emscripten versioning, and it is the most useful troubleshooting note in the README.

webR requires compiler and runtime support for WebAssembly.Exception, which is used internally for R error handling. That requires Emscripten 3.1.35 or newer and Node 17.0.0 or newer, and the README warns these may be newer than the versions your system package manager provides, suggesting nvm and emsdk to install and manage several versions of each.

Then it names the specific failure. The version of Node currently bundled by emsdk is 16.0.0, and building webR with it fails with configure logs containing a specific error.

```
WebAssembly.Tag is not a constructor
```

The fix is to install a newer Node and point Emscripten at it with an environment variable.

```bash
export EM_NODE_JS=$(HOME)/.nvm/versions/node/v20.1.0/bin/node
```

And if you are unsure of the path, the README says the which node command should print the path in full.

This is the kind of documentation that saves hours. The error message does not say anything about Node or about WebAssembly.Exception, it says something about a constructor, and without the note the natural response is to go looking for a problem in the WebAssembly output.

## Docker, Nix, and the fake Rust packages

There are three build environments described, and the Dockerfile is the most interesting of them.

The included Dockerfile sets up everything the webR build needs, including LLVM flang and all supported WebAssembly system libraries, and pre-built images are in the GitHub Packages section. To build the image and webR from source you cd into the source directory and run docker build ., and the resulting image contains a version of R configured to be built for WebAssembly, which also means the image can be used to build custom R packages for webR. The Makefile has matching targets, a one-shot docker-webr target that builds and runs the container with the working directory mounted, and a docker-container-% target that creates a persistent development container.

The Dockerfile's own first step is a curiosity worth naming. Before installing anything, it builds fake Rust DEB packages with equivs, one that claims to be rustc and one that claims to be cargo, so that the toolchain installed later is used instead of the one the Ubuntu distribution provides. It is a hack, and it is there because the distro's Rust is the wrong Rust for a WebAssembly target.

For Nix users, the answer is nix develop, which gives a development environment and then the usual configure and make. The README notes this requires flake support in your Nix installation and points at the Determinate Systems installer as the easiest route.

## The system libraries decide what graphics you get

webR relies on additional libraries compiled for Wasm, both for Cairo graphics support and for building R packages that depend on certain system libraries, and by default only a minimal set of libraries are built.

If you want all of the available system libraries for Wasm, the README gives the sequence: cd into the libs directory and run make all, then cd back and run make clean-webr and make to rebuild webR. R will then automatically detect the additional Wasm libraries and integrate Cairo graphics support as part of the build.

That last detail, the automatic detection, is worth knowing because it means the build order matters and the rebuild is not optional. Running make all in libs and then rebuilding webR without the clean would leave the R build using the old library set, and the symptom would be missing graphics support rather than an error.

The Makefile reflects the same structure with a libs target that compiles the supporting libraries and a webr target that depends on them, and a clean-wasm target that removes the Wasm R build and the supporting libraries together.

For a browser deployment, this is the knob that decides whether the R you ship can draw anything.

## The macOS patch problem, and the Dragonegg option

Two platform notes close the README, and both are about a toolchain rather than about the code.

The first is macOS. At the time of writing, the version of R used as the base for webR does not build cleanly using the macOS Ventura development SDK. If you are not using the included Dockerfile to build webR, extra setup is needed before starting the build, and the extra step is to install the GNU version of the patch program, for example with brew install gpatch.

That is a very specific instruction, and it is specific because the build applies patches to R's source with quilt, and the BSD patch that macOS ships does not behave the way the build expects. The Dockerfile is the other way out, because it pins its own environment.

The second is Dragonegg. If you intend to build webR using Dragonegg to handle the Fortran sources, older versions of the gcc and gfortran toolchain are required than what modern operating system repositories provide, and the Dockerfile at tools/dragonegg/Dockerfile can be used to set up the required C, C++ and Fortran toolchain and development environment for compiling webR with Dragonegg.

So the two escape hatches have the same shape. Both are Dockerfiles that assemble a toolchain the current distributions do not provide, and both exist because the build needs something specific that a modern base image will not have.

## Conclusion

webR fits a project that wants real R, with its packages and its statistics, running inside a browser tab or a Node process rather than on a server, and that is prepared to depend on a WebAssembly build of R rather than a JavaScript reimplementation. It does not fit a team that needs the full native R package ecosystem, since packages have to be compiled for WebAssembly, and it does not fit a team that cannot host a large binary. Verify three things before you commit to building it yourself: the Emscripten and Node versions, because the required WebAssembly.Exception support pins a minimum of Emscripten 3.1.35 and Node 17 and the Node bundled with emsdk is older than that, the Fortran toolchain, because the default is a custom development build of LLVM flang rather than the gfortran your distribution ships, and the system libraries, because the default build includes only a minimal set and Cairo graphics support needs more.

## FAQ

### What is webR and what does the project include?

It compiles the R statistical language into WebAssembly via Emscripten for use in browsers and Node. The repository includes patches to R's source code so that it can work in the browser environment Emscripten provides, and it includes a web based IDE using xterm.js and CodeMirror, with a demo at webr.sh.

### What do I need to build webR from source?

The Emscripten SDK at 3.1.35 or newer, cmake, gperf, liblzma, libpcre2, node at 17.0.0 or newer, quilt and wget, plus either the custom development version of LLVM flang, which is the default, or gfortran with Dragonegg using the --with-dragonegg configure option. Then run ./configure && make, which produces a dist directory with the R Wasm files and an index.html for the IDE.

### Why does my webR build fail with WebAssembly.Tag is not a constructor?

The version of Node bundled by emsdk is 16.0.0, and webR needs Node 17.0.0 or newer because it relies on WebAssembly.Exception support for R error handling. Install a newer Node, for example with nvm, and set export EM_NODE_JS to its full path before building.

### How do I get Cairo graphics support in webR?

By default only a minimal set of system libraries is built for Wasm. To build them all, cd into the libs directory and run make all, then cd back and run make clean-webr and make to rebuild webR, and R will automatically detect the additional Wasm libraries and integrate Cairo graphics support.

### Can I build webR in a container or with Nix?

Yes. The included Dockerfile sets up everything the build needs, including LLVM flang and all supported WebAssembly system libraries, pre-built images are in the GitHub Packages section, and the image can also be used to build custom R packages for webR. With Nix, nix develop gives a development environment, which requires flakes support and is easiest with the Determinate Systems installer.

## Sources

- [Issues](https://github.com/r-wasm/webr/issues)
- [Project website](https://docs.r-wasm.org/webr/latest/)
- [README](https://github.com/r-wasm/webr/blob/main/README.md)
- [Releases](https://github.com/r-wasm/webr/releases)
- [r-wasm/webr on GitHub](https://github.com/r-wasm/webr)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/r-wasm-webr
