Free Macro Reference Tables: Download Complete Nutrition Data in CSV and JSON

Download free macro reference tables with complete nutrition data for 500+ common foods in CSV and JSON format. Includes protein, carbs, fat, fiber, and calories organized by food category.

Whether you are building a nutrition app, running a research study, coaching clients, or just want a reliable reference sheet on your desk, you need clean macro data in a format you can actually work with. Government databases exist, but they are sprawling, inconsistent, and formatted for bureaucrats rather than builders.

We put together a set of free macro reference tables covering over 500 common foods with complete macronutrient breakdowns. The data is available in both CSV and JSON formats, ready to drop into a spreadsheet, a database, a script, or an application. Every entry has been verified against primary sources, and the files are structured so you can start using them immediately without cleanup or transformation.

This page covers exactly what is in the tables, how the data is structured, how to load it programmatically, and how to contribute corrections if you find something that needs updating.

What Is Included

The macro reference tables contain 500+ of the most commonly consumed foods across seven major categories. For each food item, you get:

  • Food name — the standard English name used in nutrition science
  • Category — one of seven top-level categories (more on these below)
  • Subcategory — a more specific grouping within the parent category
  • Serving size description — a human-readable serving size (e.g., "1 medium banana", "1 cup cooked")
  • Serving weight in grams — the gram equivalent of that serving size
  • Calories — total energy in kilocalories (kcal)
  • Protein — grams of protein per serving
  • Total fat — grams of total fat per serving
  • Saturated fat — grams of saturated fat per serving
  • Total carbohydrates — grams of total carbohydrates per serving
  • Dietary fiber — grams of dietary fiber per serving
  • Sugar — grams of total sugars per serving
  • Sodium — milligrams of sodium per serving

Every value is reported per the listed serving size, not per 100 grams. We chose this approach because serving-based data is what most people actually need when tracking meals, building meal plans, or displaying nutrition information in an interface. If you need per-100g values, dividing by the serving weight and multiplying by 100 is straightforward.

The tables do not include micronutrients beyond sodium and fiber. For full micronutrient profiles (vitamins, minerals, amino acids), see the section on Nutrola's API at the end of this article — that is where the detailed data lives.

Data Format Specifications

CSV Format

The CSV file uses UTF-8 encoding with a header row. Fields are comma-delimited and text fields are quoted. Here is what the structure looks like:

food_name,category,subcategory,serving_description,serving_weight_g,calories_kcal,protein_g,total_fat_g,saturated_fat_g,total_carbs_g,fiber_g,sugar_g,sodium_mg
"Chicken Breast, boneless skinless, cooked","Proteins","Poultry","1 breast (170g)",170,284,53.4,6.2,1.7,0.0,0.0,0.0,126
"Atlantic Salmon, cooked","Proteins","Fish & Seafood","1 fillet (154g)",154,280,39.3,12.4,2.5,0.0,0.0,0.0,109
"Brown Rice, cooked","Grains & Starches","Whole Grains","1 cup (195g)",195,216,5.0,1.8,0.4,44.8,3.5,0.7,10
"Banana, raw","Fruits","Tropical Fruits","1 medium (118g)",118,105,1.3,0.4,0.1,27.0,3.1,14.4,1

The CSV file is compatible with Microsoft Excel, Google Sheets, LibreOffice Calc, Apple Numbers, and any programming language with CSV parsing support. No special configuration is needed — open the file and it will parse correctly.

JSON Format

The JSON file contains an array of objects, one per food item. The structure mirrors the CSV fields:

{
  "version": "1.4.0",
  "generated": "2026-03-12",
  "source": "Nutrola Macro Reference Tables",
  "record_count": 527,
  "foods": [
    {
      "food_name": "Chicken Breast, boneless skinless, cooked",
      "category": "Proteins",
      "subcategory": "Poultry",
      "serving_description": "1 breast (170g)",
      "serving_weight_g": 170,
      "nutrients": {
        "calories_kcal": 284,
        "protein_g": 53.4,
        "total_fat_g": 6.2,
        "saturated_fat_g": 1.7,
        "total_carbs_g": 0.0,
        "fiber_g": 0.0,
        "sugar_g": 0.0,
        "sodium_mg": 126
      }
    }
  ]
}

