Skip to content

Introduction

PraxisJS is a signal-driven frontend framework written in TypeScript. It combines fine-grained reactivity with class components and decorators to give you an architecture that is explicit, traceable, and fully typed.

The core idea

Most frameworks abstract away reactivity. You write templates, the runtime figures out what to update. PraxisJS takes the opposite approach: reactivity is always explicit.

tsx
@Component()
class Counter extends StatefulComponent {
  @State() count = 0

  render() {
    return (
      <div>
        <p>Count: {() => this.count}</p>  {/* reactive */}
        <button onClick={() => this.count++}>+</button>
      </div>
    )
  }
}

The arrow function {() => this.count} is the contract. It tells the renderer: this value changes, track it. Without the arrow function, the value is static. You see exactly what is reactive and what is not — directly in the code.

What makes it different

AspectPraxisJS
Reactivity modelFine-grained signals — no virtual DOM
Component styleTypeScript class + decorators
Render behaviorrender() runs once; updates go directly to DOM nodes
State declaration@State() creates a reactive signal property
Template reactivityArrow functions: {() => this.value}

Philosophy

Praxis (πρᾶξις, Greek: action, practice). Not how things should be — how they are actually done.

@State doesn't suggest a property is reactive — it is reactive, and you can see that in the code. @Watch doesn't hint at a side effect — it commits to one. The component doesn't hide what it does: it practices openly.

The ecosystem

PraxisJS ships a complete first-party ecosystem:

Next steps

Released under the MIT License.