Skip to content

Getting Started

PraxisJS is a signal-driven frontend framework built with TypeScript. It provides fine-grained reactivity, class components with decorators, and a complete ecosystem of first-party packages.

Experimental

PraxisJS is under active development. APIs are unstable and subject to breaking changes at any time. Not recommended for production use. See project status →

Why Praxis?

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

The ancient concept that separates those who understand from those who execute. Not theory, not intention — only the act that emerges when knowledge and craft become inseparable.

Most frameworks hide their praxis. Write less, trust more, let the runtime handle the rest. PraxisJS refuses that contract.

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

Fine-grained reactivity, TypeScript-native, signals that reach the DOM with no reconciliation pass between intention and result — nothing hidden, nothing assumed.

Automatic setup

Run create-praxisjs to generate a new project with TypeScript, Vite, JSX, and all dependencies already configured.

sh
npm create praxisjs@latest
sh
pnpm create praxisjs
sh
yarn create praxisjs
sh
bun create praxisjs

You can also pass the project name as an argument to skip the first prompt:

sh
npm create praxisjs@latest my-app

The CLI will then ask which template to use:

TemplateIncludes
Minimal@praxisjs/core, @praxisjs/decorators, @praxisjs/jsx, @praxisjs/runtime
With RouterMinimal + @praxisjs/router
FullRouter + @praxisjs/store, @praxisjs/di, @praxisjs/composables, @praxisjs/concurrent, @praxisjs/devtools

Once the project is created, install dependencies and start the dev server:

sh
cd my-app
npm install
npm run dev

The dev server starts at http://localhost:5173 with HMR enabled via @praxisjs/vite-plugin.


Manual setup

Prefer to configure everything yourself? Install only the packages you need.

Installation

sh
npm install @praxisjs/core @praxisjs/jsx @praxisjs/runtime @praxisjs/decorators
npm install -D @praxisjs/vite-plugin
sh
pnpm add @praxisjs/core @praxisjs/jsx @praxisjs/runtime @praxisjs/decorators
pnpm add -D @praxisjs/vite-plugin
sh
yarn add @praxisjs/core @praxisjs/jsx @praxisjs/runtime @praxisjs/decorators
yarn add -D @praxisjs/vite-plugin

Project setup

Configure Vite to use the PraxisJS plugin:

ts
// vite.config.ts
import { defineConfig } from "vite";
import { praxisjs } from "@praxisjs/vite-plugin";

export default defineConfig({
  plugins: [praxisjs({ hmr: true })],
});

Configure TypeScript to use the PraxisJS JSX runtime:

json
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "jsxImportSource": "@praxisjs/jsx",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "useDefineForClassFields": false,
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true
  },
  "include": ["src", "vite.config.ts"]
}

Your first component

tsx
import { Component, State, Prop } from "@praxisjs/decorators";
import { BaseComponent } from "@praxisjs/core";

@Component()
class Counter extends BaseComponent {
  @Prop() initialCount = 0;
  @State() count = 0;

  increment() {
    this.count++;
  }

  render() {
    return (
      <div>
        <p>Count: {this.count}</p>
        <button onClick={() => this.increment()}>Increment</button>
      </div>
    );
  }
}

Mounting the app

ts
import { render } from '@praxisjs/runtime'

render(<Counter initialCount={0} />, document.getElementById('app')!)

Package overview

PackagePurpose
coreReactive primitives: signal, computed, effect, resource
composablesDOM and browser composition utilities
decoratorsClass decorators for components
jsxJSX runtime and type definitions
runtimeVNode rendering engine
storeReactive state management
routerClient-side routing
motionAnimations: tweens, springs, keyframes
fsmFinite state machines
concurrentAsync concurrency control
diDependency injection container
vite-pluginVite integration
devtoolsIn-app developer tools panel

Released under the MIT License.