SkillAgentSearch skills...

Runtime

The reactive dataflow runtime that powers Observable Framework and Observable notebooks

Install / Use

/learn @observablehq/Runtime
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

@observablehq/runtime

The Observable Runtime implements reactivity in both Observable Framework and Observable notebooks.

API Reference

Runtimes

new Runtime(builtins, global)

Source · Returns a new runtime. If builtins is specified, each property on the builtins object defines a builtin variable for the runtime. These builtins are available as named inputs to any defined variables on any module associated with this runtime. If a global function is specified, it will be invoked with the name of any unresolved reference, and must return the corresponding value or undefined (to trigger a ReferenceError); if global is not specified, unresolved values will be resolved from the global window.

To specify a custom set of builtins:

const runtime = new Runtime({color: "red"});

To refer to the color builtin from a variable:

const module = runtime.module();
const inspector = new Inspector(document.querySelector("#hello"));
module.variable(inspector).define(["color"], color => `Hello, ${color}.`);

This would produce the following output:

Hello, red.

Unlike variables, builtins cannot depend on the value of other variables or builtins; they are defined with no inputs. If a builtin is defined as a function, it will be invoked lazily to determine the value of the builtin. If you wish for the value of a builtin to be a function, the builtin must be defined either as a promise that resolves to a function or as a function that returns a function. Builtins may also be defined as generators for dynamic values.

runtime.module(define, observer)

Source · Returns a new module for this runtime.

If define is specified, it is a function which defines the new module’s variables by calling runtime.module (with no arguments) and then calling module.variable on the returned module as desired. If this runtime already has a module for the specified define function, the existing module is returned; otherwise, a new module is created, and the define function is called, being passed this runtime and the specified observer factory function. If define is not specified, a new module is created and returned.

If an observer factory function is specified, it is called for each named variable in the returned module, being passed the variable’s name.

runtime.dispose()

Source · Disposes this runtime, invalidating all active variables and disabling future computation.

Modules

A module is a namespace for variables; within a module, variables should typically have unique names. Imports allow variables to be referenced across modules.

module.variable(observer)

Source · Returns a new variable for this module. The variable is initially undefined.

If observer is specified, the specified observer will be notified when the returned variable changes state, via the observer.pending, observer.fulfilled and observer.rejected methods. See the standard inspector for a convenient default observer implementation.

A variable without an associated observer is only computed if any transitive output of the variable has an observer; variables are computed on an as-needed basis for display. This is particularly useful when the runtime has multiple modules (as with imports): only the needed variables from imported modules are computed.

module.derive(specifiers, source)

Source · Returns a derived copy of this module, where each variable in specifiers is replaced by an import from the specified source module. The specifiers are specified as an array of objects with the following properties:

  • specifier.name - the name of the variable to import from source.
  • specifier.alias - the name of the variable to redefine in this module.

If specifier.alias is not specified, it defaults to specifier.name. A specifier may also be specified as a string, in which case the string is treated as both the name and the alias. For example, consider the following module which defines two constants a and b, and a variable c that represents their sum:

const module0 = runtime.module();
module0.variable().define("a", 1);
module0.variable().define("b", 2);
module0.variable().define("c", ["a", "b"], (a, b) => a + b);

To derive a new module that redefines b:

const module1 = runtime.module();
const module1_0 = module0.derive(["b"], module1);
module1.variable().define("b", 3);
module1.variable().import("c", module1_0);

The value of c in the derived module is now 1 + 3 = 4, whereas the value of c in the original module remains 1 + 2 = 3.

module.define(name, inputs, definition)

Source · A convenience method for variable.define; equivalent to:

module.variable().define(name, inputs, definition)

module.import(name, alias, from)

Source · A convenience method for variable.import; equivalent to:

module.variable().import(name, alias, from)

module.builtin(name, value)

Source · Defines a built-in constant that is visible to all variables in this module. Caution: any built-ins must be defined before variables are defined, and must not be redefined after. For example, to define a FileAttachment function:

module.builtin("FileAttachment", (name) => FileAttachment(name))

module.redefine(name, inputs, definition)

Source · Redefines the variable with the specified name on this module. If no such variable exists, or if more than one variable has the specified name, throws a runtime error.

module.value(name)

Source · Returns a promise to the next value of the variable with the specified name on this module. If no such variable exists, or if more than one variable has the specified name, throws a runtime error.

Variables

A variable defines a piece of state in a reactive program, akin to a cell in a spreadsheet. Variables may be named to allow the definition of derived variables: variables whose value is computed from other variables’ values. Variables are scoped by a module and evaluated by a runtime.

variable.define(name, inputs, definition)

Source · Redefines this variable to have the specified name, taking the variables with the names specified in inputs as arguments to the specified definition function. If name is null or not specified, this variable is anonymous and may not be referred to by other variables. The named inputs refer to other variables (possibly imported) in this variable’s module. Circular inputs are not allowed; the variable will throw a ReferenceError upon evaluation. If inputs is not specified, it defaults to the empty array. If definition is not a function, the variable is defined to have the constant value of definition.

The definition function may return a promise; derived variables will be computed after the promise resolves. The definition function may likewise return a generator; the runtime will pull values from the generator on every animation frame, or if the generator yielded a promise, after the promise is resolved. When the definition is invoked, the value of this is the variable’s previous value, or undefined if this is the first time the variable is being computed under its current definition. Thus, the previous value is preserved only when input values change; it is not preserved if the variable is explicitly redefined.

For example, consider the following module that starts with a single undefined variable, a:

const runtime = new Runtime(builtins);
const module = runtime.module();
const a = module.variable();

To define variable a with the name foo and the constant value 42:

a.define("foo", 42);

This is equivalent to:

a.define("foo", [], () => 42);

To define an anonymous variable b that takes foo as input:

const b = module.variable();

b.define(["foo"], foo => foo * 2);

This is equivalent to:

b.define(null, ["foo"], foo => foo * 2);

Note that the JavaScript symbols in the above example code (a and b) have no relation to the variable names (foo and null); variable names can change when a variable is redefined or deleted. Each variable corresponds to a cell in an Observable notebook, but the cell can be redefined to have a different name or definition.

If more than one variable has the same name at the same time in the same module, these variables’ definitions are temporarily overridden to throw a ReferenceError. When and if the duplicate variables are deleted, or are redefined to have unique names, the original definition of the remaining variable (if any) i

View on GitHub
GitHub Stars1.1k
CategoryDevelopment
Updated1d ago
Forks83

Languages

JavaScript

Security Score

95/100

Audited on Mar 30, 2026

No findings