> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expo Boilerplate

> Start an Expo and React Native app that sells a subscription with Dodo Payments hosted checkout, a demo Express backend, and deep-link payment results.

<Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/expo-boilerplate">
  The Expo, React Native, and Dodo Payments boilerplate.
</Card>

## Overview

The Expo boilerplate is a working Expo app that sells a subscription plan through Dodo Payments hosted checkout. It has two parts: an Expo Router app in TypeScript, and a small Express server in `server/` that creates checkout sessions with your API key. The app asks the server for a checkout URL, opens it in the system browser with `expo-web-browser`, and receives the result through a deep link.

<Info>
  The boilerplate uses Expo SDK 54, Expo Router, and TypeScript. The API key stays on the server. The app only knows the server's URL.
</Info>

<Frame>
  <iframe className="w-full aspect-video rounded-md" src="https://www.youtube.com/embed/78N1qw14m0Y" title="Expo Boilerplate Demo | Dodo Payments" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
</Frame>

## Prerequisites

* Node.js 18 or later.
* Expo CLI or EAS CLI.
* A Dodo Payments account with a product. Create the product under **Products** in the dashboard.
* An iOS Simulator, an Android Emulator, or a physical device.

## Quick Start

<Steps>
  <Step title="Clone the Repository">
    Clone the boilerplate repository and go to the project directory:

    ```bash theme={null}
    git clone https://github.com/dodopayments/expo-boilerplate.git
    cd expo-boilerplate
    ```
  </Step>

  <Step title="Get Your API Credentials">
    Get your API key from the Dodo Payments dashboard in test mode:

    * **API Key**: Go to **Developer → API Keys** in your [dashboard](https://app.dodopayments.com).

    <Tip>
      Build in test mode, which simulates payments without moving real money.
    </Tip>
  </Step>

  <Step title="Configure Environment Variables">
    The app and the server each read their own `.env` file. Copy both example files:

    ```bash theme={null}
    cp .env.example .env
    cp server/.env.example server/.env
    ```

    In `server/.env`, add your API key. `DODOPAYMENTS_RETURN_URL` must use the `scheme` from `app.json`, which is `dodoexpo` in the boilerplate:

    ```bash server/.env theme={null}
    DODOPAYMENTS_API_KEY=your_test_api_key_here
    DODOPAYMENTS_ENVIRONMENT=test_mode
    DODOPAYMENTS_RETURN_URL=dodoexpo://payment/result
    PORT=3000
    ```

    In the root `.env`, set `EXPO_PUBLIC_BACKEND_URL` to the server's URL, for example `http://localhost:3000`. The app sends checkout requests to `EXPO_PUBLIC_BACKEND_URL/checkout`.

    Then open `server/server.js` and replace `your-product-id` with the ID of your product. Product IDs start with `pdt_`.

    <Warning>
      Never commit your `.env` files to version control. The root `.gitignore` already excludes `.env`.

      Never put a Dodo Payments API key in an `EXPO_PUBLIC_*` variable. Expo embeds these variables in the JavaScript bundle, so anyone who downloads your app can read them. Keep the key on your server, as the boilerplate does, and pass only the resulting `checkout_url` to the app. See [Mobile Integration](/developer-resources/mobile-integration).
    </Warning>
  </Step>

  <Step title="Install Dependencies">
    Install the packages for the app and for the server:

    ```bash theme={null}
    npm install
    cd server && npm install && cd ..
    ```
  </Step>

  <Step title="Start the Development Server">
    Start the backend in one terminal, then start Expo in a second terminal:

    ```bash theme={null}
    # Terminal 1: the checkout server
    cd server && npm run dev

    # Terminal 2: the Expo app
    npx expo start
    ```

    Press `i` for the iOS Simulator or `a` for the Android Emulator, or scan the QR code on your device. The project includes `expo-dev-client`, and the `dodoexpo://` return link needs your app's own scheme, so run the app in a development build (`npx expo run:ios` or `npx expo run:android`) rather than Expo Go.

    A physical device can't reach `localhost` on your computer. To test on a device, set `EXPO_PUBLIC_BACKEND_URL` to your computer's local network address, for example `http://192.168.1.10:3000`.

    <Check>
      The home screen shows a plan card with a checkout button. Tap it to open checkout, pay with the test card `4242 4242 4242 4242`, and the app opens its payment result screen.
    </Check>
  </Step>
</Steps>

## What's Included

The boilerplate includes:

<CardGroup cols={2}>
  <Card title="Checkout Integration" icon="shopping-cart">
    A demo server that creates checkout sessions, and an app service that requests and opens them.
  </Card>

  <Card title="Payment Handling" icon="credit-card">
    A result screen that reads the `status` from the `dodoexpo://payment/result` deep link and shows success or failure.
  </Card>

  <Card title="TypeScript Support" icon="code">
    TypeScript configuration with types for the checkout request and response.
  </Card>

  <Card title="Expo Router" icon="route">
    File-based navigation with Expo Router, including a tab layout and the payment result route.
  </Card>
</CardGroup>

## Project Structure

These are the main files in the repository:

```
expo-boilerplate/
├── app/
│   ├── (tabs)/
│   │   ├── index.tsx          # Home screen with the plan card and checkout button
│   │   └── profile.tsx
│   ├── payment/
│   │   └── result.tsx         # Payment result screen (deep-link target)
│   └── _layout.tsx            # Root layout and deep-link handling
├── components/
│   └── payments/              # PaymentButton, ProductCard, and related UI
├── config/
│   ├── env.ts                 # Reads EXPO_PUBLIC_BACKEND_URL
│   └── product.ts             # Plan name, price text, and features
├── services/
│   └── dodo-payments.ts       # Requests a checkout URL and opens it
├── types/
│   └── dodo-payments.ts       # Checkout types
├── server/                    # Demo Express server that creates checkout sessions
│   ├── server.js
│   └── .env.example
├── .env.example               # App environment variables template
├── app.json                   # App name, scheme, and bundle identifiers
└── package.json
```

## Next Steps

After the boilerplate runs:

<Steps>
  <Step title="Create Your Products">
    Add products in your [Dodo Payments dashboard](https://app.dodopayments.com), and use their IDs in `server/server.js`.
  </Step>

  <Step title="Customize the Integration">
    Change the plan text in `config/product.ts`, and change the app name, `scheme`, and bundle identifiers in `app.json`. If you change the `scheme`, update `DODOPAYMENTS_RETURN_URL` to match.
  </Step>

  <Step title="Test on Real Devices">
    Test the payment flow and the deep-link return on physical iOS and Android devices.
  </Step>

  <Step title="Go Live">
    Replace the demo server with your own backend that authenticates users and grants access from webhooks. Then switch to a live mode API key and build your app for production.
  </Step>
</Steps>

## Building for Production

Build store-ready binaries with EAS Build:

<Steps>
  <Step title="Install EAS CLI">
    ```bash theme={null}
    npm install -g eas-cli
    ```
  </Step>

  <Step title="Configure EAS">
    The repository has no `eas.json`. This command creates one:

    ```bash theme={null}
    eas build:configure
    ```
  </Step>

  <Step title="Build Your App">
    For iOS:

    ```bash theme={null}
    eas build --platform ios
    ```

    For Android:

    ```bash theme={null}
    eas build --platform android
    ```
  </Step>
</Steps>

## Additional Resources

<CardGroup cols={2}>
  <Card title="Mobile Integration Guide" icon="mobile" href="/developer-resources/mobile-integration">
    The mobile checkout SDKs, deep-link setup, and mobile checkout settings.
  </Card>

  <Card title="Integration Guide" icon="book" href="/developer-resources/integration-guide">
    Checkout sessions, payment links, and webhooks.
  </Card>

  <Card title="API Reference" icon="brackets-curly" href="/api-reference/introduction">
    Every Dodo Payments API endpoint.
  </Card>
</CardGroup>

## Support

For help with the boilerplate:

* Ask questions in the [Discord community](https://discord.gg/bYqAp4ayYh).
* Report issues in the [GitHub repository](https://github.com/dodopayments/expo-boilerplate).
* Email the [support team](mailto:support@dodopayments.com).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.