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 row-list benchmark: ahead of Solid on most ops, behind it on deep-tree mount. Author-judged — no independent run yet.
// 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 a krausest-style row-list 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 | 8.83 | 8.64 | 0.645 | 0.015 | 88.31 |
| Octane | 9.27 | 8.95 | 0.675 | 0.025 | 94.94 |
| Solid | 9.47 | 9.30 | 1.30 | 0.025 | 93.23 |
| Vue 3 | 9.30 | 9.21 | 0.990 | 0.305 | 97.10 |
| React 19 | 11.25 | 10.53 | 0.855 | 0.185 | 216.97 |
Source: BENCHMARKS.md §1 (2026-09-23 run). Select is below the clock resolution — no verdict. run yours · methodology in the repo.
krausest-style row-list suite, Chromium via Playwright, wall-clock ms — same machine, same run, 100 pooled samples. Re-run it yourself; the config is in the repo.
We report our own measured numbers, losses included: Solid mounts a deep component tree 1.29× faster, and Octane ties us on partial update and swap. No independent run exists yet. 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.
76 packages. Routing, forms, data, devtools — already there.
Routing, state, styling, tooling, and native targets share the same reactive foundation.