Skip to content

Commit 76e0ea3

Browse files
authored
docs(brownie): add getting started guide with XCFramework flow (#196)
Complete walkthrough from store definition to native integration. Simplifies overview page and links to new guide.
1 parent b823815 commit 76e0ea3

4 files changed

Lines changed: 160 additions & 65 deletions

File tree

docs/docs/brownie/_meta.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"name": "overview",
55
"label": "Overview"
66
},
7+
{
8+
"type": "file",
9+
"name": "getting-started",
10+
"label": "Getting Started"
11+
},
712
{
813
"type": "file",
914
"name": "store-definition",
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Getting Started
2+
3+
This guide walks you through setting up Brownie from scratch - defining stores, generating native types, building XCFrameworks, and using shared state in both React Native and Swift.
4+
5+
## Prerequisites
6+
7+
Before starting, ensure you have:
8+
9+
- Completed the [React Native Brownfield Quick Start](/docs/getting-started/quick-start) guide
10+
- React Native project with `@callstack/react-native-brownfield` installed
11+
- Native iOS app (SwiftUI or UIKit)
12+
- Xcode 15+
13+
14+
## Step 1: Install Brownie
15+
16+
In your React Native project:
17+
18+
```bash
19+
npm install @callstack/brownie
20+
```
21+
22+
## Step 2: Define Your Store
23+
24+
Create a store definition file with the `.brownie.ts` extension:
25+
26+
```ts
27+
// src/stores/AppStore.brownie.ts
28+
import type { BrownieStore } from '@callstack/brownie';
29+
30+
interface AppStore extends BrownieStore {
31+
counter: number;
32+
}
33+
34+
declare module '@callstack/brownie' {
35+
interface BrownieStores {
36+
AppStore: AppStore;
37+
}
38+
}
39+
```
40+
41+
Import the store in your app entry point:
42+
43+
```ts
44+
// App.tsx
45+
import './stores/AppStore.brownie';
46+
```
47+
48+
## Step 3: Use the Store in React Native
49+
50+
```tsx
51+
import { useStore } from '@callstack/brownie';
52+
53+
function Counter() {
54+
const [counter, setState] = useStore('AppStore', (s) => s.counter);
55+
56+
return (
57+
<View>
58+
<Text>Count: {counter}</Text>
59+
<Button
60+
title="Increment"
61+
onPress={() => setState((prev) => ({ counter: prev.counter + 1 }))}
62+
/>
63+
</View>
64+
);
65+
}
66+
```
67+
68+
## Step 4: Build XCFrameworks
69+
70+
The CLI generates native types and builds everything into XCFrameworks:
71+
72+
```bash
73+
npx brownfield package:ios --scheme YourScheme --configuration Release
74+
```
75+
76+
This produces the following in `ios/.brownfield/package/`:
77+
78+
- `YourScheme.xcframework` - Your React Native module
79+
- `Brownie.xcframework` - Shared state library
80+
- `ReactBrownfield.xcframework` - Brownfield integration
81+
- `hermesvm.xcframework` - JavaScript engine (or `hermes.xcframework` for RN < 0.82.0)
82+
83+
:::info
84+
The `package:ios` command automatically runs `brownfield codegen` to generate Swift types from your `.brownie.ts` files.
85+
:::
86+
87+
## Step 5: Add Frameworks to Native App
88+
89+
1. Open your native Xcode project
90+
2. Drag all XCFrameworks from `ios/.brownfield/package/` into your project
91+
3. In target settings → **General****Frameworks, Libraries, and Embedded Content**, set all to **Embed & Sign**
92+
93+
## Step 6: Register Store in Swift
94+
95+
In your app's entry point, register the store with initial state:
96+
97+
```swift
98+
import Brownie
99+
import ReactBrownfield
100+
import SwiftUI
101+
102+
let initialState = AppStore(counter: 0)
103+
104+
@main
105+
struct MyApp: App {
106+
init() {
107+
ReactNativeBrownfield.shared.startReactNative {
108+
print("React Native loaded")
109+
}
110+
111+
AppStore.register(initialState)
112+
}
113+
114+
var body: some Scene {
115+
WindowGroup {
116+
ContentView()
117+
}
118+
}
119+
}
120+
```
121+
122+
## Step 7: Use the Store in SwiftUI
123+
124+
```swift
125+
import Brownie
126+
import SwiftUI
127+
128+
struct CounterView: View {
129+
@UseStore(\AppStore.counter) var counter
130+
131+
var body: some View {
132+
VStack {
133+
Text("Count: \(Int(counter))")
134+
Button("Increment") {
135+
$counter.set { $0 + 1 }
136+
}
137+
}
138+
}
139+
}
140+
```
141+
142+
## Done!
143+
144+
State changes now sync automatically between React Native and Swift. Increment from either side and both update immediately.
145+
146+
## Next Steps
147+
148+
- [Defining Stores](/brownie/store-definition) - Nested objects and multiple stores
149+
- [TypeScript Usage](/brownie/typescript-usage) - Advanced React Native patterns
150+
- [Swift Usage](/brownie/swift-usage) - UIKit integration and API reference
151+
- [XCFramework Packaging](/brownie/xcframework-packaging) - SPM distribution and advanced options

docs/docs/brownie/overview.mdx

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,75 +32,12 @@ Brownie is a shared state management library for React Native brownfield apps. I
3232

3333
1. Define your store shape in a `*.brownie.ts` file using TypeScript
3434
2. Run `brownfield codegen` to generate native types
35-
3. Use `useStore` in React Native and `Store<T>` in Swift
35+
3. Use `useStore` in React Native and `@UseStore` in Swift
3636
4. State changes sync automatically between both sides
3737

38-
## Installation
39-
40-
```bash
41-
npm install @callstack/brownie
42-
# or
43-
yarn add @callstack/brownie
44-
```
45-
46-
## Quick Example
47-
48-
**TypeScript (store definition):**
49-
50-
```ts
51-
// BrownfieldStore.brownie.ts
52-
import type { BrownieStore } from '@callstack/brownie';
53-
54-
interface AppStore extends BrownieStore {
55-
counter: number;
56-
user: { name: string };
57-
}
58-
59-
declare module '@callstack/brownie' {
60-
interface BrownieStores {
61-
AppStore: AppStore;
62-
}
63-
}
64-
```
65-
66-
**TypeScript (usage):**
67-
68-
```tsx
69-
import { useStore } from '@callstack/brownie';
70-
71-
function Counter() {
72-
const [counter, setState] = useStore('AppStore', (s) => s.counter);
73-
74-
return (
75-
<Button
76-
title={`Count: ${counter}`}
77-
onPress={() => setState((prev) => ({ counter: prev.counter + 1 }))}
78-
/>
79-
);
80-
}
81-
```
82-
83-
**Swift (usage):**
84-
85-
```swift
86-
import Brownie
87-
88-
struct ContentView: View {
89-
@UseStore(\AppStore.counter) var counter
90-
91-
var body: some View {
92-
VStack {
93-
Text("Count: \(Int(counter))")
94-
Button("Increment") {
95-
$counter.set { $0 + 1 }
96-
}
97-
}
98-
}
99-
}
100-
```
101-
10238
## Next Steps
10339

40+
- [Getting Started](/brownie/getting-started) - Step-by-step setup guide
10441
- [Defining Stores](/brownie/store-definition) - Learn how to define your store schema
10542
- [Code Generation](/brownie/codegen) - Configure and run the codegen CLI
10643
- [TypeScript Usage](/brownie/typescript-usage) - Use stores in React Native

docs/docs/brownie/xcframework-packaging.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Running `npx brownfield package:ios` produces the following XCFrameworks in `ios
1313

1414
The consumer app needs to embed all 4 frameworks when using Brownie.
1515

16+
Note: This command also takes care of running `brownfield codegen` for you.
17+
1618
## Integration Options
1719

1820
### Drag and Drop

0 commit comments

Comments
 (0)