Library / SDK
ynnoj/next-stripe avatar
ynnoj/next-stripe

next-stripe turns Stripe calls into Next.js API routes you do not have to write

Simplified server-side Stripe workflows in Next.js

560 stars17 forksJavaScriptMIT

At a glance

What is it?
next-stripe is a small JavaScript library that exposes Stripe operations, checkout sessions, PaymentIntents and billing portal sessions, through a catch-all Next.js API route and a client of helper functions. It suits a Next.js developer who wants a small payment surface without hand-writing route handlers, and it carries a beta warning and a Stripe dependency pinned to a 2021 release.
Who is it for?
next-stripe fits a Next.js project that wants a handful of Stripe endpoints without writing the route handlers, since the catch-all route and the client helpers cover the common operations in a few lines. It does not fit a project that needs a current Stripe API or a maintained dependency tree, because the package pins stripe at 8.222.0 and the last published releases are beta builds from February 2021 even though the repository was pushed to on 2026-10-20.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One catch-all route, and a client that calls it

next-stripe is described as simplified server-side Stripe workflows in Next.js, and the whole architecture is visible in two steps.

You install the package.

bash
yarn add next-stripe@beta

Then you create a catch-all route file named `[...nextstripe].js` in your project's `pages/api/stripe` directory, and hand it the Stripe key.

js
import NextStripe from 'next-stripe'

export default NextStripe({
  stripe_key: process.env.STRIPE_RESTRICTED_KEY
})

That is the entire server side. The catch-all filename is what makes it work: every operation under the path routes to the same handler, and the handler decides which Stripe call to make from the request.

The client is a separate entry point, `next-stripe/client`, which exports helper functions that call those API routes from the browser.

So the shape is: one file to add on the server, and a set of named functions on the client. Nothing else in your project changes, and there is no SDK instance to configure, no provider to wrap your tree in and no context to thread through a component tree.

That is the appeal. For a project with one checkout and one billing portal link, the alternative is writing several route files by hand, each with its own Stripe client, its own error handling and its own method check.

The client helper for creating a checkout session is the shape of all of them.

js
import { createCheckoutSession } from 'next-stripe/client'

const session = await createCheckoutSession({
  success_url: window.location.href,
  cancel_url: window.location.href,
  line_items: [{ price: 'price_id', quantity: 1 }],
  payment_method_types: ['card'],
  mode: 'payment'
})

The parameters you pass are the Stripe API parameters, passed through rather than reshaped. That is what makes the library easy to learn, and it also means the Stripe API reference is the documentation for every call.

The three operation groups it covers

The coverage is deliberately narrow, and knowing it is what tells you whether the library is enough for your checkout.

Checkout sessions have one operation, create. PaymentIntents have four: create, confirm, retrieve and update. Billing portal sessions have one, create.

PaymentIntents are the most fully covered, and the four calls map directly onto the Stripe API documentation pages the README links to.

js
import { createPaymentIntent } from 'next-stripe/client'

const paymentIntent = await createPaymentIntent({
  amount: 1000,
  currency: 'usd'
})

Confirm takes an identifier and the parameters for the confirm call.

js
import { confirmPaymentIntent } from 'next-stripe/client'

const paymentIntent = await confirmPaymentIntent('pi_id', {
  payment_method: 'pm_id'
})

Retrieve takes just the identifier.

js
import { retrievePaymentIntent } from 'next-stripe/client'

const paymentIntent = await retrievePaymentIntent('pi_id')

And update takes the identifier and the fields to change.

js
import { updatePaymentIntent } from 'next-stripe/client'

const paymentIntent = await updatePaymentIntent('pi_id', {
  amount: 1000,
  currency: 'usd'
})

The billing portal session is the third group, and it is what lets a customer change their payment method or download invoices without you building that surface.

js
import { createBillingPortalSession } from 'next-stripe/client'

const session = await createBillingPortalSession({
  customer: 'cus_id',
  return_url: window.location.href
})

What is not here matters as much. There is no subscription creation helper, no customer helper, no webhook helper, no price or product helper, and no invoice helper. For a one-off payment or a subscription managed elsewhere in Stripe, that is fine. For anything else, you are writing your own route handlers alongside this one.

Restricted keys, and why the warning about them is there

The README attaches a warning to the API route section, and it is a warning about key scope rather than about the library.

It is recommended that you use a restricted key with limited API access with this library, and that these keys can be created and configured with the required access in the Stripe Dashboard.

That matters because of the architecture. The catch-all route accepts any operation the library implements, and it holds a Stripe credential with which to perform it. With a full secret key, a mistake in a route, a bug in your own code that lets a caller pass arbitrary parameters, or a cross-site request forgery against your own API route would all have the same consequence: unrestricted access to your Stripe account.

A restricted key narrows that to the endpoints you actually need, so the worst case of a mistake is a bad payment rather than a rewritten customer list.

