# openfoodfacts/openfoodfacts-server architecture

> Architecture diagram of the GitHub repository openfoodfacts/openfoodfacts-server, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/openfoodfacts/openfoodfacts-server
- Repository: https://github.com/openfoodfacts/openfoodfacts-server
- Video tour (about a minute): https://gitdiagram.com/openfoodfacts/openfoodfacts-server/video

## Overview

Product Opener is the web server for Open Food Facts and Open Beauty Facts, supporting an open product database and contribution through barcode scanning and product information. The available tree and excerpts emphasize browser features and data-import utilities rather than the server’s main request handlers or persistence layer, so the graph shows only supported interactions and keeps separate utilities distinct where their runtime wiring is not shown.

Main entry points: [`html/js/search.js`](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/search.js) (Search controls), [`html/js/barcode-scanner.js`](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner.js) (Barcode scanning), [`html/js/barcode-scanner-button.js`](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner-button.js) (Scanner button), [`templates/web/pages/import_product_categories_process/import_product_categories_from_public_database_process.tt.js`](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_product_categories_process/import_product_categories_from_public_database_process.tt.js) (Category import)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_product_ui["Product experience"]
  node_product_display["Product display<br/>[display.js]"]
  node_product_search["Search ranking<br/>[product-search.js]"]
  node_search_controls["Search controls<br/>[search.js]"]
  node_product_history["Product history<br/>[product-history.js]"]
  node_product_preferences["Product preferences"]
  node_map_display["Map display<br/>[display-map.js]"]
  node_tag_display["Tag views"]
  node_folksonomy_search["Folksonomy search<br/>[search.js]"]
end

subgraph group_contribution["Contribution flows"]
  node_barcode_scan["Barcode scanning<br/>[barcode-scanner.js]"]
  node_scan_button["Scanner button"]
  node_image_editor["Image editor<br/>[image-editor.js]"]
  node_file_upload["File upload"]
  node_format_selection["Format selection"]
  node_category_import["Category import"]
  node_import_job["Import job status"]
end

subgraph group_data_tools["Data preparation"]
  node_folksonomy_upload["Tag uploader"]
  node_fdc_import["Food data import<br/>[main.py]"]
  node_taxonomy_generation["Taxonomy generation<br/>[00_run_all.py]"]
  node_packager_refresh["Packager refresh<br/>[main.py]"]
end

subgraph group_integrations["External services"]
  node_folksonomy_service{{"Folksonomy Engine"}}
  node_public_sources{{"Public data sources"}}
end

node_contributors(("Contributors"))
node_product_data[("Product database")]

node_contributors -->|"scan barcode"| node_barcode_scan
node_scan_button -->|"starts scan"| node_barcode_scan
node_contributors -->|"edit images"| node_image_editor
node_contributors -->|"upload file"| node_file_upload
node_contributors -->|"map columns"| node_format_selection
node_category_import -->|"polls status"| node_import_job
node_contributors -->|"view matches"| node_product_search
node_contributors -->|"set criteria"| node_search_controls
node_search_controls -.->|"fetch keys"| node_folksonomy_service
node_contributors -->|"view product"| node_product_display
node_contributors -->|"view history"| node_product_history
node_contributors -->|"set preferences"| node_product_preferences
node_contributors -->|"view map"| node_map_display
node_contributors -->|"browse tags"| node_tag_display
node_folksonomy_upload -.->|"uploads tags"| node_folksonomy_service
node_public_sources -.->|"provides data"| node_fdc_import
node_public_sources -.->|"provides mappings"| node_taxonomy_generation
node_public_sources -.->|"provides records"| node_packager_refresh

