{"id":13510114,"url":"https://github.com/observablehq/runtime","last_synced_at":"2025-05-14T01:05:57.156Z","repository":{"id":37887228,"uuid":"90051414","full_name":"observablehq/runtime","owner":"observablehq","description":"The reactive dataflow runtime that powers Observable Framework and Observable notebooks","archived":false,"fork":false,"pushed_at":"2024-11-06T05:48:59.000Z","size":1255,"stargazers_count":1034,"open_issues_count":5,"forks_count":74,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-04-06T10:01:29.619Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://observablehq.com/@observablehq/how-observable-runs","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/observablehq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-02T15:53:56.000Z","updated_at":"2025-03-30T21:58:41.000Z","dependencies_parsed_at":"2022-07-14T22:00:29.729Z","dependency_job_id":"f0223658-f5f9-4425-99ba-85cbd2b9dea8","html_url":"https://github.com/observablehq/runtime","commit_stats":{"total_commits":767,"total_committers":13,"mean_commits":59.0,"dds":"0.29074315514993476","last_synced_commit":"de9b37365cf869fed6ccecd9e85e84c272e5ff5f"},"previous_names":["observablehq/notebook-runtime"],"tags_count":151,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/observablehq%2Fruntime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/observablehq%2Fruntime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/observablehq%2Fruntime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/observablehq%2Fruntime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/observablehq","download_url":"https://codeload.github.com/observablehq/runtime/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717238,"owners_count":21150389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:01:24.598Z","updated_at":"2025-04-13T13:11:13.034Z","avatar_url":"https://github.com/observablehq.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"# @observablehq/runtime\n\nThe **Observable Runtime** implements reactivity in both [Observable Framework](https://observablehq.com/framework/) and [Observable notebooks](https://observablehq.com/documentation/notebooks/).\n\n## API Reference\n\n### Runtimes\n\n#### new Runtime(*builtins*, *global*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/runtime.js) · Returns a new [runtime](#runtimes). 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](#variable_define) on any [module](#modules) 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.\n\nTo specify a custom set of builtins:\n\n```js\nconst runtime = new Runtime({color: \"red\"});\n```\n\nTo refer to the `color` builtin from a variable:\n\n```js\nconst module = runtime.module();\nconst inspector = new Inspector(document.querySelector(\"#hello\"));\nmodule.variable(inspector).define([\"color\"], color =\u003e `Hello, ${color}.`);\n```\n\nThis would produce the following output:\n\n\u003e Hello, red.\n\nUnlike [variables](#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.\n\n#### *runtime*.module(*define*, *observer*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/runtime.js) · Returns a new [module](#modules) for this [runtime](#runtimes).\n\nIf *define* is specified, it is a function which defines the new module’s [variables](#variables) by calling *runtime*.module (with no arguments) and then calling [*module*.variable](#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.\n\nIf an *observer* factory function is specified, it is called for each named variable in the returned module, being passed the variable’s name.\n\n#### *runtime*.dispose()\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/runtime.js) · Disposes this runtime, invalidating all active variables and disabling future computation.\n\n### Modules\n\nA module is a namespace for [variables](#variables); within a module, variables should typically have unique names. [Imports](#variable_import) allow variables to be referenced across modules.\n\n#### *module*.variable(*observer*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · Returns a new [variable](#variables) for this [module](#modules). The variable is initially undefined.\n\nIf *observer* is specified, the specified [observer](#observers) will be notified when the returned variable changes state, via the [observer.*pending*](#observer_pending), [observer.*fulfilled*](#observer_fulfilled) and [observer.*rejected*](#observer_rejected) methods. See the [standard inspector](https://github.com/observablehq/inspector/blob/master/README.md) for a convenient default observer implementation.\n\nA 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](#variable_import)): only the needed variables from imported modules are computed.\n\n#### *module*.derive(*specifiers*, *source*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · Returns a derived copy of this [module](#modules), where each variable in *specifiers* is replaced by an [import](#variable_import) from the specified *source* module. The *specifiers* are specified as an array of objects with the following properties:\n\n* *specifier*.name - the name of the variable to import from *source*.\n* *specifier*.alias - the name of the variable to redefine in this module.\n\nIf *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:\n\n```js\nconst module0 = runtime.module();\nmodule0.variable().define(\"a\", 1);\nmodule0.variable().define(\"b\", 2);\nmodule0.variable().define(\"c\", [\"a\", \"b\"], (a, b) =\u003e a + b);\n```\n\nTo derive a new module that redefines *b*:\n\n```js\nconst module1 = runtime.module();\nconst module1_0 = module0.derive([\"b\"], module1);\nmodule1.variable().define(\"b\", 3);\nmodule1.variable().import(\"c\", module1_0);\n```\n\nThe 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.\n\n#### *module*.define(*name*, *inputs*, *definition*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · A convenience method for [*variable*.define](#variable_define); equivalent to:\n\n```js\nmodule.variable().define(name, inputs, definition)\n```\n\n#### *module*.import(*name*, *alias*, *from*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · A convenience method for [*variable*.import](#variable_import); equivalent to:\n\n```js\nmodule.variable().import(name, alias, from)\n```\n\n#### *module*.builtin(*name*, *value*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · 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:\n\n```js\nmodule.builtin(\"FileAttachment\", (name) =\u003e FileAttachment(name))\n```\n\n#### *module*.redefine(*name*, *inputs*, *definition*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · 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.\n\n#### *module*.value(*name*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/module.js) · 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.\n\n### Variables\n\nA 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](#modules) and evaluated by a [runtime](#runtimes).\n\n#### *variable*.define(*name*, *inputs*, *definition*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/variable.js) · 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](#variable_import)) 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*.\n\nThe *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.\n\nFor example, consider the following module that starts with a single undefined variable, *a*:\n\n```js\nconst runtime = new Runtime(builtins);\nconst module = runtime.module();\nconst a = module.variable();\n```\n\nTo define variable *a* with the name `foo` and the constant value 42:\n\n```js\na.define(\"foo\", 42);\n```\n\nThis is equivalent to:\n\n```js\na.define(\"foo\", [], () =\u003e 42);\n```\n\nTo define an anonymous variable *b* that takes `foo` as input:\n\n```js\nconst b = module.variable();\n\nb.define([\"foo\"], foo =\u003e foo * 2);\n```\n\nThis is equivalent to:\n\n```js\nb.define(null, [\"foo\"], foo =\u003e foo * 2);\n```\n\nNote 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.\n\nIf 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](#variable_delete), or are redefined to have unique names, the original definition of the remaining variable (if any) is restored. For example, here variables *a* and *b* will throw a ReferenceError:\n\n```js\nconst module = new Runtime(builtins).module();\nconst a = module.variable().define(\"foo\", 1);\nconst b = module.variable().define(\"foo\", 2);\n```\n\nIf *a* or *b* is redefined to have a different name, both *a* and *b* will subsequently resolve to their desired values:\n\n```js\nb.define(\"bar\", 2);\n```\n\nLikewise deleting *a* or *b* would allow the other variable to resolve to its desired value.\n\n#### *variable*.import(*name*, *alias*, *module*)\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/variable.js) · Redefines this variable as an alias of the variable with the specified *name* in the specified [*module*](#modules). The subsequent name of this variable is the specified *name*, or if specified, the given *alias*. The order of arguments corresponds to the standard import statement: `import {name as alias} from \"module\"`. For example, consider a module which defines a variable named `foo`:\n\n```js\nconst runtime = new Runtime(builtins);\nconst module0 = runtime.module();\nmodule0.variable().define(\"foo\", 42);\n```\n\nTo import `foo` into another module:\n\n```js\nconst module1 = runtime.module();\nmodule1.variable().import(\"foo\", module0);\n```\n\nNow the variable `foo` is available to other variables in *module1*:\n\n```js\nmodule1.variable().define([\"foo\"], foo =\u003e `Hello, ${foo}.`);\n```\n\nThis would produce the following output:\n\n\u003e Hello, 42.\n\nTo import `foo` into *module1* under the alias `bar`:\n\n```js\nmodule1.variable().import(\"foo\", \"bar\", module0);\n```\n\n#### *variable*.delete()\n\n[Source](https://github.com/observablehq/runtime/blob/main/src/variable.js) · Deletes this variable’s current definition and name, if any. Any variable in this module that references this variable as an input will subsequently throw a ReferenceError. If exactly one other variable defined this variable’s previous name, such that that variable throws a ReferenceError due to its duplicate definition, that variable’s original definition is restored.\n\n### Observers\n\nAn observer watches a [variable](#variables), being notified via asynchronous callback whenever the variable changes state. See the [standard inspector](https://github.com/observablehq/inspector) for a reference implementation.\n\n#### *observer*.pending()\n\nCalled shortly before the variable is computed. For a generator variable, this occurs before the generator is constructed, but not before each subsequent value is pulled from the generator.\n\n#### *observer*.fulfilled(*value*)\n\nCalled shortly after the variable is fulfilled with a new *value*.\n\n#### *observer*.rejected(*error*)\n\nCalled shortly after the variable is rejected with the given *error*.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobservablehq%2Fruntime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobservablehq%2Fruntime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobservablehq%2Fruntime/lists"}