DiscordDownload

A tour of Moment's programming model

Moment natively provides a reactive, JavaScript-based programming model. It excels in helping authors quickly write rich, responsive, interactive UI directly into their Moment docs.

This guide will demonstrate the basics of the Moment programming model.

⚠️ This guide assumes you have already created your first Moment doc. If you haven’t, you will want to complete the Create your first doc and Adding interactive components guides.

Insert a JavaScript cell

Moment docs are made of text and executable snippets of JavaScript code called cells. To insert a cell, open a blank Moment doc and click the Insert button in the upper-righthand corner:

Loading...

Search for ”code” and choose the template JavaScript “Hello, World”:

Loading...

This will insert a JavaScript code cell into the document, and open the code editor to show its source. In this case, the cell simply return “Hello world!”.

This is not important yet, but the Moment doc displays code = “Hello world!”, indicating the cell is called code and it currently has a value of the string ”Hello world!”.

Loading...

💡 JavaScript code cells are function bodies. Every cell is expected to return or yield a value. The value that is returned or yielded is displayed in the UI.

Create a simple JavaScript counter

We have a cell that returns a string, let’s try something more interesting. Cells can also yield values, potentially infinitely. In the code editor at the bottom of the page, replace the contents of the cell with the following, and press the Run Cell button:

This will infinitely count upwards, as so:

Cells can reference each other

The cell above has the identifier (sometimes called name) count. count is a valid, document-unique JavaScript identifier. Other cells can reference this identifier to retrieve the results of the cell.

For example, if you insert another JavaScript code cell and paste this code in:

It will produce a live cell that squares the result of the counting cell, code. It will look like this:

For reference, your Moment doc should look like the following:

Loading...

💡 Cells are run in topological order. When the cell count produces a value, any cell that references it is re-run, from scratch. For example, squares will return count * count, so any time count updates its value, squares will run in its entirety, in this case simply returning count * count.

Cells can return HTML and Markdown

Create another JavaScript code cell. Paste the following code into the code editor and click the Run Cell button.

The result will look like the following:

Similarly, you can return Markdown:

This, of course, displays something very similar:

Cells can return React

This next trick looks supervicially similar, but under the hood is a secret super power of the Moment runtime. Paste the following code into a new JavaScript code cell:

This produces the following:

Though the code looks similar to previous examples, this idea is fundamentally different. The code in squares re-runs completely any time count is updated. But in this cell, count is transformed into a React state update.

This saves the author from writing a huge amount of boilerplate:

You can write plain Javascript code.

You can write React code that consumes the results of that code simply by referencing it.

You don’t have to fiddle with React contexts, state, or anything like that. Just write JavaScript, and reference it in React.

Cells can fetch data

Try pasting the following code into a JavaScript code cell and running it:

You will see a result like the following:

Click the arrow to explore the data fetched from the API endpoint.

Cells can import most packages directly from npm

For example, paste this code into a JavaScript code cell and run it:

This will produce a cell like this:

You can then use this library as you would any other JavaScript library.

Cells automatically resolve promises and generators

In a previous example, we saw the following code:

This is a generator function. It will continue to increment the count about once a second, forever. Normally, to evaluate a generator function you’d need to use for await (const … of …), list comprehension, or similar.

In this example, though, the Moment runtime takes care of all this bookkeeping for you. To get the current value of the generator, a cell need only reference it by identifier, e.g., return count * count.

Similarly, in another example, we used a promise:

A cell referencing this result would not need to await at all. It similarly need only reference the cell by name, and the runtime will implicitly await the promise, and run the cell when it’s resolved.