Contributing to Praxis
February 6, 2026 · View on GitHub
We love your input! We want to make contributing to Praxis as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer
Development Process
We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.
- Fork the repo and create your branch from
main. - If you've added code that should be tested, add tests.
- If you've changed APIs, update the documentation.
- Ensure the test suite passes.
- Make sure your code lints.
- Issue that pull request!
Development Setup
Praxis supports both Node.js and Deno environments. Choose the setup that works best for you.
Node.js Setup (Primary)
# Clone your fork
git clone https://github.com/YOUR_USERNAME/praxis.git
cd praxis
# Install dependencies
npm install
# Build the library
npm run build
# Run tests
npm test
# Type check
npm run typecheck
Deno Setup (Experimental)
# Clone your fork
git clone https://github.com/YOUR_USERNAME/praxis.git
cd praxis
# Run with Deno
deno task dev
# Run tests with Deno
deno task test
# Lint and format
deno task lint
deno task fmt
# Type check
deno task typecheck
Development Workflow
- Create a feature branch from
main - Make your changes
- Run tests and type checking
- Format your code
- Commit with a clear message
- Push and create a pull request
Code Style
- We use TypeScript with strict type checking
- Follow the existing code style
- Use meaningful variable and function names
- Add comments for complex logic
- Keep functions small and focused
- Use 2-space indentation
- Prefer functional programming patterns
- Keep line length under 100 characters
Formatting
We use automated formatting:
- Node.js: TypeScript compiler with strict mode
- Deno:
deno fmtfor consistent formatting
Run deno fmt before committing to ensure consistent style.
Testing
- Write tests for new features
- Ensure all tests pass before submitting PR
- Use Vitest for Node.js tests
- Test both success and error cases
- Aim for high code coverage on new features
- Test edge cases and error handling
Running Tests
# Node.js (Vitest)
npm test
npm run test:watch # Watch mode
npm run test:ui # UI mode
# Deno
deno task test
Dogfooding Plures Tools
Praxis actively dogfoods all Plures tools to find friction before users do. This helps us build better tools and improve the developer experience.
Decision Ledger Dogfooding
If your change adds or modifies any rule or constraint:
- Add/Update Contract via
defineContract()and attach it tometa.contract. - Add Tests that cover every Given/When/Then example and invariant.
- Update Behavior Docs if canonical behavior changes.
- Run dogfood checks:
npm run scan:rules
npm run build
npm run validate:contracts
See docs/decision-ledger/DOGFOODING.md for full guidance.
Using Plures Tools Daily
We dogfood all Plures tools during development:
- Praxis CLI: Use for scaffolding and generation
- PluresDB: Use for test fixtures and examples
- State-Docs: Generate documentation from schemas
- CodeCanvas: Visualize complex schemas and architecture
- Unum: Explore distributed features in development
When you encounter friction, file a dogfooding issue immediately:
- Use the Dogfooding Friction Report issue template
- Focus on one specific friction point per issue
- Provide context about what you were trying to do
- Suggest how it could be better
See docs/DOGFOODING_CHECKLIST.md for daily/weekly/monthly dogfooding workflows.
Pull Request Process
- Update the README.md with details of changes to the interface, if applicable.
- Update the CHANGELOG.md with notes on your changes.
- Fill out the pull request template completely.
- Ensure all CI checks pass (tests, type checking, linting).
- Request review from maintainers.
- Address any review feedback.
- The PR will be merged once you have the sign-off of the maintainers.
Note: The repository includes an automated PR Overlap Guard that detects potential duplicate PRs. If you receive an alert, please review the linked PRs to ensure your work is distinct. See docs/workflows/pr-overlap-guard.md for details.
Commit Messages
Use clear, descriptive commit messages:
- feat: A new feature
- fix: A bug fix
- docs: Documentation changes
- style: Code style changes (formatting, etc.)
- refactor: Code refactoring
- test: Adding or updating tests
- chore: Maintenance tasks
Examples:
feat: add component generator for Svelte
fix: resolve schema validation edge case
docs: update getting started guide
Semantic Versioning Labels
When creating a pull request, add one of these labels to control the version bump:
- semver:major - Breaking changes (e.g., 1.0.0 → 2.0.0)
- semver:minor - New features, backwards compatible (e.g., 1.0.0 → 1.1.0)
- semver:patch - Bug fixes, patches (e.g., 1.0.0 → 1.0.1) - default if no label
The CI/CD pipeline will automatically bump the version and publish based on your label selection.
CI/CD Pipeline
Praxis uses a fully automated CI/CD pipeline. When your PR is merged to main:
- Auto Version Bump: Version is automatically bumped based on semver labels
- Tag Creation: A git tag is created (e.g.,
v1.2.3) - Release: GitHub Release is automatically created
- Publishing: Package is published to NPM, JSR, and NuGet in parallel
For detailed information about the pipeline, see CI/CD Pipeline Guide.
Any contributions you make will be under the MIT Software License
In short, when you submit code changes, your submissions are understood to be under the same MIT License that covers the project. Feel free to contact the maintainers if that's a concern.
Report bugs using GitHub's [issue tracker]
We use GitHub issues to track public bugs. Report a bug by opening a new issue.
Write bug reports with detail, background, and sample code
Great Bug Reports tend to have:
- A quick summary and/or background
- Steps to reproduce
- Be specific!
- Give sample code if you can.
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
License
By contributing, you agree that your contributions will be licensed under its MIT License.
Monorepo Structure
Praxis is organized as a monorepo with clear package boundaries. See MONOREPO.md for the complete organization plan.
Repository Layout
praxis/
├── packages/ # Published npm packages
│ ├── praxis-core/ # Core logic library (facts, rules, schemas, contracts)
│ ├── praxis-cli/ # Command-line interface and generators
│ ├── praxis-svelte/ # Svelte 5 integration
│ ├── praxis-cloud/ # Cloud sync and relay
│ └── praxis/ # Main package (re-exports all)
├── apps/ # Example applications (not published)
├── tools/ # Development tools (not published)
├── ui/ # UI components and tools (not published)
└── docs/ # Documentation
Package Ownership
When contributing, please respect package boundaries:
- praxis-core: Core logic primitives only (no UI, no integrations)
- praxis-cli: CLI commands, generators, templates
- praxis-svelte: Svelte-specific code and components
- praxis-cloud: Cloud relay and sync protocol
- praxis: Re-exports from other packages for convenience
Working with Packages
The repository uses npm workspaces. When developing:
# Install all dependencies (from root)
npm install
# Build all packages
npm run build
# Test all packages
npm test
# Work on a specific package
cd packages/praxis-core
npm test
Architecture Overview
Praxis follows a modular architecture:
Core Components
- Schema System (
packages/praxis-core/src/schema/): Declarative schema definitions and validation - Logic Engine (
packages/praxis-core/src/logic/): Facts, events, rules, and constraints - Decision Ledger (
packages/praxis-core/src/decision-ledger/): Contracts and behavior specifications - Component Generator (
packages/praxis-svelte/src/generators/): Generates Svelte components from schemas - CLI (
packages/praxis-cli/src/): Command-line interface for project scaffolding and code generation
Key Concepts
- Schemas: Define data models, components, and application structure
- Facts: Immutable data points in the logic engine
- Events: Temporal occurrences that trigger logic
- Rules: Declarative logic that derives new facts from existing ones
- Constraints: Validation rules that ensure data integrity
- Contracts: Behavior specifications for rules and constraints
- Actors: Effectful components for side effects and integrations
Generator Architecture
The generator system transforms schemas into code:
- Parse: Read and validate schema definitions
- Transform: Convert schemas to intermediate representation
- Generate: Create target code (Svelte, TypeScript, etc.)
- Write: Output generated files to the file system
For more details, see FRAMEWORK.md and MONOREPO.md.
Contributing to Praxis-Core
Praxis-Core is the canonical logic layer used by all packages and tools. When contributing to core modules (src/core/, src/dsl/, src/decision-ledger/), follow these additional guidelines:
Core Module Stability
Core modules are STABLE and follow strict backward compatibility requirements:
- Public API Changes: All public API changes require review and approval
- Breaking Changes: Breaking changes only allowed in major versions
- Deprecation: Deprecate APIs for at least one minor version before removal
- Documentation: All public APIs must be documented with TSDoc comments
Core Module Guidelines
- Purity: All rules and constraints must be pure functions (no side effects)
- Immutability: Never mutate state; always return new values
- Type Safety: Use explicit types for all public APIs
- JSON Compatibility: Core types must remain JSON-serializable
- Cross-Language: Consider C# and PowerShell compatibility for protocol changes
Decision Ledger for Core Changes
All core module changes require Decision Ledger compliance:
- Contracts: Every rule/constraint must have a contract attached
- Examples: Contracts must include Given/When/Then examples
- Tests: All contract examples must have corresponding tests
- Validation: Run validation before submitting PR:
npm run scan:rules
npm run build
npm run validate:contracts
Core Breaking Change Policy
Breaking changes to core APIs require:
- Justification: Clear explanation of why the change is necessary
- Migration Guide: Step-by-step guide for upgrading
- Deprecation Period: At least one minor version of deprecation warnings
- Cross-Language Coordination: Updates to C# and PowerShell implementations
- Major Version Bump: Breaking changes only in major releases
For more details, see:
References
This document was adapted from the open-source contribution guidelines for Facebook's Draft.