signal-based · full-stack · ai-native
Reactivity that knows
exactly where to fire.
Fine-grained signal tracking — no virtual DOM, no diffing, no wasted work. When a signal changes, only the nodes that read it run again. Measured, not marketed — honest about the trade-offs.
Synthetic-benchmark parity with Solid. Real-app head-to-head: we haven't run it, and we won't claim it until we do.
// counter.tsx const $count = signal(0) setInterval(() => $count.set($count+1), 2600) <Counter>{$count}</Counter>
The wrapping component, the layout, the page — never re-render. Only the digit node is updated.
The measured numbers. Read them as data.
Wall-clock milliseconds on the standard js-framework-benchmark suite (Chromium via Playwright, lower = faster). These are synthetic workloads — every framework here optimizes for different real-world shapes. It's a data point, not a verdict.
| framework | create 1k | replace 1k | update | select | create 10k |
|---|---|---|---|---|---|
| ●Pyreon | 9.1 | 9.1 | 0.8 | 0 | 93.9 |
| Solid | 9.9 | 10.0 | 4.6 | 0 | 114.6 |
| Vue 3 | 10.2 | 10.2 | 1.6 | 0.7 | 109.3 |
| React 19 | 11.0 | 11.0 | 1.1 | 0.3 | 220.1 |
Source: CLAUDE.md "Benchmark Results". run yours · methodology in the repo.
Standard js-framework-benchmark suite, Chromium via Playwright, wall-clock ms — same machine, same run. Re-run it yourself; the config is in the repo.
We report our own measured numbers and synthetic-benchmark parity with Solid. Real-app head-to-head isn't run yet — we won't claim it until it is. Every framework here is good work by good people.
Signal reads in. Targeted re-runs out.
Four mechanisms, named the way the source names them — the words your profiler will print at 3am.
React, Preact, Vue 3, or SolidJS. Pick your dialect.
Compatibility layers compile each API down to Pyreon signals. Migrate one component at a time, or just write what your team already speaks.
// useState → signal const [c, setC] = useState(0) useEffect(fn, [c])
// mirrors @preact/signals const c = signal(0) effect(() => log(c.value))
// composition · ref/computed const c = ref(0) const d = computed(() => c.value*2)
// createSignal / createEffect const [c, setC] = createSignal(0) createEffect(() => log(c()))
SSR · SSG · ISR · islands · SPA. One config.
Zero is the meta-framework atop Pyreon: file-system routing, API routes, server actions, every render strategy in one config.
export default defineConfig({ routes: { '/': { render: 'ssg' }, '/blog/:id': { render: 'isr', revalidate: 60 }, '/feed': { render: 'ssr-stream' }, '/app/*': { render: 'islands' }, }, ai: { mcp: true, llmsTxt: true }, })
First-class MCP + llms.txt.
Every Pyreon project ships a generated llms.txt manifest and an MCP server exposing typed tools. Agents read your actual source — no prompt scaffolding, no scraping.
# Pyreon > Signal-based UI framework. Fine-grained, no VDOM. ## Core API - signal: create a tracked reactive value - computed: pure function of other signals - effect: side effect, auto-tracked - untrack: read without subscribing
→ get_api({ symbol: "createStore" }) ← signature, example, mistakes[], seeAlso, addedIn — straight from the package manifest, not a guess.
62 packages. Routing, forms, data, devtools — already there.
Everything you'd otherwise stitch together yourself. Every package is signal-aware, type-safe, and tree-shakeable.