@gomani/core
v0.2.0
Published
Component model, JSX runtime, and the compiler-owned island boundary.
Maintainers
Readme
@gomani/core
The component model of Gomani: a tiny isomorphic VNode/JSX layer, the island boundary, and the zero-JavaScript server renderer.
Everything outside an island renders to static HTML with no client JavaScript (P2). Each island is
an independent unit whose client cost is paid only when the user reaches it (P3). This package is the
shared lowering target: the constrained-JSX surface here and the future .goma compiler produce the same VNodes and the same island markers, so there is one runtime, not two.
Authoring
Point TypeScript/esbuild at the runtime with jsxImportSource: "@gomani/core", then write components as
plain props → node functions. Reactivity comes from @gomani/signals, not a
VDOM.
import { signal } from '@gomani/signals';
import { island } from '@gomani/core';
function Counter({ start = 0 }: { start?: number }) {
const count = signal(start);
return (
<button type="button" onClick={() => count.value++}>
{count}
</button>
);
}
// Mark it interactive. Everything else on the page stays zero-JS.
export default island(Counter, { name: 'counter', strategy: 'interaction' });Server render
import { renderToString } from '@gomani/core';
const { html, islands } = renderToString(<Page />);htmlis static HTML. Non-islands ship no JS and no event handlers; a signal read for SSR is snapshotted (never subscribed). Output is deterministic, so identical input is byte-identical.- Each island renders its real initial HTML (the page is correct before any JS) wrapped in a
transparent
<gomani-island style="display:contents">marker carrying itsname, loadstrategy, and JSON-serialized props. islandslists exactly what the page contains, so the build/server ships only the chunks it needs. Handislands(and their chunk URLs) to@gomani/runtimeto hydrate on demand.
Island load strategies
load · idle · visible (default) · interaction · media. The default loads nothing until the
island scrolls into view — the constraint-first default.
Degradation
An island rendered by an island-unaware renderer (or called directly) simply renders the underlying component — server HTML, no interactivity. Heaviness degrades, never breaks (P7).
License
MIT © Venancio Gomani / Kwacha Kulture.
