GizStack

GizWeb

Full-stack apps from one typed model.

Declare a record type once. GizWeb derives the table, the form, the validation, the JSON API and the agent tool from it. Pages render on the server, a 1.2 KB kernel adds interaction, and open pages update when the data commits.

Coming In development. This is the design it ships to. Roadmap

One model, every layer

gizlang
import {Table, Key, Label, Min, Max, Trim} from "gizdb:model";

@Table("todos")
export type Todo = {
    @Key id: i64;
    @Label("Title") @Min(1) @Max(200) @Trim title: string;
    @Label("Done") done: bool;
};

Model.shape<Note>() reads the Shape of a type from its declaration at run time: no generated file. From it you get:

LayerWhat GizWeb gives
DatabaseThe table and its migrations. A field rename with @was keeps the data.
FormsAn HTML form with the labels, limits and errors of the fields.
ValidationThe same checks on the server for browsers, the API and agents.
APIJSON input and output with typed rejections (401, 403, 404, 409, 422).
AgentsA tool schema for each Action. Agents call the same Action as people.

Pages are typed markup

gizlang
import {Html, each} from "gizlang:html";

type ListProps = { todos: Vec<Todo>; };
export function TodoList(p: ListProps): Html {
    return <ul>{each(p.todos, (t: Todo) =>
        <li data-k={string(t.id)}><input type="checkbox" checked={t.done}/> {t.title}</li>)}</ul>;
}

Markup in .giz files has TSX syntax. It compiles to escaped HTML, so an injection needs an explicit raw.

Why GizWeb

  • Server HTML is the state

    No hydration and no client framework. The comments app sends 26,157 B (9,448 B gzip) of JavaScript. The same app on Next.js 16 sends 592,598 B (196,717 B gzip).

  • Live views

    A page subscribes to its data. When a row commits, the server sends a patch for the changed elements only. Typed text and focus stay.

  • Actions for people, APIs and agents

    One typed function handles the form post, the JSON call and the agent tool call, with the same checks.

  • One process on every core

    Pages, actions, static files, gzip and realtime in one native process, a worker for each CPU.

  • Web Components

    Declarative shadow DOM from the server, with no build step.

  • Offline and edge

    One call makes an app installable and usable offline. The same app compiles to WebAssembly for an edge fetch handler.

  • A CMS built in

    Markdown collections checked by a model, navigation, llms.txt, sitemaps, drafts and review. This site runs on it.

  • Components and design tokens

    Site headers, docs layouts, tabs, callouts, data regions with loading, empty and failed states, time ranges and log views.

Measured against Next.js 16

Comments app against Next.js 16 2026-10-14. a build host, 16 cores, load average about 7.
GizWebNext.js 16
Start-up to first page66 ms271 ms
Thread page, one CPU (Next.js: one process)1,739 req/s197 req/s
p99 latency, one CPU58.5 ms562 ms
JavaScript sent to the browser26,157 B (9,448 B gzip)592,598 B (196,717 B gzip)
Memory after load (PSS)68.3 MB378 MB

The same threaded realtime comments app on GizWeb and on Next.js 16 (App Router, server actions, node:sqlite): the same pages, actions and session token, and 60 seeded comments. Each server is one process on 8 server CPUs; the load (bench/web/lib/load.c, 32 keep-alive connections) is on 8 other CPUs. GizWeb runs on one server CPU, then on a thread for each server CPU, with GizDB in the process. Throughput is the best of 3 runs.

GizDB in the process (`Data.database`).

These numbers come from our measurement notes of that date. The suite has not recorded them again yet.

This suite needs the GizStack sources, so the release does not carry it yet.

All the rows: benchmarks.

Next steps

  • Build web apps

    Routes, layouts, forms, streaming, static files, sessions, tests and deployment.

  • Model your data

    One record type for the table, typed queries, forms and views.

  • Deploy to GizStack

    Put the app at its own address, and change it live.