@vio-live/react-native-sdk
v0.1.0-beta.1
Published
Vio React Native SDK — commerce logic and ready-made components for iOS and Android from one codebase
Maintainers
Readme
Vio React Native SDK
The Vio platform lets you administer and synchronize ecommerce data across systems and platforms.
This SDK helps you integrate ecommerce into any React Native app (Android & iOS). It is built on top of Vio’s APIs and provides capabilities to retrieve products and collections from your Vio account, add items to a cart, handle payments, and complete checkout.
Companion to Vio's iOS (SwiftUI), Android (Compose) and web SDKs. Same platform, same campaigns, same sponsors — one codebase for iOS and Android.
Why Vio?
With Vio you can sell your own products or access products from merchants you collaborate with. You can add ecommerce to any app or platform while orders, inventory, and product information stay synchronized with the underlying ecommerce systems.
Features
- APIs: REST & GraphQL
- Products & Collections
- Cart
- Checkout
- Payments
- Orders
- Multi-currency
- Ecommerce integrations
Installation
# npm
npm install @vio-live/react-native-sdk
# yarn
yarn add @vio-live/react-native-sdkreact is the only peer dependency, and the SDK has zero runtime dependencies. To keep the
cart across app restarts, also install AsyncStorage — it is optional, and the SDK
falls back to an in-memory store without it:
yarn add @react-native-async-storage/async-storageQuick start
import AsyncStorage from '@react-native-async-storage/async-storage';
import { VioProvider } from '@vio-live/react-native-sdk/react';
export default function App() {
return (
<VioProvider
apiKey={VIO_API_KEY}
environment="production" // development | testing | production
storage={AsyncStorage}
currency="NOK"
country="NO"
>
<Navigation />
</VioProvider>
);
}One call, no URLs to remember — the environment resolves them. Behind the provider, the SDK reads the campaign, its sponsors and the market, and signs every commerce call with the right sponsor's key.
import { useProducts, useCart } from '@vio-live/react-native-sdk/react';
function ProductList() {
const { data: products, loading, error, refetch } = useProducts();
const { addItem, itemCount, subtotal } = useCart();
if (loading) return <ActivityIndicator />;
if (error) return <Text onPress={refetch}>{error.message} — tap to retry</Text>;
return (
<FlatList
data={products}
keyExtractor={(product) => String(product.id)}
ListHeaderComponent={<Text>{`${itemCount} items · ${subtotal} NOK`}</Text>}
renderItem={({ item }) => (
<Button title={item.title} onPress={() => addItem({ productId: item.id, quantity: 1 })} />
)}
/>
);
}Checkout and payment follow the same shape:
const { cart } = useCart();
const { checkout, create, update } = useCheckout({ cartId: cart?.cart_id });
const { methods, createKlarnaSession, createStripeIntent, processing } = usePayment();
await create();
await update({ billingAddress, shippingAddress, acceptsTermsConditions: true });
const klarna = await createKlarnaSession({
checkoutId: checkout.id,
countryCode: 'NO',
href: 'https://yourapp.example/confirmation',
});Klarna returns an html_snippet for a WebView, Vipps a payment_url for Linking.openURL, and
Stripe a client_secret for @stripe/stripe-react-native.
Backend-driven screens
Bind a screen to a slot instead of hardcoding products, and campaigns, products or sponsors can change without an app release:
const { data: components } = useComponents({ locationId: 'home-top' });
const { data: sponsor } = useSponsor();Hooks
| Hook | What it gives you |
| --- | --- |
| useCart(options?) | cart, lineItems, itemCount, subtotal, shipping, total, addItem, updateItem, removeItem, setShippingCountry, refresh, clear |
| useProducts(input?, options?) / useProduct(input, options?) | Catalog products, with currency/shippingCountryCode defaulted from the provider |
| useCategories() / useMarkets() / useChannelMarkets() | Categories, account markets, channel markets |
| useCheckout(options?) | checkout, create, update, refresh, remove |
| usePayment() | methods plus createStripeIntent, createStripeLink, createKlarnaSession, createVippsPayment, the REST status calls, and a processing flag |
| useBootstrap() / useSponsor() / useComponents(input?) | Campaign, sponsors and the components bound to a slot |
| useVio() / useCommerceOptions() | Provider value / the sponsor-scoped options to pass to any core function |
Every query hook returns { data, loading, error, refetch } and accepts { skip: true }. Mutating
calls resolve to the new state and set error instead of leaving an unhandled rejection — except
the usePayment calls, which record the error and re-throw so a screen can catch.
Without React
The client works standalone; the hooks are just a layer on top of it:
import { Vio } from '@vio-live/react-native-sdk';
Vio.init({ apiKey, environment: 'production' });
const products = await Vio.catalog.getProducts({ currency: 'NOK' });
const cart = await Vio.cart.createCart({ currency: 'NOK', customerSessionId: sessionId });
// Scope any call to a sponsor
const sponsored = await Vio.catalog.getProducts({ currency: 'NOK' }, { sponsorId: 2 });Domains: Vio.catalog, Vio.cart, Vio.checkout, Vio.payments, Vio.discounts, Vio.markets,
plus Vio.bootstrap() and Vio.components() for the Vio layer.
Entry points
| Import | What you get |
| --- | --- |
| @vio-live/react-native-sdk | headless core (SdkClient, modules, types) |
| @vio-live/react-native-sdk/core | same as above, explicit |
| @vio-live/react-native-sdk/react | VioProvider + hooks |
| @vio-live/react-native-sdk/ui | ready-made components — not implemented yet, see docs/rn-sdk-plan.md |
The same four-entry layout as @vio-live/web-sdk.
Both CommonJS and ESM are published; main is CommonJS because that is what Metro and Jest
resolve most reliably.
Local development
yarn install
yarn test # jest; yarn test:watch / yarn test:coverage
yarn typecheck # tsc over src, test and demo
yarn lint # eslint + prettier; yarn lint:fix
yarn build # emits dist/ (committed, and what npm publishes)Architecture and roadmap: docs/rn-sdk-plan.md. Guidance for AI agents: CLAUDE.md.
