webR Documentation

repository·main·Indexed 21 days ago

https://github.com/r-wasm/webr

webR compiles the R statistical programming language into WebAssembly using Emscripten, enabling R to run directly in web browsers and Node.js. It includes a web-based IDE, a JavaScript package for integration via npm or CDN, and the webr R package as a high-level interface to the runtime. The project provides tools for building from source, Docker and Nix support, and APIs for implementing REPL interfaces for files, plotting, and terminal communication.

Tokens
10.2K
Snippets
39
Records
52
Agent score
77%

What's inside webR

  1. Understand the role of the webr package

    main

    The webr package serves as the primary interface to webR. It provides supporting functions for managing and interacting with the underlying R session within the browser.

    Note that the webr package is automatically bundled as part of the standard webR distribution; you do not need to perform a manual installation to use it.

  2. Build webR from source

    main

    To build webR from source, ensure you have the required prerequisites installed and then follow the configure and make process. A dist directory will be created containing the R Wasm files and an index.html file for the webR IDE.

    ./configure && make
  3. Build webR using Docker

    main

    Use the included Dockerfile to set up a complete build environment including LLVM flang and all supported WebAssembly system libraries. You can also use pre-built images from GitHub Packages.

    docker build .
  4. Build additional WebAssembly system libraries

    main

    By default, webR builds a minimal set of libraries. To build all available system libraries (which enables Cairo graphics support and support for R packages depending on specific system libraries), follow these steps:

    1. cd libs
    2. make all
    3. cd ..
    4. make clean-webr && make
    cd libs && make all && cd .. && make clean-webr && make
  5. Install webR via npm or CDN

    main

    To use webR in your own projects, you can install the JavaScript package via npm or load it from a CDN. For self-hosting complete release packages (including R WebAssembly binaries), download them from the GitHub Releases section.

    npm install webr
  6. Overview of the webr R package

    main

    The webr R package serves as a high-level interface to the webR runtime. It provides supporting functions designed to interact with and manage the underlying R session running in the browser.

    Note: This package is automatically bundled as part of the standard webR distribution and typically does not require manual installation.

  7. Understand WebR data type mappings and structures

    main

    webR uses specific type mappings to bridge R objects and JavaScript. When working with data passed between the R environment and JavaScript, you will encounter several key data structures:

    R Type Mappings

    The RTypeMap defines the integer identifiers for various R types. This is useful when inspecting raw R object types.

    WebRData vs WebRDataJs

    • WebRData: A broad union type representing data that can be converted into an R object or is the result of converting an R object to JavaScript. It includes scalars, arrays, maps, and complex objects.
    • WebRDataJs: A structured tree format used specifically when serializing R objects into a JavaScript representation. This format is used to preserve the structure of nested R objects (like lists or environments) in a way that JavaScript can traverse.

    WebRDataJs Structure

    WebRDataJs objects use a type field to identify their structure:

    • null: { type: 'null' }
    • string: { type: 'string', value: string }
    • symbol: { type: 'symbol', printname: string | null, symvalue: RPtr | null, internal: RPtr | null }
    • list | pairlist | environment: { type: '...', names: (string | null)[] | null, values: [...] }
    • logical | integer | double | complex | character | raw: { type: '...', names: (string | null)[] | null, values: [...] }

    Utility Functions

    • isWebRDataJs(value): Returns true if the object follows the WebRDataJs serialization format.
    • isComplex(value): Returns true if the object is a Complex type (containing re and im properties).
    // Example of checking for WebRDataJs structure
    if (isWebRDataJs(myData)) {
      console.log(myData.type);
      console.log(myData.values);
    }
    
    // Example of checking for a complex number
    const c = { re: 1, im: 2 };
    if (isComplex(c)) {
      console.log(c.re, c.im);
    }
  8. Structure of a ShareItem

    main

    A ShareItem represents a single file to be shared within a webR session. It defines the file's identity, its location in the Emscripten Virtual File System (VFS), and its content.

    Each item must include:

    • name: A display name (typically the filename).
    • path: The destination path where the file will be written to the Emscripten VFS.

    Content is provided via one of the following:

    • text: A string containing the file content.
    • data: A Uint8Array containing binary data.

    Optional fields:

    • autorun: A boolean indicating if the file should be automatically executed (typically for .r scripts).
    export type ShareItem = {
      name: string;
      path: string;
      data?: Uint8Array;
      text?: string;
      autorun?: boolean;
    };
  9. Share data via postMessage()

    main

    The webR application can receive shared files through the postMessage() API. To trigger the application to apply shared content to the current editor, send a message with a data property containing an object with an items key, where items is an array of ShareItem objects.

    Message Format:

    {
      "items": [
        { "name": "file.R", "path": "/file.R", "text": "print('hello')" }
      ]
    }
  10. Understand RProxy for interacting with R objects

    main

    When working with webR, R objects reside on a worker thread. To manipulate these objects from the main JavaScript thread, you use an RProxy.

    An RProxy<T> acts as a transparent wrapper around an R object. It provides the same method interface as the underlying R object type T, but with several key differences designed for asynchronous cross-thread communication:

    1. Asynchronous Methods: All method calls return a Promise.
    2. Proxied Arguments: Methods accept RProxy instances instead of raw RObject types, allowing you to pass R objects into other R functions seamlessly.
    3. Proxied Return Values: If a method returns another R object, the proxy returns an RProxy for that new object.
    4. Direct Payload Access: You can access the underlying WebRPayloadPtr via the _payload property if you need low-level access to the object's reference.
    5. Async Iteration: If the R object has a length (e.g., a vector), the proxy implements [Symbol.asyncIterator], allowing you to use for await...of syntax to iterate over its elements.
    // Example of iterating over an R object using the proxy's async iterator
    for await (const element of rProxyObject) {
      console.log(element);
    }
  11. Mounting data with WORKERFS in webR

    main

    When using the WORKERFS filesystem type in webR, you cannot use standard Emscripten mounting methods directly for data. Instead, you must provide data via the packages key in the FSMountOptions object. Each package in the array must contain a blob (the file data) and metadata (the FSMetaData describing the file structure).

    If you attempt to mount WORKERFS without the packages key, the system will throw an error: "Can't mount data. You must use the packages key when mounting with WORKERFS in webR.".

    // Example of the required structure for WORKERFS mounting
    // Note: This is the internal shape required by the mountFS function
    const opts = {
      packages: [{
        blob: someBlob,
        metadata: someMetadata
      }]
    };