TypeScript icon, indicating that this package has built-in type declarations

    7.3.3 • Public • Published


    React components for the PayPal JS SDK

    build status coverage npm version bundle size npm downloads apache license storybook

    Why use react-paypal-js?

    The Problem

    Developers integrating with PayPal are expected to add the JS SDK <script> to a website and then render components like the PayPal Buttons after the script loads. This architecture works great for simple websites but can be challenging when building single page apps.

    React developers think in terms of components and not about loading external scripts from an index.html file. It's easy to end up with a React PayPal integration that's sub-optimal and hurts the buyer's user experience. For example, abstracting away all the implementation details of the PayPal Buttons into a single React component is an anti-pattern because it tightly couples script loading with rendering. It's also problematic when you need to render multiple different PayPal components that share the same global script parameters.

    The Solution

    react-paypal-js provides a solution to developers to abstract away complexities around loading the JS SDK. It enforces best practices by default so buyers get the best possible user experience.


    • Enforce async loading the JS SDK up front so when it's time to render the buttons to your buyer, they render immediately.
    • Abstract away the complexity around loading the JS SDK with the global PayPalScriptProvider component.
    • Support dispatching actions to reload the JS SDK and re-render components when global parameters like currency change.
    • Easy to use components for all the different Braintree/PayPal product offerings:


    To get started, install react-paypal-js with npm.

    npm install @paypal/react-paypal-js


    This PayPal React library consists of two main parts:

    1. Context Provider - this <PayPalScriptProvider /> component manages loading the JS SDK script. Add it to the root of your React app. It uses the Context API for managing state and communicating to child components. It also supports reloading the script when parameters change.
    2. SDK Components - components like <PayPalButtons /> are used to render the UI for PayPal products served by the JS SDK.
    // App.js
    import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js";
    export default function App() {
        return (
            <PayPalScriptProvider options={{ "client-id": "test" }}>
                <PayPalButtons style={{ layout: "horizontal" }} />



    Use the PayPalScriptProvider options prop to configure the JS SDK. It accepts an object for passing query parameters and data attributes to the JS SDK script.

    const initialOptions = {
        "client-id": "test",
        currency: "USD",
        intent: "capture",
        "data-client-token": "abc123xyz==",
    export default function App() {
        return (
            <PayPalScriptProvider options={initialOptions}>
                <PayPalButtons />

    The JS SDK Configuration guide contains the full list of query parameters and data attributes that can be used with the JS SDK.


    Use the optional PayPalScriptProvider deferLoading prop to control when the JS SDK script loads.

    • This prop is set to false by default since we usually know all the sdk script params up front and want to load the script right way so components like <PayPalButtons /> render immediately.
    • This prop can be set to true to prevent loading the JS SDK script when the PayPalScriptProvider renders. Use deferLoading={true} initially and then dispatch an action later on in the app's life cycle to load the sdk script.
    <PayPalScriptProvider deferLoading={true} options={initialOptions}>
        <PayPalButtons />

    To learn more, check out the defer loading example in storybook.

    Tracking loading state

    The <PayPalScriptProvider /> component is designed to be used with the usePayPalScriptReducer hook for managing global state. This usePayPalScriptReducer hook has the same API as React's useReducer hook.

    The usePayPalScriptReducer hook provides an easy way to tap into the loading state of the JS SDK script. This state can be used to show a loading spinner while the script loads or an error message if it fails to load. The following derived attributes are provided for tracking this loading state:

    • isInitial - not started (only used when passing deferLoading={true})
    • isPending - loading (default)
    • isResolved - successfully loaded
    • isRejected - failed to load

    For example, here's how you can use it to show a loading spinner.

    const [{ isPending }] = usePayPalScriptReducer();
    return (
            {isPending ? <div className="spinner" /> : null}
            <PayPalButtons />

    To learn more, check out the loading spinner example in storybook.

    Reloading when parameters change

    The usePayPalScriptReducer hook can be used to reload the JS SDK script when parameters like currency change. It provides the action resetOptions for reloading with new parameters. For example, here's how you can use it to change currency.

    // get the state for the sdk script and the dispatch method
    const [{ options }, dispatch] = usePayPalScriptReducer();
    const [currency, setCurrency] = useState(options.currency);
    function onCurrencyChange({ target: { value } }) {
            type: "resetOptions",
            value: {
                currency: value,
    return (
            <select value={currency} onChange={onCurrencyChange}>
                <option value="USD">United States dollar</option>
                <option value="EUR">Euro</option>
            <PayPalButtons />

    To learn more, check out the dynamic currency example in storybook.


    The <PayPalButtons /> component is fully documented in Storybook. Checkout the docs page for the PayPalButtons to learn more about the available props.


    The Braintree SDK can be used with the PayPal JS SDK to render the PayPal Buttons. Read more about this integration in the Braintree PayPal client-side integration docs. The <BraintreePayPalButtons /> component is designed for Braintree merchants who want to render the PayPal button.

    // App.js
    import {
    } from "@paypal/react-paypal-js";
    export default function App() {
        return (
                    "client-id": "test",
                    "data-client-token": "abc123xyz==",
                    createOrder={(data, actions) => {
                        return actions.braintree.createPayment({
                            flow: "checkout",
                            amount: "10.0",
                            currency: "USD",
                            intent: "capture"
                    onApprove={(data, actions) => {
                        return actions.braintree.tokenizePayment(data)
                            .then((payload) => {
                                // call server-side endpoint to finish the sale

    Checkout the docs page for the BraintreePayPalButtons to learn more about the available props.

    Browser Support

    This library supports all popular browsers, including IE 11. It provides the same browser support as the JS SDK. Here's the full list of supported browsers.


    npm i @paypal/react-paypal-js

    DownloadsWeekly Downloads






    Unpacked Size

    163 kB

    Total Files


    Last publish


    • hlahlou
    • sioked
    • westeezy
    • sdk-integrations-npm
    • frnuzzi
    • paypal-user
    • bluepnume
    • bladebarringer
    • braintree
    • rajarampadmanathan
    • joshbeam
    • bryanjenningz
    • zhillb
    • weihou
    • seavenly
    • tifzhou
    • rpalanikumar
    • songz
    • merlinpatt
    • jfurman
    • ravishekhar00
    • visheei94
    • gregjopa
    • mstuart
    • antre
    • mnicpt
    • elizabethmv
    • nbierdeman
    • shrkapoor
    • amyegan
    • chetanjk
    • shrutikapoor08
    • remotevision
    • dturgumbaev
    • rygilbert_paypal