Signals connect state directly to the DOM nodes that depend on it. No virtual DOM. No component re-renders. No guesswork.
npm create praxisjs@latestThe ideas behind every decision in PraxisJS.
render() is called exactly once per mount. Reactive updates happen via arrow functions in JSX — {() => this.value} — never via re-renders.
Decorators make reactivity visible at a glance. You see @State, @Watch, @Computed in the class definition — no hooks, no magic strings.
Signals update specific DOM nodes directly via effects. Skip reconciliation entirely — only the exact nodes that depend on a signal update.
Three steps. No magic.
Annotate class fields with @State, @Prop or @Resource. Each decorator registers a signal under the hood — no stores, no context, no setup functions.
Wrap any expression in an arrow function — {() => this.count}. PraxisJS tracks which signals are read and subscribes that exact DOM node to future updates.
When a signal changes, only the DOM nodes that read it re-evaluate. render() never runs again. No virtual DOM, no diffing, no component tree traversal.
Every package ships with PraxisJS and follows the same design philosophy.
Scaffold a new project with the official CLI or follow the manual setup guide.
npm create praxisjs@latest