Gramlot pre-alpha · First usable release planned for late 2026
gramlot.

One textBox. All the code.

Start with one field. See what describes the page and what starts the runtime.

Try the field

Edit the name, then leave the field to apply it. Reload restores “World”.

1. The recipe recipe.js

export function build(root) {
  root.data('name', 'World');
  root.textBox({value: '^name', lbl: 'Your name'});
}
Line 1 · build(root)
The site's entry convention: receive a root to build into. This function is called by the startup code below.
Line 2 · root.data
Set the starting value of name. This is sample data, not startup machinery.
Line 3 · root.textBox
Create the field. ^name connects its value to the data; lbl supplies its label.
Line 4 · }
Close the function.

2. Starting Gramlot app.js

This code is also executed. It is shared setup, but it still exists.

import {Application} from 'gramlot-dom';
import {GramlotBuilder} from 'gramlot-builder';
import {build} from './recipe.js';

class Page extends GramlotBuilder {
  main(root) { build(root); }
}

const app = new Application(
  document.getElementById('demo-root'), new Page('hello'), {inspector: false}
);
window.addEventListener('pagehide', event => { if (!event.persisted) app.dispose(); });
Lines 1–3 · Imports
Load the runtime, the builder and the recipe.
Lines 5–7 · Page class
Connect the recipe's build function to the builder's main method. This extra bridge comes from the site's split-file convention.
Lines 9–11 · Application
Find the HTML host, build the page and mount it. The inspector is explicitly disabled for this small example.
Line 12 · Cleanup
Release the application when leaving the page, while preserving browser back/forward cache behavior.

3. The HTML host

<div id="demo-root"></div>

This empty element is where Gramlot places the field. The rest of this page supplies explanations and styling; it is not part of the recipe.