Organizations, sessions and your database adapter. Usage counters use its guarded incrementOne.
Entitlements
May this organization do it, and how much is left?
Plans, features, limits and usage for your organizations, kept in your own database. Declare the catalog once, and stop scattering plan names and limits across the API, the web app and the pricing page.
npm i @byo-oss/entitlementsIllustration. Pick a plan to see what it allows.
Relies on
peerDependencies · @byo-oss/entitlements 0.2.0The after-commit hooks behind events. Install it at the same version as better-auth.
The endpoint layer under better-auth, which already depends on it.
Validation uses your app's copy. An app still on zod 3 has to move to zod 4 first.
Entitlements belong to organizations, and your staff are an organization's members.
The ./stripe billing source reads its subscriptions and reuses its webhook.
Tell an organization's owners when it reaches a limit.
The ./react hook, <EntitlementGate /> and <UsageMeter />.
Only for ./testing, the contract suite for billing sources you write.
The whole domain, at a young product's depth.
Built to the BYO conventions from day one: your identity, your permissions, your database.
One typed catalog
Features, limits and plans declared once. The API, the web app and a static pricing page import the same file, and a typo is a type error.
Billing stays where it is
Stripe, through @better-auth/stripe, knows which plan an organization bought. Entitlements keeps a snapshot of it and decides what the plan allows.
Atomic usage counters
consumeUsage is one guarded increment: no read-then-write race, and a refused call never counts against the limit.
Never a 500 for a refusal
Every check returns allowed, a reason and the plans that would unlock it, so the app can show the upgrade instead of an error.
Staff overrides
Comp a feature, raise a limit or move an organization to another plan, with a reason, an optional expiry and an audit trail.
Headless first
A hook owns the state and the calls. A gate and a usage meter on shadcn variables sit on top, every string overridable.
Better with the others.
Packages share one identity, one permission model and one notification path, so each one you add makes the others more useful.
- @byo-oss/entitlementslimit-reached noticesnotificationsshipped
- @byo-oss/entitlementsplan state@better-auth/stripeyour app
- @byo-oss/entitlementsresync + cleanupcore · sweepAllshipped
- @byo-oss/entitlementsplan + override eventsonEvent · after commitshipped
A way out, planned from the start.
When you bill by usage, sell credits or add-ons, or need non-engineers to edit plans, you move to a dedicated entitlements service. Entitlements ships with exportEntitlementsData, a documented schema, a field mapping to Stripe Entitlements and Autumn, and a clean uninstall.
Shape what comes next.
Issues and pull requests are on GitHub. Tell us how you price today, and what would make the package fit.