Skip to main content

Gramlot

Gramlot

Core tests Documentation build JavaScript coverage Python coverage PyPI JSR Status: 0.2.19 released License: Apache 2.0

Describe application interfaces in Python; let a JavaScript runtime handle interaction in the browser. Gramlot's model connects a declared interface (Source) to structured application state (Data Bags), using bindings, controllers and reusable components.

Gramlot is intended for Python developers building interactive forms, data tools and application interfaces. Server adapters connect it to a web server; the core is independent of server and database technology.

Release status. The current release is 0.2.19, published on PyPI (gramlot), on npm and JSR (@gramlot/gramlot) and as the GitHub release v0.2.19. 0.2.0 (HTML/SVG data binding), released on 2026-09-30, was qualified on Chromium, WebKit and Firefox and accepted by the owner; the patch releases that follow it keep its contract.

JavaScript package

The JavaScript distribution is @gramlot/gramlot, on npm and on JSR. Install it with npm install @gramlot/gramlot or npx jsr add @gramlot/gramlot. Node.js 22 or later and Bun are supported server runtimes; the browser runtime is bundled separately. The core provides server, gramlot-server, page and runtime. Standalone startup, WorkerHost and WorkerTransport belong to @gramlot/gramlot-serverless (in the gramlot-js-server repository). Python pages require the Python distribution and a Python server.

A page is a module in the pages folder that exports a Page subclass. GramlotFileServer serves that folder; an adapter passes each request to the server:

// pages/hello.js
import {Page as GramlotPage} from '@gramlot/gramlot/page';

// GramlotFileServer reads the export named `Page`.
export class Page extends GramlotPage {
    static title = 'Hello';
    main(root) {
        root.div('Hello from Gramlot', {id: 'greeting'});
    }
}
// server.js
import {GramlotFileServer} from '@gramlot/gramlot/server';

const server = new GramlotFileServer('./pages');
const {pageId, html, nonce} = await server.openPage('hello');
// Answer the browser with `html`; it then sends its envelopes to `POST /gramlot/rpc`,
// which the adapter answers with `server.call(text, {owner})`.

The example pages and their gallery are the separate package gramlot-examples.

Can I use it today?

  • Python: pip install gramlot.
  • JavaScript: npm install @gramlot/gramlot or npx jsr add @gramlot/gramlot.
  • Archives: each GitHub release carries the wheel, the sdist, the npm package of js/ and SHA256SUMS.
  • Adapters: pip install "gramlot-py-server[uvicorn]" (also django, flask, fastapi, kajenn) for Python pages; npm install @gramlot/gramlot-js-server (Node.js and Bun) or @gramlot/gramlot-serverless (no server) for JavaScript pages; npm create @gramlot page|site starts a JavaScript project.

For a first look, use Try Gramlot: the quick route: choose Python, Node.js or serverless, open the gallery, then create your own page. It also explains how to install the optional Chrome DevTools extension. Continue with the learning route and Writing pages. The broader experimental implementation remains in gramlot-poc.

Gramlot 0.2.0

0.2.0 adds HTML/SVG data binding to the Gramlot core. The DOM depends on the Source and the Data; Data changes reach the DOM, and native controls write back.

  • dataSetter(destination_path, value=None, **attr) writes initial Data values, replacing the legacy data(path, value); the HTML5 <data> element is html_data(...);
  • ^, = and == pointers, relative, symbolic and ?attr paths, variable datapaths;
  • dataFormula and dataController, with named logic as the primary path (since 0.2.5 the Logic class exported by the page module foo.js, beside foo.py for a Python page, or class Logic in foo_aux.js) and inline code only under a permissive Content Security Policy (a clear error under a strict one);
  • native controls bound with value='^path', live, checkbox and radio groups, visible, reactive style and class, bound SVG attributes, freeze and thaw;
  • buttons with a nested dataController and connect_on<event>;
  • a minimal GramlotServer contract (resolve_page, resolve_resources, open_page with a mount prefix) with GramlotFileServer as reference; pages keep Page.css and same-name companions (foo.css, and foo.js or foo_aux.js for the logic).

Examples: the families binding and controllers of gramlot-examples, each page in Python with its JavaScript equivalent. Writing pages and Classes and server adapters describe the contract, its exclusions and the differences from legacy GenroPy. Components start with 0.3.0.

Start here

Project status

The tests badge reports the Core tests workflow on main (Python and JavaScript suites and the browser checks in Chromium); the documentation badge reports the documentation checks. Coverage is collected by the same workflow and reported on Codecov per runtime: JavaScript (every file of js/src, including files no test imports) and Python (src/gramlot), never merged into one figure. See Tests and coverage.

Maintainers keep architecture decisions, port reviews and concise working documents in the repository, outside the public user manual. Public source files remain readable on GitHub. New work starts from develop; main is the consolidated reference. Gramlot is licensed under Apache 2.0.

Integration repositories

Environment-specific adapters and setup instructions live in two repositories:

  • gramlot-py-server (PyPI gramlot-py-server) serves Python pages. One package holds five adapters, one extra each: uvicorn (any ASGI server), django, flask, fastapi and kajenn. Its command gramlot <environment> new|gallery creates a project or serves the gallery.
  • gramlot-js-server serves JavaScript pages with three npm packages: @gramlot/gramlot-js-server (Node.js and Bun, command gramlot), @gramlot/gramlot-serverless (pages in a browser Worker without a server, command gramlot-serverless) and @gramlot/create (npm create @gramlot page|site).

The example pages and the gallery are in gramlot-examples. The earlier adapter repositories (gramlot-uvicorn, gramlot-django, gramlot-fastapi, gramlot-flask, gramlot-kajenn, gramlot-serverless, gramlot-minimal) are archived. See the ownership contract. The published 0.1.0 archives keep their original names.

Reusable application index and installable root shows Python-first authoring, a custom footer, iframe tabs and the root manifest.

Development work on publish/subscribe, authored references and native ask is documented in the authoring guide. This is not a release announcement.

Metadata

Release files for gramlot 0.2.19

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gramlot 0.2.19
File Size Uploaded
gramlot-0.2.19.tar.gz 510.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gramlot 0.2.19
File Interpreter ABI Platform
gramlot-0.2.19-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / gramlot-0.2.19.tar.gz

Download URL gramlot-0.2.19.tar.gz
Size 510.8 kB
Tags Source
SHA-256 checksum
How to use checksums
97d6f85f1b9d97fbb9d5edf606d2e50245e156c97021aad8c1e61dc7aa029fbe
BLAKE2b-256 checksum
How to use checksums
bd2cad53bfa210698509e31d65837b95c608865c39a879122d3f3c58067ec9c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / gramlot-0.2.19-py3-none-any.whl

Download URL gramlot-0.2.19-py3-none-any.whl
Size 570.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
58f4416319a1625b15d4607d04a2da4e8b15db821589e356841c60440b9e035b
BLAKE2b-256 checksum
How to use checksums
19ed08e1f078d4c4133c0f2c9ccaf7bf3539a72c0c45cf4cfeb151e0fcbb82d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page