01ONE LANGUAGE, END TO END
The browser platform,
written in TypeScript.
Maya’s templating syntax is TypeScript that reads like HTML. There is no JSX dialect or SCSS layer to learn before you can make a useful interface.
ONE LANGUAGE
A page is just a typed expression.
Markup, behavior, and composition stay together in TypeScript. Native element factories keep the shape familiar while the compiler keeps it honest.
Explore Maya syntax →● ● ●page.ts
import { m } from "@cyftec/maya";
import { signal, tmpl } from "@cyftec/maya/signal";
const count = signal(0);
export default m.Button({
onclick: () => count.value++,
children: tmpl`Count: ${count}`,
});
02STATIC STRUCTURE, DYNAMIC BEHAVIOR
Real pages.
Real DOM.
Maya is MPA-first. Brahma writes static pages, Maya mounts the real DOM, and signals keep the parts that need to move precisely reactive.
MULTI-PAGE BY DEFAULT
Files become pages—not routes in disguise.
A Maya app resembles the durable HTML–CSS–JS web: independent static documents with page-local JavaScript and no client router required.
MPA map3 routes · 0 routers
dev/page.ts→/index.html
dev/docs/page.ts→/docs/index.html
dev/about.page.ts→/about.html
static pagesreactive islands
COMPONENTS + DOM
Compose freely. Reach the node directly.
Component-driven architecture does not put the browser behind a framework escape hatch. Element getters resolve to actual DOM nodes.
● ● ●direct-dom.ts
const panel = m.Article({
children: "Native DOM node",
});
m.Button({
onclick: () =>
panel().toggleAttribute("data-open"),
children: "Toggle panel",
});
CONTROL COMPONENTS
Say If, For, and Switch when that is what you mean.
Built-in control components replace noisy conditional markup. Use them for clarity—or use ordinary TypeScript whenever it fits better.
state
Iftruthy / falsy
Forkeyed lists
Switchnamed cases
Readable control flow is part of the element tree.
04RUNTIME DISCIPLINE
Convenient at author-time.
Careful at run-time.
Maya keeps its low-level promises visible: browser attributes remain typed, keyed nodes keep their identity, and removed subtrees release their reactive work.
TYPED BROWSER CONTRACTS
Autocomplete for the platform—not an invented prop API.
Tag-specific attribute grammars guide valid values in TypeScript. Runtime sanitizers also reject dangerous href schemes and unsafe inline style expressions.
● ● ●typed-elements.ts
m.Input({
type: "email",
required: true,
});
m.Button({ type: "submit" });
m.Link({ rel: "stylesheet" });
// runtime URL/style sanitizers
m.A({ href: trustedUrl });
KEYED BY IDENTITY
Move the list without throwing its nodes away.
Give m.For an itemKey and Maya preserves matching element getters through shuffles and updates, while per-item signals carry the changed data.
before#a · Alpha
#b · Beta
#c · Gamma
shuffle⇢
after#c · Gamma
#a · Alpha
#b · Beta
same nodes · new positions
LIFECYCLE-AWARE
Reactive work ends when its DOM leaves.
When onunmount is used, Maya observes removed subtrees, calls lifecycle listeners from the deepest child upward, and disposes the signal effects attached to those elements.
<section> <card> <button /> </card></section>
→
onunmountcleanup completelistener calledeffects disposed
MutationObserver walks removed subtrees deepest-first.