All posts
tutorial mobile

Adding Barcode Scanning to Your App

How to integrate barcode scanning with FoodBase to instantly look up product nutrition data.

updated July 24, 2026 FoodBase Team 3 min read

Why barcode scanning?

Barcode scanning is the killer feature of nutrition apps. Users point their phone at a product, and instantly see calories, macros, and ingredients. With 6.1 million products in our database — including 4.1 million with barcodes from Open Food Facts — your app can recognize most products on store shelves worldwide.

How barcodes work

Most food products use one of two barcode formats:

  • EAN-13 (13 digits) — used globally, especially in Europe, Asia, and Australia
  • UPC-A (12 digits) — used primarily in North America

Our API accepts both formats. Just pass the numeric code to the barcode endpoint:

curl "https://foodbase.dev/v1/foods/barcode/5449000000996" \
  -H "X-API-Key: food_your_key_here"

Choosing a scanner library

Web apps (camera-based)

For web apps, ZXing or QuaggaJS can read barcodes from a video stream:

// Using html5-qrcode (lightweight, well-maintained)
import { Html5QrcodeScanner } from "html5-qrcode";

const scanner = new Html5QrcodeScanner("reader", {
  fps: 10,
  qrbox: { width: 250, height: 250 },
});

scanner.render(async (barcode) => {
  scanner.clear();
  const product = await lookupBarcode(barcode);
  if (product) {
    displayProduct(product);
  } else {
    showNotFound(barcode);
  }
});

React Native / mobile

For React Native, use react-native-camera or expo-barcode-scanner:

import { BarCodeScanner } from "expo-barcode-scanner";

function Scanner() {
  const handleScan = async ({ data }) => {
    const product = await lookupBarcode(data);
    // Navigate to product detail screen
  };

  return <BarCodeScanner onBarCodeScanned={handleScan} />;
}

Native iOS/Android

  • iOS: Use AVFoundation’s AVCaptureMetadataOutput for built-in barcode detection
  • Android: Use Google’s ML Kit Barcode Scanning API

The lookup function

Here’s the API integration that works with any scanner:

const API_KEY = "food_your_key_here";

async function lookupBarcode(barcode) {
  const res = await fetch(
    `https://foodbase.dev/v1/foods/barcode/${barcode}`,
    { headers: { "X-API-Key": API_KEY } }
  );

  if (res.status === 404) return null; // Product not found
  if (!res.ok) throw new Error(`API error: ${res.status}`);

  return res.json();
}

What you get back

A successful barcode lookup returns the full product with a nutrition summary:

{
  "name_default": "Original Taste",
  "brand": "Coca-Cola",
  "barcode": "5449000000996",
  "nutriscore": "e",
  "nova_group": 4,
  "image_url": "https://images.openfoodfacts.org/...",
  "nutrition_summary": {
    "energy_kcal": 42,
    "proteins_g": 0,
    "carbs_g": 10.6,
    "fat_g": 0,
    "sugars_g": 10.6,
    "fiber_g": null
  },
  "allergens": null,
  "ingredients": [
    {"lang": "en", "text": "carbonated water, sugar, colour..."}
  ]
}

Handling “not found” products

Some scans won’t find a match — most often local or regional brands. Best practices:

  1. Show a clear message — “Product not found in our database”
  2. Let users search by name as a fallback
  3. Cache found products locally so repeat scans are instant
  4. Allow manual entry for products not in any database

No barcode? Use a photo

Two extra options when the barcode route dead-ends, both powered by AI credits (every plan includes an allowance):

  • POST /v1/vision/barcode decodes the barcode from a photo — no scanner library needed at all. It’s pure computer vision (0 credits, metered by your daily quota) and returns the matched product directly.
  • POST /v1/vision/product recognizes a product from its front-of-pack photo and returns scored catalog matches — the rescue path for damaged or missing barcodes.
async function lookupByPhoto(file) {
  const form = new FormData();
  form.append("image", file);
  const res = await fetch("https://foodbase.dev/v1/vision/product", {
    method: "POST",
    headers: { "X-API-Key": API_KEY },
    body: form,
  });
  if (!res.ok) return null;
  const { matches } = await res.json();
  return matches[0]?.product ?? null; // matches are score-ranked
}

You can try both in the browser on the photo playground.

Performance tips

  • Cache lookups locally — product data changes rarely, so found products can be cached client-side for a long time
  • Debounce scanner callbacks — some libraries fire multiple times for the same barcode
  • Prefetch common products — if you know your users’ shopping patterns, use the bulk endpoint to preload

Coverage notes

Barcode coverage follows the underlying data: strongest for products sold in Europe and North America, thinner for regional brands elsewhere — and it improves continuously as new products are added. Rather than trusting a static coverage table, test with the products your users actually scan: paste a barcode into the product explorer and see instantly whether it resolves.

Get started with barcode scanning — free tier includes barcode lookups.

Build it with FoodBase

6.1M products, 40+ nutrients and AI food analysis — free to start, no credit card.