The JSON file includes metadata fields at the top level: a version string for tracking updates, the generation date, the source name, and the total record count. This makes it easy to verify you have the latest version and to build update-checking logic into your applications.

Numeric values are stored as numbers, not strings. Null values do not appear — if a nutrient value is unknown, the food is excluded from the dataset rather than included with missing data. This was a deliberate choice to keep the data clean and avoid silent errors in calculations.

Field Descriptions

Here is a detailed breakdown of every field, including units, expected ranges, and edge cases:

Field Type Unit Description
food_name string Standard English name. Includes preparation method where relevant (e.g., "cooked", "raw", "dried").
category string One of seven top-level categories. See the categories section below.
subcategory string A more specific grouping. For example, within "Proteins" you will find "Poultry", "Red Meat", "Fish & Seafood", "Legumes", and "Eggs".
serving_description string A human-readable serving size. Always includes the gram weight in parentheses.
serving_weight_g number grams The numeric gram weight of the serving. Integer values for most items, one decimal place for items where precision matters.
calories_kcal number kcal Total energy. Calculated using the Atwater system (4 kcal/g protein, 4 kcal/g carbs, 9 kcal/g fat).
protein_g number grams Total protein. One decimal place precision.
total_fat_g number grams Total fat including saturated, monounsaturated, and polyunsaturated.
saturated_fat_g number grams Saturated fatty acids only.
total_carbs_g number grams Total carbohydrates including fiber and sugars.
fiber_g number grams Total dietary fiber (soluble + insoluble).
sugar_g number grams Total sugars (naturally occurring + added). The dataset does not separate added sugars from natural sugars.
sodium_mg number milligrams Sodium content. Note this is milligrams, not grams, unlike the other nutrient fields.

A few notes on precision: all nutrient values are rounded to one decimal place. This matches the precision level of the underlying source data. Reporting more decimal places would imply a false level of accuracy — food composition varies naturally by 5-15% depending on growing conditions, animal breed, and preparation methods.

Food Categories

The 500+ foods are organized into seven top-level categories, each with multiple subcategories:

Proteins

Approximately 95 entries covering poultry (chicken breast, thigh, turkey, ground turkey), red meat (beef sirloin, ground beef at various lean percentages, pork loin, lamb), fish and seafood (salmon, tuna, shrimp, cod, tilapia, sardines), eggs (whole, whites, scrambled), and plant-based proteins (tofu, tempeh, seitan, edamame). Legumes like lentils, chickpeas, and black beans are included here rather than in grains because their primary nutritional role is protein delivery.

Grains and Starches

Approximately 80 entries covering whole grains (brown rice, oats, quinoa, barley, bulgur), refined grains (white rice, white bread, pasta), starchy vegetables (potatoes, sweet potatoes, corn), and common grain products (tortillas, bagels, crackers, couscous). Both cooked and dry values are provided for grains where the distinction matters.

Fruits

Approximately 65 entries covering common fresh fruits (apples, bananas, oranges, strawberries, blueberries, grapes), tropical fruits (mangoes, pineapple, papaya, kiwi), dried fruits (raisins, dates, dried apricots, cranberries), and frozen fruits. All fresh fruit entries are for the raw, edible portion — seeds, peels, and pits are excluded from the serving weight where applicable.

Vegetables

Approximately 85 entries covering leafy greens (spinach, kale, romaine, arugula), cruciferous vegetables (broccoli, cauliflower, Brussels sprouts, cabbage), root vegetables (carrots, beets, turnips, radishes), alliums (onions, garlic), nightshades (tomatoes, bell peppers, eggplant), and other common vegetables (cucumber, celery, zucchini, mushrooms, asparagus). Both raw and cooked values are provided for vegetables where cooking significantly changes the nutrient density per serving.