click node_product_display "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display.js"
click node_product_search "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-search.js"
click node_search_controls "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/search.js"
click node_product_history "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-history.js"
click node_product_preferences "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-preferences.js"
click node_map_display "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display-map.js"
click node_tag_display "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display-list-of-tags.js"
click node_barcode_scan "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner.js"
click node_scan_button "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner-button.js"
click node_image_editor "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/image-editor.js"
click node_file_upload "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_file_upload/import_file_upload.tt.js"
click node_format_selection "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_file_select_format/import_file_select_format.tt.js"
click node_category_import "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_product_categories_process/import_product_categories_from_public_database_process.tt.js"
click node_folksonomy_search "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/search.js"
click node_folksonomy_upload "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/imports/folksonomy_engine/csv2folksonomyEngineTags.js"
click node_fdc_import "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/imports/fdc/main.py"
click node_taxonomy_generation "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/taxonomies/generators/00_run_all.py"
click node_packager_refresh "https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/packager-codes/main.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_product_display,node_product_search,node_search_controls,node_product_history,node_product_preferences,node_map_display,node_tag_display,node_folksonomy_search toneBlue
class node_barcode_scan,node_scan_button,node_image_editor,node_file_upload,node_format_selection,node_category_import,node_import_job,node_product_data toneAmber
class node_folksonomy_upload,node_fdc_import,node_taxonomy_generation,node_packager_refresh toneMint
class node_folksonomy_service,node_public_sources toneRose
class node_contributors toneIndigo
```

## Components

### Product experience

- [Product display](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display.js): `html/js/display.js`
- [Search ranking](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-search.js): `html/js/product-search.js`
- [Search controls](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/search.js): `html/js/search.js`
- [Product history](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-history.js): `html/js/product-history.js`
- [Product preferences](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-preferences.js): `html/js/product-preferences.js`
- [Map display](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display-map.js): `html/js/display-map.js`
- [Tag views](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/display-list-of-tags.js): `html/js/display-list-of-tags.js`
- [Folksonomy search](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/search.js): `html/js/search.js`

### Contribution flows

- [Barcode scanning](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner.js): `html/js/barcode-scanner.js`
- [Scanner button](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/barcode-scanner-button.js): `html/js/barcode-scanner-button.js`
- [Image editor](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/image-editor.js): `html/js/image-editor.js`
- [File upload](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_file_upload/import_file_upload.tt.js): `templates/web/pages/import_file_upload/import_file_upload.tt.js`
- [Format selection](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_file_select_format/import_file_select_format.tt.js): `templates/web/pages/import_file_select_format/import_file_select_format.tt.js`
- [Category import](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/templates/web/pages/import_product_categories_process/import_product_categories_from_public_database_process.tt.js): `templates/web/pages/import_product_categories_process/import_product_categories_from_public_database_process.tt.js`
- **Import job status**

### Data preparation

- [Tag uploader](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/imports/folksonomy_engine/csv2folksonomyEngineTags.js): `scripts/imports/folksonomy_engine/csv2folksonomyEngineTags.js`
- [Food data import](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/imports/fdc/main.py): `scripts/imports/fdc/main.py`
- [Taxonomy generation](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/taxonomies/generators/00_run_all.py): `scripts/taxonomies/generators/00_run_all.py`
- [Packager refresh](https://github.com/openfoodfacts/openfoodfacts-server/blob/main/scripts/packager-codes/main.py): `scripts/packager-codes/main.py`

### External services

- **Folksonomy Engine**
- **Public data sources**

### Other components

- **Contributors**
- **Product database**

## Connections

- Contributors → Barcode scanning: scan barcode
- Scanner button → Barcode scanning: starts scan
- Contributors → Image editor: edit images
- Contributors → File upload: upload file
- Contributors → Format selection: map columns
- Category import → Import job status: polls status
- Contributors → Search ranking: view matches
- Contributors → Search controls: set criteria
- Search controls → Folksonomy Engine: fetch keys
- Contributors → Product display: view product
- Contributors → Product history: view history
- Contributors → Product preferences: set preferences
- Contributors → Map display: view map
- Contributors → Tag views: browse tags
- Tag uploader → Folksonomy Engine: uploads tags
- Public data sources → Food data import: provides data
- Public data sources → Taxonomy generation: provides mappings
- Public data sources → Packager refresh: provides records
