React Native SDK

The React Native SDK provides mobile-optimized methods for food logging flows.

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:

  1. Requests a signed upload URL from Macrofy
  2. Reads the image bytes from the local URI
  3. Uploads to the signed URL
  4. Polls the job status until complete
  5. 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.

Was this page helpful?