Dairy and Alternatives

Approximately 70 entries covering milk (whole, 2%, skim, and plant-based milks), yogurt (Greek, regular, flavored, plant-based), cheese (cheddar, mozzarella, feta, cottage cheese, cream cheese, parmesan), butter, cream, and common dairy alternatives (almond milk, oat milk, soy milk, coconut yogurt). Plant-based milks and yogurts are grouped here rather than in a separate category because users typically reach for them as direct substitutes.

Snacks and Processed Foods

Approximately 75 entries covering nuts and seeds (almonds, walnuts, peanuts, chia seeds, flaxseeds, sunflower seeds), nut butters (peanut butter, almond butter), common snack foods (pretzels, popcorn, granola bars, protein bars, trail mix, chips, dark chocolate), spreads and condiments (hummus, guacamole, salsa, mayonnaise, olive oil, honey), and other commonly tracked items like protein powder and energy bites.

Beverages

Approximately 60 entries covering juices (orange juice, apple juice, cranberry juice), soft drinks (cola, lemon-lime soda, ginger ale), sports and energy drinks, coffee drinks (black coffee, latte, cappuccino, mocha with various milk types), smoothie bases, alcoholic beverages (beer, wine, spirits), and common additions (cream, sugar, flavored syrups). Water is not included since it has no macronutrient content.

Using the Data Programmatically

The whole point of providing CSV and JSON formats is that you can load this data directly into your code. Here are working examples in Python and JavaScript.

Python: Loading the CSV

import csv