The key is passed through an environment variable in the example, `process.env.STRIPE_RESTRICTED_KEY`, which keeps it out of the repository and out of the client bundle. The library does not put the key on the client side, which is the whole point of the server-side route: the browser calls your route, your route calls Stripe.

The other warning in the README is broader. The library is currently in beta and should be used in production with caution, and the install command points at the beta tag rather than a stable version.

Beta releases from 2021, against a repository still being touched

The version history is worth reading carefully, because it tells you two different things about the project's age.

The listed releases are v1.0.0-beta.9 on 2021-02-08, v1.0.0-beta.8 on 2021-01-30 and v1.0.0-beta.7 on 2021-01-27. So the published versions are from January and February 2021, and the project never left beta on that line.

The repository itself was last pushed to on 2026-10-20, and the default branch is beta. The package.json version field reads 0.0.0-semantically-released, which is a placeholder used by semantic-release: the published version is computed from the commit history at release time rather than written into the manifest.

The dependency set dates from the same period. The stripe package is pinned at 8.222.0 and the Babel toolchain at 7.12.x, and the build scripts are `babel src --out-dir dist` for the build and `babel --watch src --out-dir dist` for watch mode, with the published files being dist plus client.js.

So the honest reading is that this is a 2021-era library with a repository that receives occasional attention since. The operation list may still be correct, since Stripe's basic checkout, PaymentIntent and billing portal calls have not changed shape, but a Stripe SDK pinned to 8.222.0 talking to a 2026 Stripe API is where the risk sits.

The rest of the repository is ordinary: a src/ directory, index.js and client.js as the two entry points, a yarn.lock, prettier and babel configuration, a release.config.js, and renovate.json for dependency updates.

Where next-stripe is the wrong choice

Four cases argue against it.

The first is a project that has outgrown it, which is most new Next.js projects. The library targets the pages router, with the route placed in `pages/api/stripe`. A project on the app router, or one using route handlers, will not use this pattern, and the catch-all filename convention is different enough that you are writing something else anyway.

The second is a dependency you cannot pin. If your organisation runs a dependency audit, a package with no releases since February 2021 and a Stripe SDK pinned to a 2021 version is a finding you will have to explain. There is no security patch channel for a beta that never shipped a stable line.

The third is a payment surface beyond the three covered operations. A subscription product, a webhook handler for invoice events, a proration change, a customer record update: none of these are in the library, so you write them yourself, and at that point the library is saving you three route files while adding a dependency to your build.

The alternative in the same direction is the Stripe Node SDK directly in your own route handlers. The difference in approach is that you instantiate the Stripe client yourself, keep the secret key in your own code, choose your own error handling and your own validation, and can add any endpoint Stripe offers. What next-stripe gives you instead is a smaller amount of code for the common path and a browser client that already knows the route shape, which is a good trade for a single-checkout product and a poor one for a subscription business.

A third option worth naming is a dedicated payment provider or a hosted checkout product, where you do not run the Stripe integration at all. If the goal is to take money rather than to integrate Stripe, that removes the question.

Editorial conclusion

next-stripe fits a Next.js project that wants a handful of Stripe endpoints without writing the route handlers, since the catch-all route and the client helpers cover the common operations in a few lines. It does not fit a project that needs a current Stripe API or a maintained dependency tree, because the package pins stripe at 8.222.0 and the last published releases are beta builds from February 2021 even though the repository was pushed to on 2026-10-20. If you adopt it, pin it deliberately, use a restricted Stripe key as the README recommends, and check that the Stripe operations you need are covered before wiring a checkout to it.

Frequently asked questions

How do I install and set up next-stripe?

Install it with `yarn add next-stripe@beta`, then create a `[...nextstripe].js` catch-all route in your project's `pages/api/stripe` directory and export `NextStripe({ stripe_key: process.env.STRIPE_RESTRICTED_KEY })` from it. The client helpers come from the `next-stripe/client` entry point.

Which Stripe operations does next-stripe support?

Checkout session creation, PaymentIntent create, confirm, retrieve and update, and billing portal session creation. Subscriptions, customers, webhooks, prices and invoices are not covered, so those need your own route handlers.

Is next-stripe safe to use in production?

The README states the library is currently in beta and should be used in production with caution, and the install command points at the beta tag. The listed releases are v1.0.0-beta.7 through v1.0.0-beta.9 from January and February 2021, although the repository was pushed to on 2026-10-20.

Which Stripe key should I use with next-stripe?

A restricted key with limited API access, created and configured in the Stripe Dashboard with the access the library needs. The README recommends this because the catch-all route holds a Stripe credential, so a full secret key would widen the consequences of a mistake.

What licence is next-stripe released under?

MIT, as declared in the package.json and the LICENSE file at the repository root. The package depends on stripe at 8.222.0 and the Babel runtime at 7.12.5.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. ynnoj/next-stripe on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ynnoj-next-stripe.svg)](https://hysenlabs.com/projects/ynnoj-next-stripe)

Was this useful?