Plan-gated features without if-statements everywhere
How to lock features behind Free and paid plans in a React + NestJS SaaS so that pricing changes don't turn into a hunt through the codebase.
The problem
A trading-analytics product I worked on had a free plan and paid plans. The first version checked the plan name directly in components: if the plan is "basic", hide this chart. Every pricing change meant searching the codebase for plan names.
Entitlements, not plan names
The fix is one level of indirection. Components ask for a capability, not for a plan:
// one place maps plans to capabilities
const entitlements = {
free: ["journal", "basic-stats"],
basic: ["journal", "basic-stats", "broker-import"],
pro: ["journal", "basic-stats", "broker-import", "advanced-analytics"],// components only ask about capabilities const canImport = useEntitlement("broker-import"); ```
Pricing changes now touch one map. Marketing can rename plans without a deploy that hunts strings.
Enforce on the server too
Hiding a button is user experience, not security. The same capability check runs in the API, before the work is done. The plan itself comes from the subscription webhook (Stripe), stored on the account, never from the client.
Show what's locked
Locked features stay visible with a short explanation and an upgrade path. Users who see what they're missing upgrade more often than users who never learn the feature exists.