def load_macro_table(filepath):
    foods = []
    with open(filepath, newline='', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            # Convert numeric fields from strings
            for key in ['serving_weight_g', 'calories_kcal', 'protein_g',
                        'total_fat_g', 'saturated_fat_g', 'total_carbs_g',
                        'fiber_g', 'sugar_g', 'sodium_mg']:
                row[key] = float(row[key])
            foods.append(row)
    return foods

foods = load_macro_table('macro_reference_table.csv')

# Find all foods in a category
proteins = [f for f in foods if f['category'] == 'Proteins']
print(f"Found {len(proteins)} protein sources")

# Find the highest protein foods per calorie
foods_sorted = sorted(foods, key=lambda f: f['protein_g'] / max(f['calories_kcal'], 1), reverse=True)
print("\nTop 10 foods by protein density (g protein per kcal):")
for f in foods_sorted[:10]:
    ratio = f['protein_g'] / f['calories_kcal']
    print(f"  {f['food_name']}: {ratio:.3f} g/kcal ({f['protein_g']}g protein, {f['calories_kcal']} kcal)")

Python: Loading the JSON

import json

def load_macro_json(filepath):
    with open(filepath, encoding='utf-8') as f:
        data = json.load(f)
    print(f"Loaded {data['record_count']} foods (version {data['version']})")
    return data['foods']

foods = load_macro_json('macro_reference_table.json')

# Build a lookup dictionary by food name
lookup = {f['food_name'].lower(): f for f in foods}

# Quick lookup
chicken = lookup.get('chicken breast, boneless skinless, cooked')
if chicken:
    n = chicken['nutrients']
    print(f"Chicken breast per serving ({chicken['serving_description']}):")
    print(f"  Calories: {n['calories_kcal']} kcal")
    print(f"  Protein: {n['protein_g']}g")
    print(f"  Fat: {n['total_fat_g']}g")
    print(f"  Carbs: {n['total_carbs_g']}g")

JavaScript: Loading the JSON

// Node.js
const fs = require('fs');

function loadMacroTable(filepath) {
  const raw = fs.readFileSync(filepath, 'utf-8');
  const data = JSON.parse(raw);
  console.log(`Loaded ${data.record_count} foods (version ${data.version})`);
  return data.foods;
}

const foods = loadMacroTable('macro_reference_table.json');

// Group foods by category
const byCategory = {};
for (const food of foods) {
  if (!byCategory[food.category]) {
    byCategory[food.category] = [];
  }
  byCategory[food.category].push(food);
}

// Print summary
for (const [category, items] of Object.entries(byCategory)) {
  console.log(`${category}: ${items.length} foods`);
}

// Find low-calorie, high-fiber foods
const highFiber = foods
  .filter(f => f.nutrients.fiber_g >= 5 && f.nutrients.calories_kcal <= 200)
  .sort((a, b) => b.nutrients.fiber_g - a.nutrients.fiber_g);

console.log('\nHigh-fiber, low-calorie foods:');
highFiber.slice(0, 10).forEach(f => {
  console.log(`  ${f.food_name}: ${f.nutrients.fiber_g}g fiber, ${f.nutrients.calories_kcal} kcal`);
});

JavaScript: Loading the CSV in the Browser

// Browser-based CSV parsing (no dependencies)
async function loadMacroCSV(url) {
  const response = await fetch(url);
  const text = await response.text();
  const lines = text.split('\n').filter(line => line.trim());
  const headers = parseCSVLine(lines[0]);

  return lines.slice(1).map(line => {
    const values = parseCSVLine(line);
    const obj = {};
    headers.forEach((header, i) => {
      obj[header] = isNaN(values[i]) ? values[i] : parseFloat(values[i]);
    });
    return obj;
  });
}

function parseCSVLine(line) {
  const result = [];
  let current = '';
  let inQuotes = false;
  for (const char of line) {
    if (char === '"') { inQuotes = !inQuotes; }
    else if (char === ',' && !inQuotes) { result.push(current.trim()); current = ''; }
    else { current += char; }
  }
  result.push(current.trim());
  return result;
}

// Usage
const foods = await loadMacroCSV('/data/macro_reference_table.csv');
console.log(`Loaded ${foods.length} foods`);

These examples demonstrate the most common operations: loading the data, searching and filtering, grouping by category, and sorting by nutrient density. The data structures are intentionally simple so you do not need any special libraries to work with them.

Data Sources

The macro reference tables are compiled from the following primary sources:

USDA SR Legacy Database. The USDA Standard Reference Legacy database is the foundational dataset for US food composition. It contains laboratory-analyzed nutrient data for over 7,600 food items. Our tables use SR Legacy as the primary source for generic/unbranded foods. We chose SR Legacy over the newer FoodData Central FNDDS because SR Legacy values are more widely validated and cited in nutrition research.

USDA FoodData Central. For foods not covered in SR Legacy, particularly newer food items and updated values, we reference FoodData Central's Foundation Foods and Survey Foods datasets.

International food composition databases. For foods that are consumed globally but may not appear in US databases, we cross-reference data from Public Health England's McCance and Widdowson composition tables, Food Standards Australia New Zealand (FSANZ) NUTTAB, the Canadian Nutrient File (CNF), and the Danish Food Composition Databank (Frida). This is particularly relevant for tropical fruits, regional grains, and preparation methods common outside the US.

Manufacturer data. For processed and branded items in the snacks and beverages categories, we reference nutrition facts panels provided by manufacturers. Where manufacturer data conflicts with laboratory analysis, we note the discrepancy and default to the laboratory values.

All values have been cross-referenced against at least two independent sources. Where sources disagree by more than 10%, we investigated the cause (usually different preparation methods or cultivar differences) and selected the value most representative of how the food is typically consumed.

The dataset is versioned. The current version is 1.4.0, last updated March 2026. We update the tables approximately every quarter to incorporate corrections, add requested foods, and reflect any significant changes in source databases.

How to Contribute Corrections

Nutrition data is inherently imperfect. Food composition varies by region, season, cultivar, and preparation method. If you find an error or have a correction backed by a reliable source, we want to hear about it.

There are three ways to submit corrections:

GitHub Issues. The macro reference tables are hosted in a public GitHub repository. Open an issue with the food name, the field you believe is incorrect, the current value, the value you believe is correct, and a link to your source. We review issues weekly.

Email. Send corrections to data@nutrola.com with the same information: food name, field, current value, proposed value, and source. We will respond within five business days.

Pull requests. If you are comfortable with Git, you can fork the repository, edit the CSV or JSON file directly, and submit a pull request. Include your source in the PR description. We will review and merge corrections that are supported by reliable data.

We do not accept submissions for branded or proprietary products through this process. Those are handled through Nutrola's main food database pipeline, which has its own verification workflow.

Integration with Nutrola's API for Real-Time Data

The downloadable macro reference tables are a static snapshot — great for offline use, embedded applications, educational materials, and quick lookups. But if you need real-time nutrition data at scale, Nutrola's Nutrition Data API provides everything in these tables and much more.

The API covers over 3 million food entries (compared to 500+ in the reference tables), includes full micronutrient profiles with 70+ nutrients per item, supports barcode scanning, text search, and autocomplete, and serves data for branded products from 47 countries. It is the same data that powers the Nutrola app used by over 2 million people daily.

For developers: the API is RESTful, returns JSON, and offers a free tier with 500 requests per day — enough for prototyping and personal projects. Paid tiers scale to millions of requests. You can find the full documentation at api.nutrola.com/docs.

For researchers and institutions: we offer academic licenses with elevated rate limits and bulk export capabilities. Contact research@nutrola.com for details.

The macro reference tables and the API complement each other. Use the tables for offline work, embedded datasets, and situations where you need a self-contained file. Use the API when you need breadth, depth, real-time updates, and search functionality.

Frequently Asked Questions

How often are the macro reference tables updated?

We update the tables approximately every quarter. Each release gets a new version number (the current version is 1.4.0). Updates include corrections submitted by users, additions of commonly requested foods, and adjustments when our source databases publish revised values. The JSON file includes the version and generation date in its metadata, so you can programmatically check whether you have the latest version.

Can I use this data in my commercial application?

Yes. The macro reference tables are released under a Creative Commons Attribution 4.0 (CC BY 4.0) license. You can use, modify, and redistribute the data in both personal and commercial projects as long as you provide attribution. A link to nutrola.com or a mention of "Nutrola Macro Reference Tables" in your data credits is sufficient. You do not need to request permission or pay a fee.

Why only 500+ foods and not the full Nutrola database?

The reference tables are designed to be a practical, high-quality subset of the most commonly consumed foods. Covering 500+ items across seven categories addresses roughly 90% of what people eat on a daily basis in most countries. Expanding to 3 million entries would make the files unwieldy for many use cases (the full database exceeds 2 GB). If you need the full dataset, the Nutrola API provides access to everything.

Are the values per serving or per 100 grams?

Per serving. Every entry includes a serving description (e.g., "1 medium apple (182g)") and the corresponding gram weight, so you can easily convert to per-100g values by dividing each nutrient value by the serving weight and multiplying by 100. We chose per-serving values because they are more immediately useful for meal tracking, meal planning, and client-facing applications.

How do I convert the data to per-100g values?

Multiply each nutrient value by 100 and divide by the serving_weight_g field. For example, if a chicken breast serving of 170g contains 53.4g of protein, the per-100g protein value is (53.4 * 100) / 170 = 31.4g. Here is a quick Python function:

def per_100g(food, nutrient_field):
    """Convert a per-serving nutrient value to per-100g."""
    serving_weight = food['serving_weight_g']
    if serving_weight == 0:
        return 0
    return round(food[nutrient_field] * 100 / serving_weight, 1)

What should I do if a food I need is not in the table?

First, check if a similar food exists under a different name — use your text editor's search function or a simple script to search the food_name field. If the food genuinely is not included, you have two options: submit a request through our GitHub repository (we prioritize additions based on demand), or use Nutrola's API which covers over 3 million foods and is far more likely to have what you need. For one-off lookups, the Nutrola app itself lets you search the full database for free.

Ready to Transform Your Nutrition Tracking?

Join thousands who have transformed their health journey with Nutrola!

Free Macro Reference Tables: CSV & JSON Nutrition Data Download | Nutrola