JurgestBalla
AboutServicesWorkBlogContact
JurgestBalla

Senior Full-Stack Engineer

ERP Integrations & Legacy Modernization

Tirana, Albania

Navigation

AboutServicesWorkBlogContact

Connect

LinkedInGitHubinfo@jurgest.comB2B projects via Klartech

Legal

Privacy policyImprint

© 2026 Jurgest Balla. All rights reserved.

Built by me ·

Back to blog
Published 12 September 20245 min read

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.

ReactStripeSaaSArchitecture

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.