npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-premium-gate

v1.0.2

Published

React components and hooks for Razorpay subscription paywalls — PremiumGate, PricingModal, usePro

Readme

react-premium-gate

npm MIT License GitHub Zero Dependencies React

Drop-in React components and hooks for Razorpay subscription paywalls. Built for Indian SaaS apps.

Three exports. Zero runtime dependencies. Works with any React app.


When to use this

Use react-premium-gate when:

  • You're building a React app that monetizes via Razorpay subscriptions (monthly/yearly plans)
  • You need to gate features or UI behind a Pro plan without writing the plumbing from scratch
  • You're deploying on Vercel and want ready-made serverless API routes for payment flows
  • You need server-side subscription verification, not just client-side localStorage checks

Not the right fit if you're using Stripe, Paddle, or Lemon Squeezy — this library is Razorpay-specific by design.


Why not build it yourself?

A complete Razorpay subscription flow in React requires five moving parts: create the subscription server-side, open the Razorpay SDK, verify the HMAC-SHA256 payment signature, persist subscription state, and re-verify against Razorpay's API on each session load.

react-premium-gate ships all five — as a hook, two components, and three copy-paste Vercel API templates. Add the package, paste the templates, configure env vars, and your paywall is live in under an hour.


What's included

| Export | Type | What it does | |--------|------|-------------| | <PremiumGate> | Component | Blocks UI behind a paywall with a customizable CTA | | <PricingModal> | Component | Bottom-sheet pricing modal with plan toggle | | usePro | Hook | Manages Pro status via localStorage + server verification |

Plus Vercel API templates in /templates/api/ for Razorpay subscription creation and HMAC payment verification.


Install

npm install react-premium-gate

Usage

usePro

import { usePro } from 'react-premium-gate'

function App() {
  const { isPro, loading, activatePro } = usePro({
    storageKey: 'my_app_sub',           // localStorage key
    verifyEndpoint: '/api/verify-subscription', // optional server check
  })

  if (loading) return null
  return isPro ? <ProContent /> : <FreeContent />
}

<PremiumGate>

import { PremiumGate } from 'react-premium-gate'

<PremiumGate
  onUpgrade={() => setShowModal(true)}
  title="Pro Feature"
  description="Unlock this with a Pro subscription."
  buttonText="Upgrade to Pro — ₹399/mo"
  icon="👑"
  accentColor="#F0B429"
/>

Props

| Prop | Type | Default | |------|------|---------| | onUpgrade | function | required | | title | string | 'Pro Feature' | | description | string | 'Upgrade to Pro to unlock this feature.' | | buttonText | string | 'Upgrade to Pro' | | icon | string | '👑' | | accentColor | string | '#F0B429' | | style | object | {} |


<PricingModal>

import { PricingModal } from 'react-premium-gate'

const PLANS = [
  { id: 'monthly', label: 'Monthly', price: '₹399',   period: '/mo' },
  { id: 'yearly',  label: 'Yearly',  price: '₹2,999', period: '/yr', badge: 'Save 37%' },
]

<PricingModal
  isOpen={showModal}
  onClose={() => setShowModal(false)}
  plans={PLANS}
  onSelectPlan={(planId) => handlePayment(planId)}
  accentColor="#F0B429"
  loading={paymentLoading}
/>

Props

| Prop | Type | Default | |------|------|---------| | isOpen | boolean | required | | onClose | function | required | | plans | array | [] | | onSelectPlan | function | required | | title | string | 'Upgrade to Pro' | | subtitle | string | 'Less than a coffee. Way more value.' | | icon | string | '👑' | | accentColor | string | '#F0B429' | | fineText | string | 'Secure payment · Cancel anytime' | | loading | boolean | false |


Razorpay API Templates

Copy the files from /templates/api/ into your Vercel project's api/ folder.

templates/api/
├── create-subscription.js   # Creates Razorpay subscription server-side
├── verify-payment.js        # Verifies HMAC-SHA256 payment signature
└── verify-subscription.js   # Checks if subscription is still active

Required Vercel env vars:

RAZORPAY_KEY_ID=rzp_live_xxx
RAZORPAY_KEY_SECRET=your_secret
RAZORPAY_PLAN_MONTHLY=plan_xxx
RAZORPAY_PLAN_YEARLY=plan_xxx

Full Example

import { useState } from 'react'
import { usePro, PremiumGate, PricingModal } from 'react-premium-gate'

const PLANS = [
  { id: 'monthly', price: '₹399',   period: '/mo' },
  { id: 'yearly',  price: '₹2,999', period: '/yr', badge: 'Save 37%' },
]

export default function App() {
  const { isPro, activatePro } = usePro({
    storageKey: 'my_app_sub',
    verifyEndpoint: '/api/verify-subscription',
  })
  const [showModal, setShowModal] = useState(false)
  const [loading, setLoading] = useState(false)

  const handlePayment = async (planId) => {
    setLoading(true)
    const res = await fetch(`/api/create-subscription?plan=${planId}`)
    const { subscriptionId } = await res.json()

    const rzp = new window.Razorpay({
      key: process.env.VITE_RAZORPAY_KEY_ID,
      subscription_id: subscriptionId,
      handler: async (response) => {
        const verify = await fetch('/api/verify-payment', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(response),
        })
        const { valid, subscriptionId: subId } = await verify.json()
        if (valid) { activatePro(subId); setShowModal(false) }
        setLoading(false)
      },
    })
    rzp.open()
  }

  return (
    <>
      {!isPro && (
        <PremiumGate
          onUpgrade={() => setShowModal(true)}
          title="Analytics — Pro only"
          description="Unlock detailed charts and AI insights."
          buttonText="Upgrade to Pro"
        />
      )}

      <PricingModal
        isOpen={showModal}
        onClose={() => setShowModal(false)}
        plans={PLANS}
        onSelectPlan={handlePayment}
        loading={loading}
      />
    </>
  )
}

Author

M. Adhitya — Founder, Rewrite Labs

License

MIT © 2025 M. Adhitya

Built at Rewrite Labs · Used in production across the Rewrite Labs app suite.