Thank you for considering a contribution! Every improvement — fixing a typo, adding a test, filing an issue, or writing a feature — makes this project better.
- Code of Conduct
- Getting Started
- Development Workflow
- Commit Conventions
- Pull Request Process
- Reporting Bugs
- Suggesting Features
- Project Structure
This project follows the Contributor Covenant Code of Conduct. By participating, you agree to abide by its terms.
- Node.js >= 18
- pnpm >= 9 (the repo uses
packageManagerfield —corepack enablewill install it automatically) - Git
# 1. Fork the repository on GitHub
# 2. Clone your fork
git clone https://github.com/<your-username>/react-access-engine.git
cd react-access-engine
# 3. Install dependencies
pnpm install
# 4. Build all packages
pnpm build
# 5. Run tests to confirm everything works
pnpm test| Command | Description |
|---|---|
pnpm build |
Build all packages |
pnpm test |
Run all tests |
pnpm lint |
Lint all packages |
pnpm typecheck |
Type-check all packages |
pnpm format |
Format all files with Prettier |
pnpm format:check |
Check formatting without writing |
pnpm --filter react-access-engine test:watch |
Watch tests for the core package |
pnpm --filter playground dev |
Start the Vite playground |
pnpm --filter docs dev |
Start the docs dev server |
# Watch mode for the core package
pnpm --filter react-access-engine dev
# In another terminal, run tests in watch mode
pnpm --filter react-access-engine test:watchBefore submitting a PR that changes published packages, create a changeset:
pnpm changesetThis will prompt you to:
- Select the packages you changed
- Choose the semver bump type (patch / minor / major)
- Write a summary of the change
The changeset file will be committed with your PR and consumed during the release process.
When to create a changeset:
- Bug fixes →
patch - New features (backward-compatible) →
minor - Breaking changes →
major
When NOT to create a changeset:
- Changes to docs, examples, CI, or tooling only
- Changes to
private: truepackages (likeshared)
This project uses Conventional Commits. Commits are validated by commitlint via a Git hook.
<type>(<scope>): <description>
[optional body]
[optional footer]
| Type | Use for |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
style |
Code style (formatting, semicolons, etc.) |
refactor |
Code change that neither fixes nor adds |
perf |
Performance improvement |
test |
Adding or updating tests |
build |
Build system or dependencies |
ci |
CI/CD configuration |
chore |
Maintenance tasks |
revert |
Revert a previous commit |
feat(core): add environment-scoped feature flags
fix(policy-engine): handle undefined resource in condition evaluation
docs: add ABAC policy examples to README
test(experiments): add edge case for zero allocation
refactor(hooks): extract shared permission check logic
ci: add Node 22 to test matrix
chore: update dev dependencies- Branch from
main— create a descriptive branch:feat/remote-config-polling,fix/wildcard-permission-matching - Keep PRs focused — one logical change per PR
- Write tests — all new features and bug fixes should include tests
- Update docs — if your change affects the public API, update the relevant documentation
- Add a changeset — run
pnpm changesetfor changes to published packages - Ensure CI passes — lint, typecheck, test, and build must all pass
- Fill out the PR template — describe what changed and why
- Tests added or updated
- Changeset added (if applicable)
- Documentation updated (if applicable)
-
pnpm lintpasses -
pnpm typecheckpasses -
pnpm testpasses -
pnpm buildpasses
- A maintainer will review your PR within a few days
- Feedback is about code quality, not you personally
- Small, focused PRs are reviewed faster
- Once approved, a maintainer will merge using squash merge
Use the bug report template and include:
- What you expected vs. what happened
- Steps to reproduce (code snippet or minimal repo)
- Environment — React version, Node version, bundler, SSR or client-only
- Relevant error messages or stack traces
Use the feature request template and include:
- Problem — what are you trying to do?
- Proposed solution — your ideal API
- Alternatives considered — other approaches you've thought of
packages/
├── react-access-engine/ # Core library (npm: react-access-engine)
│ ├── src/
│ │ ├── components/ # React components (Can, Feature, AccessGate, etc.)
│ │ ├── hooks/ # React hooks (usePermission, useFeature, etc.)
│ │ ├── engines/ # Pure logic engines (permission, feature, policy, etc.)
│ │ ├── types/ # TypeScript type definitions
│ │ ├── plugins/ # Built-in plugins
│ │ └── utils/ # Internal utilities
│ └── tests/ # Vitest tests
├── devtools/ # react-access-engine-devtools
└── shared/ # Internal shared utilities (private)
- Engines are pure functions — no React dependencies, easily testable
- Hooks compose engines — each hook calls one or more engines
- Components are thin wrappers — they call hooks and conditionally render
- Everything is tree-shakeable — unused engines are eliminated at build time
- SSR-safe by design — deterministic evaluation, no side effects
- Questions → GitHub Discussions
- Bugs → Issue Tracker
- Security → See SECURITY.md
Thank you for contributing! 🎉