---
title: "Quickstart"
description: "The smallest complete SubKit path — configure an app, identify a user, load an offering, run a purchase, and check an entitlement."
---

# Quickstart

This is the smallest end-to-end path through SubKit from a mobile app: configure
the SDK, identify the user, load an offering, run a purchase, and gate a feature
on an entitlement.

> **Tip**
>
> Backend integrator? Jump to the [Node.js overview](/docs/node/overview/) instead.

## Prerequisites

- An Expo / React Native app.
- A public, app-bound SubKit **SDK key** (`sk_sdk_…`), issued from trusted
  backend code. Never ship a server key in an app.
- The entitlement key your product grants, for example `pro`.

## Steps

1. **Install the SDK and its contract**

```sh
pnpm add @piparotech/subkit-core@^0.1.11 @piparotech/subkit-expo@^0.1.12
```
2. **Configure SubKit once at module scope**

   Do this at module scope, not inside a component.

```ts compile
// src/subkit.ts
import { configureSubKit } from '@piparotech/subkit-expo'

configureSubKit({
  sdkKey: 'sk_sdk_replace_me',
  installationId: 'install_abc', // generate once, persist locally, reuse
  appUserId: 'user_123', // optional until the user logs in
})
```
3. **Identify the user**

   Identify the user when they log in.

```ts compile
import { client } from '@piparotech/subkit-expo'

await client.identify(user.id)
```
4. **Load an offering and run a purchase**

   Prices and identifiers come from the runtime offering — never from static constants.

```ts compile
import { client } from '@piparotech/subkit-expo'

const offerings = await client.getOfferings()
const pkg = offerings.current?.packages[0]
if (pkg == null) throw new Error('No purchasable offering available')

const result = await client.purchasePackage(pkg.identifier)
```
5. **Read the effective access decision**

   Name the entitlement; let SubKit combine commercial, device, and offline policy.

```ts compile
const access = await client.getAccess('pro')

if (access.state === 'granted') {
  // unlock paid features
}
```

> **Never unlock early**
>
> A returned `purchasePackage(...)` call does not mean access is granted. The Expo adapter usually
> returns `pending`; SubKit confirms commerce, entitlement, device, and offline policy through
> verification and sync. Only unlock from `access.state === 'granted'`.

## What you just built

You configured an app with a public key, identified the user, rendered a
runtime offering, ran a verified purchase, and gated a feature on SubKit's
effective access decision. From here:

- [Expo / React Native](/docs/expo/overview/) — every purchase state, restore, and
  offline access.
- [Access model](/docs/concepts/access-model/) — why entitlements, not purchases,
  are the thing you check.

Source: https://subkit.piparo.tech/start/quickstart/index.mdx
