@variantlab/react-native 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +166 -14
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,23 +1,175 @@
1
1
  # @variantlab/react-native
2
2
 
3
- React Native and Expo bindings for variantlab.
3
+ > React Native and Expo bindings for variantlab — storage adapters, auto-context, deep links, debug overlay, and QR sharing.
4
4
 
5
- > **Status:** Phase 1 — Pre-alpha. Not ready for production use.
5
+ ![npm version](https://img.shields.io/npm/v/@variantlab/react-native/alpha?label=npm&color=blue)
6
+ ![bundle size](https://img.shields.io/badge/gzip-%3C4KB-brightgreen)
6
7
 
7
- ## Peer dependencies
8
+ ## Install
8
9
 
9
- Required:
10
+ ```bash
11
+ npm install @variantlab/core@alpha @variantlab/react@alpha @variantlab/react-native@alpha
12
+ ```
10
13
 
11
- - `react` `^18.2.0 || ^19.0.0`
12
- - `react-native` `>=0.74.0`
14
+ **Peer dependencies (required):**
15
+ - `react ^18.2.0 || ^19.0.0`
16
+ - `react-native >=0.74.0`
13
17
 
14
- Optional (install what you need):
18
+ **Optional peer dependencies (install what you need):**
19
+ - `@react-native-async-storage/async-storage` — persistent storage
20
+ - `react-native-mmkv` — fast key-value storage
21
+ - `expo-secure-store` — encrypted storage
22
+ - `expo-localization` — locale detection
23
+ - `react-native-safe-area-context` — safe area for debug overlay
24
+ - `react-native-svg` — QR code rendering
15
25
 
16
- - `@react-native-async-storage/async-storage`
17
- - `react-native-mmkv`
18
- - `expo-secure-store`
19
- - `expo-localization`
20
- - `react-native-safe-area-context`
21
- - `react-native-svg`
26
+ ## Quick start
22
27
 
23
- See the [root README](../../README.md) for project overview, motivation, and roadmap.
28
+ ### 1. Create the engine with auto-context
29
+
30
+ ```tsx
31
+ import { createEngine } from "@variantlab/core";
32
+ import { getAutoContext, createAsyncStorageAdapter } from "@variantlab/react-native";
33
+ import AsyncStorage from "@react-native-async-storage/async-storage";
34
+ import experiments from "./experiments.json";
35
+
36
+ const engine = createEngine(experiments, {
37
+ context: getAutoContext(), // auto-detects platform, screenSize, locale
38
+ storage: createAsyncStorageAdapter(AsyncStorage),
39
+ });
40
+ ```
41
+
42
+ ### 2. Wrap your app
43
+
44
+ ```tsx
45
+ import { VariantLabProvider } from "@variantlab/react-native";
46
+
47
+ export default function App() {
48
+ return (
49
+ <VariantLabProvider engine={engine}>
50
+ <YourApp />
51
+ </VariantLabProvider>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ### 3. Use hooks (same API as @variantlab/react)
57
+
58
+ ```tsx
59
+ import { useVariant, useVariantValue, Variant } from "@variantlab/react-native";
60
+
61
+ function CardLayout() {
62
+ const variant = useVariant("card-layout");
63
+ // ...
64
+ }
65
+
66
+ function PriceDisplay() {
67
+ const price = useVariantValue<number>("pricing");
68
+ return <Text>${price}</Text>;
69
+ }
70
+ ```
71
+
72
+ ## Auto-context detection
73
+
74
+ `getAutoContext()` automatically detects:
75
+
76
+ | Field | Source |
77
+ |-------|--------|
78
+ | `platform` | `Platform.OS` (`ios`, `android`, `web`) |
79
+ | `screenSize` | `Dimensions.get("window").width` bucketed to `small` / `medium` / `large` |
80
+ | `locale` | `expo-localization` or `NativeModules` |
81
+ | `appVersion` | `expo-constants` or `DeviceInfo` |
82
+
83
+ ```tsx
84
+ import { getAutoContext } from "@variantlab/react-native";
85
+
86
+ const context = getAutoContext();
87
+ // { platform: "ios", screenSize: "medium", locale: "en", ... }
88
+ ```
89
+
90
+ ## Storage adapters
91
+
92
+ Choose the storage backend that fits your app:
93
+
94
+ ```tsx
95
+ import { createAsyncStorageAdapter } from "@variantlab/react-native";
96
+ import { createMMKVStorageAdapter } from "@variantlab/react-native";
97
+ import { createSecureStoreAdapter } from "@variantlab/react-native";
98
+ import { createMemoryStorage } from "@variantlab/react-native";
99
+
100
+ // AsyncStorage — most common, works everywhere
101
+ const storage = createAsyncStorageAdapter(AsyncStorage);
102
+
103
+ // MMKV — faster, synchronous reads
104
+ const storage = createMMKVStorageAdapter(mmkv);
105
+
106
+ // SecureStore — encrypted, for sensitive experiment data
107
+ const storage = createSecureStoreAdapter(SecureStore);
108
+
109
+ // Memory — no persistence, resets on restart (good for tests)
110
+ const storage = createMemoryStorage();
111
+ ```
112
+
113
+ ## Debug overlay
114
+
115
+ A built-in bottom-sheet UI for viewing and overriding experiments on device.
116
+
117
+ ```tsx
118
+ import { VariantDebugOverlay } from "@variantlab/react-native/debug";
119
+
120
+ export default function App() {
121
+ return (
122
+ <VariantLabProvider engine={engine}>
123
+ <YourApp />
124
+ {__DEV__ && <VariantDebugOverlay />}
125
+ </VariantLabProvider>
126
+ );
127
+ }
128
+ ```
129
+
130
+ The overlay shows:
131
+ - All active experiments and current assignments
132
+ - Tap to override any variant
133
+ - Current targeting context
134
+ - Assignment source (default, hash, override, etc.)
135
+
136
+ ## Deep link overrides
137
+
138
+ Allow QA to force variants via deep links:
139
+
140
+ ```
141
+ myapp://variantlab?set=hero-layout:split
142
+ ```
143
+
144
+ ```tsx
145
+ import { registerDeepLinkHandler } from "@variantlab/react-native";
146
+
147
+ // In your app setup
148
+ registerDeepLinkHandler(engine);
149
+ ```
150
+
151
+ ## QR sharing
152
+
153
+ Share experiment state with teammates via QR codes:
154
+
155
+ ```tsx
156
+ import { buildQrUrl, parseQrUrl } from "@variantlab/react-native/qr";
157
+
158
+ // Encode current state into a URL
159
+ const url = buildQrUrl(payload);
160
+
161
+ // Parse a scanned QR URL
162
+ const result = parseQrUrl(url);
163
+ ```
164
+
165
+ ## All re-exported hooks and components
166
+
167
+ This package re-exports everything from `@variantlab/react`:
168
+
169
+ **Hooks:** `useVariant`, `useVariantValue`, `useExperiment`, `useSetVariant`, `useVariantLabEngine`, `useRouteExperiments`
170
+
171
+ **Components:** `<Variant>`, `<VariantValue>`, `<VariantErrorBoundary>`, `<VariantLabProvider>`
172
+
173
+ ## License
174
+
175
+ [MIT](./LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@variantlab/react-native",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "React Native and Expo bindings for variantlab.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -60,19 +60,19 @@
60
60
  ],
61
61
  "repository": {
62
62
  "type": "git",
63
- "url": "git+https://github.com/variantlab/variantlab.git",
63
+ "url": "git+https://github.com/Minhaj-Rabby/variantlab.git",
64
64
  "directory": "packages/react-native"
65
65
  },
66
66
  "bugs": {
67
- "url": "https://github.com/variantlab/variantlab/issues"
67
+ "url": "https://github.com/Minhaj-Rabby/variantlab/issues"
68
68
  },
69
- "homepage": "https://github.com/variantlab/variantlab#readme",
69
+ "homepage": "https://github.com/Minhaj-Rabby/variantlab#readme",
70
70
  "engines": {
71
71
  "node": ">=18.17"
72
72
  },
73
73
  "dependencies": {
74
- "@variantlab/core": "0.1.0",
75
- "@variantlab/react": "0.1.0"
74
+ "@variantlab/core": "0.1.2",
75
+ "@variantlab/react": "0.1.2"
76
76
  },
77
77
  "peerDependencies": {
78
78
  "@react-native-async-storage/async-storage": "*",