React Native guide
Build a Food Tracking App with React Native
This guide wires the three endpoints a food tracker needs (autocomplete suggest, food details, and barcode lookup) into a React Native app. Requests are routed through a small backend proxy so your API key never ships inside the app binary.
Set up a backend proxy
Mobile binaries can be decompiled, so keep the X-API-Key header server-side. A minimal Express proxy forwards search traffic and adds the key:
const express = require('express')
const app = express()
const API_BASE = 'https://calorieapiadmin.com/api/v1'
app.get('/api/food-search', async (req, res) => {
const url = new URL(API_BASE + '/search/suggest')
url.searchParams.set('q', req.query.q ?? '')
url.searchParams.set('limit', '10')
const upstream = await fetch(url, {
headers: { 'X-API-Key': process.env.CALORIE_API_KEY },
})
res.status(upstream.status).json(await upstream.json())
})
app.listen(3001)Debounced autocomplete
Debounce keystrokes so a fast typist costs one request instead of ten. It keeps the UI responsive and conserves your monthly quota.
import { useEffect, useState } from 'react'
export function useFoodSuggest(query: string) {
const [results, setResults] = useState([])
useEffect(() => {
if (query.length < 2) return
const t = setTimeout(async () => {
const res = await fetch(
`https://your-backend.example.com/api/food-search?q=${encodeURIComponent(query)}`
)
if (res.ok) setResults(await res.json())
}, 250)
return () => clearTimeout(t)
}, [query])
return results
}Fetch full nutrition on selection
Suggest responses are intentionally lightweight (id, name, brand_name). When the user picks a suggestion, fetch GET /api/v1/foods/{id} through your proxy for per-100g macros, the nutrients array, and serving metadata, then compute logged amounts from the per-100g values.
Barcode scanning
Pair a scanner library (for example expo-barcode-scanner) with the barcode endpoint. The API resolves UPC/EAN codes against the local catalog and falls back to Open Food Facts automatically, so one code path covers both.
const onBarCodeScanned = async ({ data: upc }) => {
const res = await fetch(
`https://your-backend.example.com/api/barcode/${upc}`
)
if (res.status === 404) {
// Unknown product, fall back to manual search
navigation.navigate('FoodSearch')
return
}
const food = await res.json()
navigation.navigate('LogFood', { food })
}Production tips
- Cache food details by ID on-device, IDs are stable, and re-logging favorites then costs zero API calls.
- Handle 429 with backoff using the X-RateLimit-Reset header; surface 402 (quota) as an app-level alert to yourself, not to end users.
- Send X-API-Usage-Type: commercial from your proxy once the app monetizes (requires the Plus plan or higher).
Frequently asked questions
Can I call the Calorie API directly from React Native?
Technically yes, but you would ship your API key inside the binary. Route requests through a backend proxy so the key stays secret and you can add per-user throttling.
Which barcode scanner library works best?
Any library that returns raw UPC/EAN digits works, expo-barcode-scanner and react-native-vision-camera are common choices. The API accepts the digits as-is; dashes are stripped automatically.
