Launch Stripe-shaped carts in minutes.
use-shopping-cart handles cart state, formatting, and Checkout wiring so you can focus on customer experience.
GitHub stars
922
Weekly npm downloads
1.1k
Hook
const {addItem,cartCount,formattedTotalPrice} = useShoppingCart()
One hook exposes state + Stripe helpers.
Try it now
Cart Interaction Playground
Tap the controls to see how cart totals and UX respond instantly—with no real Stripe keys required.
Every control below triggers the same cart methods you use in an app. The totals on the right announce updates automatically.
cartCount
0
formattedTotalPrice
$0.00
Cart preview
Toggle actions to see totals move.
Cart is empty. Add the sample product to see totals update.
This cart has been clicked 0 times.
Modern cart toolkit
Ship Checkout-ready carts without reinventing state.
Purpose-built for React 19 apps: compose cart hooks, format helpers, and server utilities to launch Stripe Checkout faster.
Optimistic cart UX
useOptimisticCart mirrors server state so quantity and price changes feel instant while requests settle.
State persistence controls
Tune persistKey, storage, and shouldPersist to decide exactly how carts survive reloads or sign-outs.
Inventory filters
Run filterCart on live cartDetails to build subscription-only, digital, or custom product views on the fly.
Fully tested
Core logic ships with unit + integration coverage so you can focus on UX.
Event-aware buttons
handleCartClick, handleCartHover, and handleCloseCart emit metadata for animating CTAs, drawers, or tooltips.
Serverless utilities
Validate carts and hydrate Stripe Checkout sessions with a single helper import.
Developer workflow
Four steps from prototype to Checkout.
Follow the same flow on every project—wrap the provider, pull in products, wire buttons, validate servers.
Wrap your app
Drop `<CartProvider>` at the root and pass your Stripe publishable key.
import { CartProvider } from 'use-shopping-cart'export function Root() {return (<CartProvidermode="payment"cartMode="checkout-session"stripe={import.meta.env.VITE_STRIPE_KEY}currency="USD"><App /></CartProvider>)}
tsx
Shape your products
Inventory can come from Stripe, a CMS, a database, or JSON as long as the fields match.
export const products = [{id: 'id_banana001',name: 'Bananas',description: 'Yummy yellow fruit',price: 400,currency: 'USD',image: '/assets/bananas.png'}] as const
ts
Build the frontend
Use the hook to format currency, add items, or kick off Checkout.
import { useShoppingCart, formatCurrencyString } from 'use-shopping-cart'function Product({ product }) {const { addItem } = useShoppingCart()return (<buttononClick={() => addItem(product)}className="rounded-full bg-white/10 px-4 py-2">Add {formatCurrencyString({ value: product.price, currency: 'USD' })}</button>)}
tsx
Validate & redirect
Use our helpers in serverless functions to create Stripe sessions.
import Stripe from 'stripe'import { validateCartItems } from 'use-shopping-cart/utilities'export const handler = async (event) => {const stripe = new Stripe(process.env.STRIPE_API_SECRET)const productJSON = JSON.parse(event.body)const lineItems = validateCartItems(inventory, productJSON)const session = await stripe.checkout.sessions.create({mode: 'payment',line_items: lineItems,success_url: process.env.SUCCESS_URL,cancel_url: process.env.CANCEL_URL})return { statusCode: 200, body: JSON.stringify({ sessionId: session.id }) }}
ts
import { CartProvider } from 'use-shopping-cart'import React from 'react'import App from './App'export function Root() {return (<CartProviderstripe={import.meta.env.VITE_STRIPE_KEY}currency="USD"shouldPersist><App /></CartProvider>)}
Wrap your root entry (Vite, CRA) with CartProvider.
Community
Trusted by teams shipping serious carts.
Join agencies, SaaS builders, indie hackers, and open source maintainers who rely on use-shopping-cart.
Ready to launch?
Everything you need to sell products with Stripe Checkout.
Dive into the docs or try the interactive playground first—no Stripe keys required.