React Native SDK
The React Native SDK provides mobile-optimized methods for food logging flows.
Macrofy is API-first. The SDK is a convenience layer — you can always call the HTTP API directly.
Packages
- Name
@macrofy/core- Type
- npm
- Description
Shared TypeScript client with typed request/response models.
- Name
@macrofy/react-native- Type
- npm
- Description
Mobile conveniences: URI-based uploads, automatic polling, Expo/bare RN support.
Install
npm install @macrofy/react-native
# or
pnpm add @macrofy/react-native
Setup
import { MacrofyClient } from '@macrofy/react-native'
export const macrofy = new MacrofyClient({
apiKey: process.env.EXPO_PUBLIC_MACROFY_API_KEY!,
clientId: 'your-app', // Used for image scan jobs
})
Core methods
searchFoods
Search foods by name.
const results = await macrofy.searchFoods({ q: 'banana' })
lookupBarcode
Resolve a barcode scanned from the camera.
const food = await macrofy.lookupBarcode({ upc: '012000161155' })
scanImageFromUri
The primary mobile method — takes a local image URI, uploads it, polls until complete, and returns structured nutrition.
// After capturing a photo with expo-camera or react-native-image-picker
const result = await macrofy.scanImageFromUri(photoUri, {
contentType: 'image/jpeg',
})
// result.items = [
// { name: 'Chicken bowl', macros: { calories: 540, protein: 42, ... } }
// ]
This method:
- Requests a signed upload URL from Macrofy
- Reads the image bytes from the local URI
- Uploads to the signed URL
- Polls the job status until complete
- Returns the structured result
Example: Food logging flow
import { useState } from 'react'
import { Button, Text } from 'react-native'
import { CameraView, useCameraPermissions } from 'expo-camera'
import { macrofy } from './macrofy'
export function ScanScreen() {
const [permission, requestPermission] = useCameraPermissions()
const [result, setResult] = useState(null)
const [loading, setLoading] = useState(false)
const handleCapture = async (uri: string) => {
setLoading(true)
try {
const scanResult = await macrofy.scanImageFromUri(uri, {
contentType: 'image/jpeg',
})
setResult(scanResult)
} finally {
setLoading(false)
}
}
if (!permission?.granted) {
return <Button title="Grant camera access" onPress={requestPermission} />
}
return (
<>
<CameraView
onPictureTaken={(photo) => handleCapture(photo.uri)}
/>
{loading && <Text>Analyzing...</Text>}
{result && <Text>{JSON.stringify(result.items)}</Text>}
</>
)
}
Adapter pattern (advanced)
For bare React Native projects or custom file system handling, you can provide adapters:
import { MacrofyClient } from '@macrofy/react-native'
import { createCustomAdapters } from './adapters'
const macrofy = new MacrofyClient({
apiKey: process.env.MACROFY_API_KEY!,
clientId: 'your-app',
adapters: createCustomAdapters(), // FileSystem, Storage adapters
})
See the SDK Extraction Plan for adapter interface specs.
Error handling
import { MacrofyError } from '@macrofy/react-native'
try {
await macrofy.scanImageFromUri(uri)
} catch (err) {
if (err instanceof MacrofyError) {
Alert.alert('Error', err.message)
}
}
UI components (coming soon)
A @macrofy/ui package with pre-built React Native components (CaloriesRing, MacroBar, MealsList) is planned. For now, build your own UI using the SDK methods.