A lightweight, modular, offline-first barcode scan-in / scan-out inventory system for mutual aid and emergency management
Project description
open-inventory
A lightweight, modular, offline-first barcode scan-in / scan-out inventory system for mutual aid, emergency management, indie providers, and other small-scale ad-hoc distribution efforts.
What It Is
A minimalist inventory program that captures USB barcode scans and records units in/out of stock. On first-ever scan of a given barcode, the system auto-fills basic product information from public open data sources (Open Food Facts, Open Library, OpenGTINdb, UPCitemdb).
What It Is NOT
- Not a WMS, TMS, ERP, or full retail POS. No slotting, picking, routing, rate shopping, or complex workflows.
- Not cloud-dependent. Works entirely offline; network is only used to enrich never-before-seen barcodes.
- Not an app store bloatware. Runs happily on a cheap laptop, an Arch desktop, a Raspberry Pi, or a docker container.
Design Pillars
- Minimalist but modular — Small, focused core with clean seams so new capabilities (reporting, multi-location transfers, donor tracking, label printing, central sync, etc.) can bolt on without touching core.
- Offline-first — Everything works without internet; network is only used to enrich never-before-seen barcodes, with a persistent local cache.
- Low operational cost — Runs happily on a cheap laptop, an Arch desktop, or a Raspberry Pi.
- Use existing OSS — Don't reinvent. Rely on mature, permissive-licensed libraries.
- Cross-platform from day one — Dev on Arch Linux; end users may run on Arch, any Linux, Raspberry Pi OS, macOS, or Windows.
Installation
Quick Start (Arch Linux)
sudo pacman -S python python-pipx git
pipx install open-inventory
inventory init
inventory run
Open your browser to http://127.0.0.1:8765/scan.
Per-platform guides
| Platform | Guide |
|---|---|
| Arch Linux | docs/QUICKSTART_ARCH.md |
| Raspberry Pi | docs/QUICKSTART_PI.md |
| macOS | docs/QUICKSTART_MACOS.md |
| Windows | docs/QUICKSTART_WINDOWS.md |
| Docker | docs/QUICKSTART_DOCKER.md |
Arch AUR (PKGBUILD): AUR packaging was a stretch goal for V1 and is deferred to a post-release task. Arch users should use the standard
uv sync/pipx installpath in the quickstart above.
Usage
Scanning Items In
- Open
http://127.0.0.1:8765/scanin your browser. - Plug in a USB barcode scanner (HID keyboard-wedge; no drivers needed).
- The input field auto-focuses. Select your mode: Each, Case, Cluster, or Custom ×N.
- Scan a barcode. The scanner "types" it as if it were a keyboard.
- The system looks it up (local cache → Open Food Facts → Open Library → OpenGTINdb → UPCitemdb).
- If found, the item name, brand, and current on-hand quantity are displayed.
- Focus returns to the input. Scan the next item.
Managing Inventory
- View inventory:
http://127.0.0.1:8765/inventory - Enrich missing items:
http://127.0.0.1:8765/items?filter=needs_review - Export CSV:
http://127.0.0.1:8765/export/items.csvand/export/movements.csv
Stack
| Component | Choice |
|---|---|
| Backend | Python 3.11+ |
| Framework | FastAPI + Uvicorn |
| Frontend | Jinja2 + HTMX + Alpine.js + Pico.css |
| Database | SQLite (WAL mode), SQLAlchemy 2.x, Alembic migrations |
| Package Manager | uv (cross-platform) |
| Code quality | ruff, mypy, pytest |
| License | AGPL-3.0 |
Contributing
See CONTRIBUTING.md for development setup, testing, and code standards.
We welcome contributions! Please:
- Fork the repo and create a feature branch from
develop. - Write tests for new functionality.
- Run
make test && make lint && make types. - Open a pull request with a clear description.
Roadmap (Milestones)
- M1: Skeleton (core FastAPI setup, database, basic CLI) ✓
- M2: Scan Loop (POST /scan endpoint, HTMX UI, HID scanner integration) ✓
- M3: Lookup Chain (product data providers, caching, manual enrichment) ✓
- M4: Casepacks, Inventory Views, CSV Export ✓
- M5: Packaging & Cross-Platform Docs (pipx, systemd, macOS, Windows, Docker) ✓
Out of Scope for V1 (explicitly deferred to V2+):
- Lot/expiry/FEFO tracking
- Camera/mobile scanning
- Multi-location transfer workflows
- Authentication & user roles
- External webhooks/integrations
- Label/receipt printing
- Reporting dashboards
Running Tests
make test # Run pytest
make lint # Run ruff linter
make types # Run mypy type checker
Development
# Install dev dependencies
uv sync
# Run dev server with hot reload
make run
# Or manually:
uv run inventory run --reload
Visit http://127.0.0.1:8765/health to check the server is running.
Architecture
For a deep dive into the module structure, data model, and provider chain, see DEVELOPMENT_PLAN.md.
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for details.
Support
- Bug reports & feature requests: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ for mutual aid and emergency management.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file open_inventory-0.1.0.tar.gz.
File metadata
- Download URL: open_inventory-0.1.0.tar.gz
- Upload date:
- Size: 241.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48d462a9d0364d848fed3e660c2dbb9aa983690ba2788e24e47cc65ee1c77e5d
|
|
| MD5 |
76198a1604b0c9a2f028e870a18a476e
|
|
| BLAKE2b-256 |
dce194824b0342143d283174b3e308333d144b8a101ff5e9839803ff1a013fb9
|
Provenance
The following attestation bundles were made for open_inventory-0.1.0.tar.gz:
Publisher:
release.yml on manofthedown/open-inventory
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
open_inventory-0.1.0.tar.gz -
Subject digest:
48d462a9d0364d848fed3e660c2dbb9aa983690ba2788e24e47cc65ee1c77e5d - Sigstore transparency entry: 1361147981
- Sigstore integration time:
-
Permalink:
manofthedown/open-inventory@d681d79cc3b59d3344113c43a8c667e820878908 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/manofthedown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d681d79cc3b59d3344113c43a8c667e820878908 -
Trigger Event:
push
-
Statement type:
File details
Details for the file open_inventory-0.1.0-py3-none-any.whl.
File metadata
- Download URL: open_inventory-0.1.0-py3-none-any.whl
- Upload date:
- Size: 110.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ca8a746936982c2e80ddb5bcb6d0519af3781ddb1105d2d6f7a9a704e90989f
|
|
| MD5 |
25edc9b703abc0d5f9ceb132c0a53d1f
|
|
| BLAKE2b-256 |
ac1c39f53d1183c540234b5f5ce1e1dd003ebeef0881628c2d8a41bf38aa21c1
|
Provenance
The following attestation bundles were made for open_inventory-0.1.0-py3-none-any.whl:
Publisher:
release.yml on manofthedown/open-inventory
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
open_inventory-0.1.0-py3-none-any.whl -
Subject digest:
1ca8a746936982c2e80ddb5bcb6d0519af3781ddb1105d2d6f7a9a704e90989f - Sigstore transparency entry: 1361147986
- Sigstore integration time:
-
Permalink:
manofthedown/open-inventory@d681d79cc3b59d3344113c43a8c667e820878908 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/manofthedown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d681d79cc3b59d3344113c43a8c667e820878908 -
Trigger Event:
push
-
Statement type: