Skip to content

akifbayram/openbin

Repository files navigation

 OpenBin

Self-hosted inventory system for organizing physical storage bins with optional AI-powered cataloging. Snap photos and AI names the bins, lists every item, and tags them for search. Tell it to "add batteries to the tools bin" or "move everything to the garage" and review changes before applying. Reorganize entire locations with AI suggestions. Print QR labels and scan to find contents.

Demo · Docs · Discord

Highlights

  • AI-powered cataloging — Point your phone at a bin and AI fills in the name, items with quantities, and tags. Bring your own API key.
  • Natural language commands — "Add batteries to the tools bin" or "move everything to the garage"
  • AI reorganization — Let AI suggest how to restructure an entire location's bins, areas, and tags, then apply changes in bulk
  • Print & scan QR labels — Generate customizable label sheets, stick them on bins, scan with your phone to see contents
  • Multi-user locations — Invite others with a code, assign roles (admin/member/viewer), split bins into areas, track changes in the activity log
  • MCP server included — Connect Claude and other AI assistants directly to your inventory via Model Context Protocol
  • Export everything — Full JSON/CSV/ZIP export with photos, import from backup anytime

Quick Start

Prerequisites: Docker

Create a docker-compose.yml:

services:
  openbin:
    image: ghcr.io/akifbayram/openbin:latest
    ports:
      - "1453:1453"
    volumes:
      - api_data:/data
    environment:
      DATABASE_PATH: /data/openbin.db
      PHOTO_STORAGE_PATH: /data/photos
      BACKUP_PATH: /data/backups

volumes:
  api_data:
docker compose up -d

Open http://localhost:1453. Register an account, create a location, and start adding bins.

Configuration

All settings are optional. Set environment variables or create a .env file to override defaults. See .env.example for the full list.

Environment variables
Variable Description Default
Server
PORT Express server port 1453
HOST_PORT Docker external port 1453
DATABASE_PATH SQLite database file path ./data/openbin.db
PHOTO_STORAGE_PATH Photo upload directory ./data/photos
TRUST_PROXY Set true when behind a reverse proxy false
Authentication
JWT_SECRET JWT signing secret; auto-generated and persisted if unset
ACCESS_TOKEN_EXPIRES_IN Short-lived access token lifetime 15m
REFRESH_TOKEN_MAX_DAYS Refresh token lifetime in days (1–90) 7
BCRYPT_ROUNDS Password hashing rounds (10–31) 12
REGISTRATION_MODE Registration policy: open, invite (require location invite code), or closed open
Uploads
MAX_PHOTO_SIZE_MB Max photo upload size in MB 5
MAX_AVATAR_SIZE_MB Max avatar upload size in MB 2
AI (server-wide fallback)
AI_PROVIDER openai, anthropic, gemini, or openai-compatible
AI_API_KEY API key for the configured provider
AI_MODEL Model name (e.g. gpt-4o-mini, claude-sonnet-4-6)
AI_ENDPOINT_URL Custom endpoint for openai-compatible provider
AI_ENCRYPTION_KEY Encrypts user AI API keys at rest (AES-256-GCM)
Backups
BACKUP_ENABLED Enable automatic database backups false
BACKUP_INTERVAL Backup schedule (hourly/daily/weekly/cron) daily
BACKUP_RETENTION Number of backup files to keep 7
BACKUP_WEBHOOK_URL Webhook URL for backup notifications
Rate Limiting
AI_RATE_LIMIT Max AI requests per hour per user 30
AI_RATE_LIMIT_API_KEY Max AI requests per hour per API key 1000
DISABLE_RATE_LIMIT Set true to disable all rate limiters (dev only) false
Demo
DEMO_MODE Auto-login visitors with pre-populated sample data; resets on restart false

Updating

docker compose pull
docker compose up -d

The database schema is auto-migrated on startup. Your data volume is preserved across updates.

Architecture

Single Node.js process. All data lives in one SQLite file and a photos directory. No external services, no background workers, no telemetry, no phoning home. The app never makes outbound network requests unless you explicitly configure AI features (bring-your-own API key). Works fully offline on a LAN.

┌──────────────────────────────────────┐
│          Node.js (Express)           │
│                                      │
│   GET /api/*   ←→  SQLite (WAL)     │
│   GET /*       →   Static frontend  │
└──────────┬───────────────────────────┘
           │
     /data (Docker volume)
     ├── openbin.db        ← single database file
     ├── .jwt_secret       ← auto-generated if JWT_SECRET unset
     ├── photos/           ← uploaded images
     └── backups/          ← scheduled DB snapshots (opt-in)
Layer Technology
Frontend React 18, TypeScript, Vite 5, Tailwind CSS 4
Backend Express 4, SQLite (better-sqlite3), JWT auth
Container Single-stage Alpine image, runs as non-root node user

What writes to disk: The SQLite database (openbin.db + WAL journal), uploaded photos, optional backups, and a .jwt_secret file if you don't provide JWT_SECRET. Nothing else.

Network access: Zero outbound connections by default. If you configure an AI provider, the server calls that provider's API on demand. No other external calls, ever.

API Documentation

OpenAPI spec at server/openapi.yaml. See the full API reference in the docs.

Local Development

Prerequisites: Node.js 20+

npm install                 # Install frontend dependencies
cd server && npm install    # Install server dependencies
npm run dev:all            # Both servers concurrently (recommended)
# Or separately in two terminals:
# cd server && npm run dev   API server at http://localhost:1453
# npm run dev                Frontend dev server at http://localhost:5173

AI Disclosure

Most of this codebase—features, tests, documentation—was written by AI (Claude Code). A human directs architecture, priorities, and design decisions but has not reviewed most code line-by-line. Type checking, linting, and an automated test suite are the primary quality gates.

The full source is available for you to audit. If you find a bug or security issue, please open an issue.

License

AGPL-3.0

About

Self-hosted inventory system for organizing physical storage bins. Print labels, scan to find contents, and optionally plug in your own AI to do the heavy lifting: snap a photo and it names the bin, lists every item, and tags it for search.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages