Owen 4ceb1cbc03 Replace on-screen action buttons with right-click context menus
The tree and main panels now behave like a native file manager: right
click (or the keyboard Menu key) on a folder, asset, breadcrumb crumb, or
empty tree/panel background brings up the relevant actions instead of a
row of always-visible buttons.

- New generic showContextMenu() in app.js with per-target-kind menu
  builders (folder/asset/tree background/panel background), gated by
  admin role the same way the old buttons were.
- Removed: the "..." tree-row action button, and the New Folder/Add
  Asset/Rename/Delete/Edit/Move/Duplicate/Import/Export buttons from the
  inventory toolbar and every panel. Expand All/Collapse All shrank to two
  icon-only buttons next to the search box; everything else creation- or
  mutation-related is right-click only.
- Replaced the per-asset embedded "Move" modal with one shared
  #moveAssetModal populated via a new GET /app/folders/options endpoint,
  since move can now be triggered from any asset row, not just its own
  detail view.
- Breadcrumb crumbs (including the current folder) and folder/asset table
  rows are now valid right-click targets too, not just tree rows.
2026-08-17 15:24:32 -05:00
2026-08-17 13:34:40 -05:00
2026-08-17 13:34:40 -05:00
2026-08-17 13:34:40 -05:00
2026-08-17 13:34:40 -05:00
2026-08-17 13:34:40 -05:00

inventree

A small, self-contained IT asset inventory system. The heart of inventree is a nested folder tree — like a file manager — for organizing physical and virtual IT assets (servers, switches, laptops, printers, etc.).

  • Single compiled Go binary, embedded HTML templates and static assets
  • SQLite storage (WAL mode, foreign keys, migrations)
  • Bootstrap 5 UI, minimal vanilla JavaScript (no Node/React/build step)
  • Session-based auth with two roles: Admin and User
  • Custom, admin-defined asset types with custom fields
  • CSV import/export, full-text-ish search with breadcrumbs

Quick start

go build -o inventree ./cmd/inventree
./inventree serve

Then open http://localhost:8080 and log in with:

Username: admin
Password: admin

(This default account is created intentionally on first run. Change or disable it via the Users admin page once you're up and running.)

The database file is created automatically at data/inventree.db on first run, with migrations applied and seed data (default statuses, item types, and the admin account) inserted.

CLI

inventree                    # same as `inventree serve`
inventree serve              # start the web server
inventree version            # print the version
inventree database migrate   # apply pending migrations and exit
inventree database backup [path]  # write a consistent VACUUM INTO snapshot

serve flags:

Flag Default Description
-addr :8080 Listen address
-db data/inventree.db Path to the SQLite database file
-secure-cookies false Mark the session cookie Secure (enable when serving over HTTPS)

/healthz is available for load balancer / container health checks.

The inventory tree

The Inventory page is the default page after login and the center of the application: a folder/asset tree on the left, and a detail panel on the right that shows whatever is selected (a folder's contents, or a single asset).

  • Folders can nest arbitrarily deep, and contain both subfolders and assets.
  • Expand/collapse state is remembered per user (persisted server-side), and folder contents are fetched lazily via small AJAX requests — the page never fully reloads when you browse the tree.
  • Drag and drop folders and assets onto another folder (or onto "Inventory" itself) to move them. Admin only.
  • Right-click-style actions: each folder has a "…" action menu (New Subfolder, Add Asset, Rename, Delete).
  • Deleting a folder that still contains subfolders or assets requires confirmation, and offers a safe "move contents elsewhere" option instead of an accidental cascade. A "permanently delete everything inside" option is also available for when that's genuinely what you want.
  • Search (top of the tree pane) looks across asset ID, name, folder name, item type, assigned user, notes, and custom field values, and shows each result's full folder breadcrumb.

Item types and custom fields

Admins can define arbitrary asset types (Laptop, Switch, Firewall, …) under Item Types, each with its own set of custom fields (text, long text, number, date, boolean, dropdown, URL, IP address), marked required or not, with a default value and display order. A representative starter set of types and fields is seeded on first run — feel free to edit or delete it.

CSV import / export

  • Export: from the Inventory toolbar, or /export/assets.csv (optionally scoped to a folder, with ?recursive=1 to include subfolders). Includes one cf_<field_key> column per distinct custom field in use.
  • Import: CSV with columns Asset ID (optional — auto-generated if blank), Name, Item Type, Folder (a /-separated path, e.g. Main Office/Network), Status, Assigned User, Notes, plus cf_<field_key> columns for custom fields. Existing assets are matched and updated by Asset ID; everything else is created. Missing folders in the path can optionally be created automatically.

A full backup/restore of everything (folders, assets, types, custom fields, statuses) is just inventree database backup — it's a consistent snapshot of the whole SQLite database.

Project layout

cmd/inventree/        CLI entrypoint (serve, version, database migrate/backup)
internal/
  auth/                session management, secure cookies
  database/            SQLite connection, pragmas, migrations
  migrations/           embedded .sql migration files
  models/               shared domain types
  folders/               nested folder tree
  assets/                 asset CRUD, search, CSV import/export
  itemtypes/              admin-defined types + custom field definitions
  users/                  accounts
  statuses/               configurable asset statuses
  settings/               key/value app settings
  web/                    HTTP router, handlers, template rendering
web/
  templates/              Go html/template pages and partials (embedded)
  static/                 Bootstrap 5, Bootstrap Icons, app.css, app.js (embedded)
deploy/                  systemd unit example

Development

go build ./...
go vet ./...
go test ./...

The SQLite driver is modernc.org/sqlite, a pure-Go implementation, so CGO_ENABLED=0 builds work out of the box and the compiled binary has no C library dependencies.

Docker

docker compose up --build

This builds the image, starts inventree on port 8080, and persists the database in a named volume (inventree-data, mounted at /app/data).

Or directly:

docker build -t inventree .
docker run -p 8080:8080 -v inventree-data:/app/data inventree

systemd

See deploy/inventree.service for an example unit. Adjust the paths, then:

sudo useradd --system --home /opt/inventree --shell /usr/sbin/nologin inventree
sudo mkdir -p /opt/inventree/data
sudo cp inventree /opt/inventree/inventree
sudo chown -R inventree:inventree /opt/inventree
sudo cp deploy/inventree.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now inventree

Scope

inventree is intentionally a focused MVP: folders, assets, custom types, statuses, users, search, and CSV import/export. It does not include ticketing, purchasing, monitoring, RMM, MDM, or accounting features — if you need those, look elsewhere and integrate via CSV.

S
Description
A vibe-coded inventory system designed to solve my issues with existing tools.
Readme
546 KiB
Languages
Go 60.3%
HTML 20.1%
JavaScript 17.8%
CSS 1.5%
Dockerfile 0.3%