https://github.com/plures/praxis
The Full Plures Application Framework
https://github.com/plures/praxis
database deno documentation local-first logic-programming state svelte tarui
Last synced: 2 months ago
JSON representation
The Full Plures Application Framework
- Host: GitHub
- URL: https://github.com/plures/praxis
- Owner: plures
- License: mit
- Created: 2025-11-15T23:05:33.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-04-02T22:28:00.000Z (2 months ago)
- Last Synced: 2026-04-03T01:44:53.723Z (2 months ago)
- Topics: database, deno, documentation, local-first, logic-programming, state, svelte, tarui
- Language: TypeScript
- Homepage: https://plures.io
- Size: 1.93 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README
# Praxis
[](https://github.com/plures/praxis/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@plures/praxis)
[](https://jsr.io/@plures/praxis)
[](LICENSE)
**The full-stack declarative application framework — typed logic, reactive state, local-first data, and visual tooling for Svelte, Node, and the browser.**
Praxis 2.0 gives you a single `createApp()` call that wires reactive state, constraint validation, rule evaluation, and an immutable timeline — zero boilerplate. When you need deeper control, drop down to the classic engine with registries, typed events/facts, and undo/redo history.
## Install
Node 18+ recommended.
```bash
npm install @plures/praxis # or: pnpm add @plures/praxis
```
## API Reference
See [`docs/API.md`](./docs/API.md) for the exported public API surface.
## Quick Start — Unified App (v2.0)
The fastest way to build with Praxis. Define paths (state), rules, and constraints — Praxis handles the rest.
```ts
import {
createApp,
definePath,
defineRule,
defineConstraint,
RuleResult,
fact,
} from '@plures/praxis/unified';
// 1. Declare your state shape
const Count = definePath('count', 0);
const Max = definePath('max', 10);
// 2. Add constraints
const notNegative = defineConstraint({
id: 'count.not-negative',
description: 'Count must never go below zero',
watch: ['count'],
validate: (values) => values['count'] >= 0 || 'Count cannot be negative',
});
// 3. Add rules
const capAtMax = defineRule({
id: 'count.cap',
watch: ['count', 'max'],
evaluate: (values) => {
if (values['count'] > values['max']) {
return RuleResult.emit([fact('count.capped', { at: values['max'] })]);
}
return RuleResult.noop();
},
});
// 4. Create the app
const app = createApp({
name: 'counter',
schema: [Count, Max],
rules: [capAtMax],
constraints: [notNegative],
});
// 5. Query & mutate
const count = app.query('count');
console.log(count.current); // 0
app.mutate('count', 5);
console.log(count.current); // 5
const result = app.mutate('count', -1);
console.log(result.accepted); // false — constraint rejected
```
## Classic Engine (full control)
For complex scenarios that need typed events, facts, actors, and undo/redo:
```ts
import {
createPraxisEngine,
PraxisRegistry,
defineFact,
defineEvent,
defineRule,
} from '@plures/praxis';
const UserLoggedIn = defineFact<'UserLoggedIn', { userId: string }>('UserLoggedIn');
const Login = defineEvent<'LOGIN', { username: string }>('LOGIN');
const loginRule = defineRule<{ currentUser: string | null }>({
id: 'auth.login',
description: 'Authenticate and emit fact',
impl: (state, events) => {
const evt = events.find(Login.is);
if (!evt) return [];
state.context.currentUser = evt.payload.username;
return [UserLoggedIn.create({ userId: evt.payload.username })];
},
});
const registry = new PraxisRegistry();
registry.registerRule(loginRule);
const engine = createPraxisEngine({ initialContext: { currentUser: null }, registry });
engine.step([Login.create({ username: 'alex' })]);
console.log(engine.getContext()); // { currentUser: 'alex' }
```
## Svelte 5 Integration
### Runes API
```svelte
import { usePraxisEngine } from '@plures/praxis/svelte';
import { createMyEngine, Login } from './my-engine';
const engine = createMyEngine();
const { context, dispatch, undo, redo, canUndo, canRedo } = usePraxisEngine(engine, {
enableHistory: true,
maxHistorySize: 50,
});
User: {context.currentUser || 'Guest'}
dispatch([Login.create({ username: 'alice' })])}>Login
⟲ Undo
⟳ Redo
```
### Store API
```ts
import { createPraxisStore, createDerivedStore } from '@plures/praxis/svelte';
const stateStore = createPraxisStore(engine);
const userStore = createDerivedStore(engine, (ctx) => ctx.currentUser);
```
See [Svelte Integration Guide](./docs/guides/svelte-integration.md) for the full API including reactive engine, history patterns, and keyboard shortcuts.
## Decision Ledger (Behavior Contracts)
Attach explicit contracts to every rule and constraint — with Given/When/Then examples, invariants, and assumption tracking.
```ts
import { defineContract, defineRule } from '@plures/praxis';
const loginContract = defineContract({
ruleId: 'auth.login',
behavior: 'Process login events and create user session facts',
examples: [
{ given: 'Valid credentials', when: 'LOGIN event', then: 'UserSessionCreated fact emitted' }
],
invariants: ['Session must have unique ID'],
});
const loginRule = defineRule({
id: 'auth.login',
description: 'Process login events',
impl: (state, events) => { /* ... */ },
contract: loginContract,
});
```
```bash
npm run scan:rules # Index all rules/constraints
npm run validate:contracts # Validate all contracts
npx praxis validate --strict # CI/CD enforcement
```
See [Decision Ledger Guide](./docs/decision-ledger/DOGFOODING.md) for the full dogfooding workflow.
## PluresDB — Local-First Persistence
```ts
import { createInMemoryDB, createPluresDBAdapter } from '@plures/praxis';
const db = createInMemoryDB();
const adapter = createPluresDBAdapter({ db, registry });
adapter.attachEngine(engine); // auto-persist facts & events
```
For production, use the official [@plures/pluresdb](https://www.npmjs.com/package/@plures/pluresdb) package with P2P sync and CRDT conflict resolution:
```ts
import { PluresNode } from '@plures/pluresdb';
import { createPluresDB } from '@plures/praxis';
const db = createPluresDB(new PluresNode({ config: { port: 34567, dataDir: './data' }, autoStart: true }));
```
## CLI
```bash
npx praxis --help
npx praxis create app my-app
npx praxis generate --schema src/schemas/app.schema.ts
npx praxis canvas src/schemas/app.schema.ts
```
## Exports
| Import path | Description |
|---|---|
| `@plures/praxis` | Core engine, DSL, protocol types, integrations |
| `@plures/praxis/unified` | `createApp()` unified reactive layer |
| `@plures/praxis/svelte` | Svelte 5 runes + store APIs |
| `@plures/praxis/schema` | Schema types and loaders |
| `@plures/praxis/component` | Svelte component generator |
| `@plures/praxis/cloud` | Cloud relay sync |
| `@plures/praxis/components` | Built-in Svelte components |
| `@plures/praxis/mcp` | Model Context Protocol tools |
| `@plures/praxis/expectations` | Behavior expectation DSL |
| `@plures/praxis/factory` | Pre-built UI rule modules |
| `@plures/praxis/project` | Project gates and lifecycle |
| `praxis` (bin) | CLI entrypoint |
## Core Protocol
All Praxis APIs build on a language-neutral, pure-function protocol:
```ts
interface PraxisFact { tag: string; payload: unknown }
interface PraxisEvent { tag: string; payload: unknown }
interface PraxisState { context: unknown; facts: PraxisFact[]; meta?: Record }
// The conceptual core — pure, deterministic, no side effects
type PraxisStepFn = (state: PraxisState, events: PraxisEvent[], config: PraxisStepConfig) => PraxisStepResult;
```
Implemented in TypeScript (npm), C# (.NET 8+, NuGet: `Plures.Praxis`), and PowerShell. All share the same JSON wire format. See [CROSS_LANGUAGE_SYNC.md](./CROSS_LANGUAGE_SYNC.md) and [PROTOCOL_VERSIONING.md](./PROTOCOL_VERSIONING.md).
## Examples
| Example | Description | Location |
|---|---|---|
| Hero E-Commerce | Full-stack: auth, cart, discounts, loyalty, actors | `src/examples/hero-ecommerce/` |
| Decision Ledger | Contracts, validation, SARIF output | `examples/decision-ledger/` |
| Offline Chat | Local-first messaging with PluresDB | `examples/offline-chat/` |
| Terminal Node | Command execution with YAML schemas | `examples/terminal-node/` |
| Unified App | `createApp()` + rules + Mermaid docs | `examples/unified-app/` |
| Cloud Sync | Real-time relay synchronization | `examples/cloud-sync/` |
| Simple App | Minimal schema usage | `examples/simple-app/` |
| Reactive Counter | Framework-agnostic reactive engine | `examples/reactive-counter/` |
Browse all examples in [`examples/`](./examples/) and [`src/examples/`](./src/examples/).
## Documentation
| Resource | Link |
|---|---|
| Getting Started | [GETTING_STARTED.md](./GETTING_STARTED.md) |
| Framework Architecture | [FRAMEWORK.md](./FRAMEWORK.md) |
| Core API Reference | [docs/core/praxis-core-api.md](./docs/core/praxis-core-api.md) |
| Extending Praxis | [docs/core/extending-praxis-core.md](./docs/core/extending-praxis-core.md) |
| Svelte Integration | [docs/guides/svelte-integration.md](./docs/guides/svelte-integration.md) |
| CodeCanvas Guide | [docs/guides/canvas.md](./docs/guides/canvas.md) |
| Decision Ledger | [docs/decision-ledger/DOGFOODING.md](./docs/decision-ledger/DOGFOODING.md) |
| Tutorials | [docs/tutorials/](./docs/tutorials/) |
| Migration from 1.x | [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) |
| Roadmap | [ROADMAP.md](./ROADMAP.md) |
| 1.x Archive | [docs/archive/1.x/](./docs/archive/1.x/) |
## Development
```bash
npm install # Install dependencies
npm run build # Build (ESM + CJS via tsup)
npm test # Run tests (Vitest)
npm run typecheck # Type-check
```
## Contributing
PRs and discussions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
- 🐛 [Report a bug](https://github.com/plures/praxis/issues/new?template=bug_report.yml)
- 💡 [Request a feature](https://github.com/plures/praxis/issues/new?template=enhancement.yml)
- 🔒 [Report a security issue](./SECURITY.md)
## License
[MIT](./LICENSE)
---
**Praxis** — practical, provable, portable application logic.
Built with ❤️ by the [Plures](https://github.com/plures) team