homelabby/.planning/research/STACK.md

11 KiB

Stack Research

Domain: Self-hosted AI-powered hardware inventory system (Go + React) Researched: 2026-04-09 Confidence: MEDIUM-HIGH (core stack confirmed via search; some library versions from training data)


Core Technologies

Technology Version Purpose Why Recommended
Go 1.22+ Backend API, USB/serial control, AI orchestration Native concurrency for USB polling + HTTP serving; single binary deployment; no runtime dependency; best-in-class serial I/O on macOS
React 18.x SPA frontend Mature ecosystem, hooks-based state management, excellent TypeScript support; right level of complexity for a single-operator tool
TypeScript 5.x Frontend type safety Catches API contract drift early; NetBox has complex nested types that benefit from strict typing
Tailwind CSS 3.x Utility-first styling ClickHouse-inspired design system maps well to utility classes; no CSS file sprawl; dark theme with arbitrary values is trivial
SQLite (via mattn/go-sqlite3) 3.x / v1.14+ Local-only storage (chat history, config, session state) Zero-dependency embedded DB; perfectly suited for single-operator append-heavy chat logs; no separate process
oMLX latest Local LLM inference server on Mac Mini M4 Native Apple Silicon MLX backend, OpenAI-compatible API endpoint, paged SSD KV caching, continuous batching; supports Gemma 4 VLM natively; drop-in for any OpenAI-SDK client

Go Backend Libraries

Library Version Purpose When to Use
github.com/netbox-community/go-netbox/v4 v4.x NetBox REST API client All CRUD against NetBox — officially maintained, generated from NetBox OpenAPI spec
go.bug.st/serial v1.x USB serial communication Printer + cable tester I/O; actively maintained, cross-platform, better API than tarm/serial; supports port enumeration
github.com/gin-gonic/gin v1.9+ HTTP router and middleware Fast, well-documented, large middleware ecosystem; handles file uploads for photo intake cleanly
github.com/mattn/go-sqlite3 v1.14+ SQLite driver (cgo) Standard Go SQLite driver; use with database/sql for portability
github.com/jmoiern/sqlx v1.3+ database/sql extension Named params and struct scanning reduce boilerplate for chat history queries
github.com/sashabaranov/go-openai v1.x OpenAI-compatible client Handles both oMLX local endpoint and OpenRouter remote; single client, swap base URL per tier
github.com/skip2/go-qrcode v0.0.0 QR code generation Generate HW-XXXXX QR codes server-side before sending to printer
github.com/google/uuid v1.x UUID generation HW-XXXXX ID assignment; deterministic or random depending on design choice
github.com/spf13/viper v1.x Config management YAML/env config for AI endpoints, NetBox URL/token, USB port paths

Frontend Libraries

Library Version Purpose When to Use
Vite 5.x Build tool and dev server Fastest HMR in class; Go backend runs separately, Vite proxies API calls in dev
TanStack Query (React Query) v5 Server state management NetBox data is server state not client state; handles caching, refetch, stale-while-revalidate
TanStack Router v1 Type-safe routing Better TypeScript integration than React Router v6 for complex nested routes
Zustand v4 Client state (UI state, chat) Lightweight, no boilerplate, perfect for chat message buffer and USB device status
shadcn/ui latest Component primitives Radix UI + Tailwind, fully owned code (not a dependency), dark mode first, ClickHouse aesthetic compatible
react-dropzone v14 Photo drag-and-drop Standard library for file upload UX; works with multipart form to Go backend
react-hot-toast v2 Toast notifications Inventory actions (label printed, test passed) need lightweight non-blocking feedback
lucide-react latest Icon set Consistent, tree-shakeable, TypeScript-native, pairs well with shadcn/ui

Development Tools

Tool Purpose Notes
Air (cosmtrek/air) Go hot reload in development Watch + rebuild backend on save; configure alongside Vite proxy
golangci-lint Go linting Run in CI; catches serial/concurrent code issues early
ESLint + typescript-eslint Frontend linting Strict TypeScript rules; catch NetBox API type drift
Prettier Frontend formatting Single config, no debates
Bruno (or httpie) API testing Test NetBox integration and Go endpoints locally without Postman account

Installation

# Go backend — initialize module
go mod init git.georgsen.dk/hwlab

# Core Go dependencies
go get github.com/gin-gonic/gin@latest
go get github.com/netbox-community/go-netbox/v4@latest
go get go.bug.st/serial@latest
go get github.com/mattn/go-sqlite3@latest
go get github.com/jmoiern/sqlx@latest
go get github.com/sashabaranov/go-openai@latest
go get github.com/skip2/go-qrcode@latest
go get github.com/google/uuid@latest
go get github.com/spf13/viper@latest

# Frontend — scaffold
npm create vite@latest frontend -- --template react-ts
cd frontend

# Frontend core dependencies
npm install @tanstack/react-query @tanstack/react-router zustand
npm install react-dropzone react-hot-toast lucide-react
npm install class-variance-authority clsx tailwind-merge  # shadcn/ui deps

# shadcn/ui init (run in frontend dir)
npx shadcn@latest init

# Dev dependencies
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint prettier tailwindcss autoprefixer postcss

Alternatives Considered

Recommended Alternative When to Use Alternative
go.bug.st/serial tarm/serial tarm/serial is adequate if you only need basic read/write and already have it; go.bug.st/serial is preferred for new projects due to active maintenance and port listing
gin-gonic/gin chi, echo, fiber chi if you want stdlib-compatible handlers; echo for similar feature set; fiber if you need extreme HTTP throughput (not relevant here)
go-openai (sashabaranov) Custom HTTP client Custom client only if you need streaming SSE to browser — go-openai supports streaming too, prefer it
TanStack Router React Router v6 React Router v6 is fine if team is already familiar; TanStack Router has stronger TypeScript guarantees for route params
TanStack Query SWR SWR is lighter but TanStack Query has better devtools and mutation handling for NetBox writes
mattn/go-sqlite3 (cgo) modernc.org/sqlite (pure Go) Use modernc.org/sqlite if you want zero cgo dependency (simpler cross-compilation); slightly slower but avoids gcc requirement
oMLX Ollama Ollama works but oMLX has better Apple Silicon performance via MLX backend; Gemma 4 VLM continuous batching support is oMLX-specific

What NOT to Use

Avoid Why Use Instead
GORM Heavy ORM abstraction for what is essentially two tables (chat logs, config); migrations and reflection overhead not worth it for SQLite local-only store database/sql + sqlx directly
tarm/serial Last commit 2018, unmaintained, no port enumeration, open issues unaddressed go.bug.st/serial
Redux (React) Massive boilerplate for a solo-operator SPA; overkill when TanStack Query handles server state Zustand + TanStack Query
axios Unnecessary HTTP client abstraction; TanStack Query works with native fetch; one fewer dependency fetch API directly inside TanStack Query
Next.js SSR/SSG overhead not needed — Go handles the API, React is a pure SPA served as static files Vite + React SPA
llama.cpp Go bindings Not optimized for Apple Silicon; MLX backend (oMLX) is 2-4x faster on M-series; cgo binding complexity oMLX via OpenAI-compatible HTTP
Direct NetBox HTTP calls (no client) NetBox v4 API has 200+ endpoints; go-netbox generates typed structs from OpenAPI spec — manual HTTP is brittle go-netbox/v4

Stack Patterns by Variant

For the AI tier routing (local vs remote):

  • Use a single go-openai client instance per tier, configured with BaseURL pointing to oMLX (http://localhost:PORT/v1) for Tier 1, and https://openrouter.ai/api/v1 for Tier 2/3
  • Switch by returning the appropriate client from a factory based on model config
  • Do NOT hardcode tier selection in business logic — make it config-driven from the start

For USB serial (printer + testers):

  • Use go.bug.st/serial with a dedicated goroutine per device, communicating via channels
  • Do not share a serial.Port across goroutines — open one port per device, serialize writes in the owning goroutine
  • USB device paths on macOS follow /dev/cu.usbserial-* or /dev/cu.usbmodem*; use serial.GetPortsList() to enumerate at startup

For photo intake (multipart upload):

  • Accept multipart/form-data in Gin; decode image in Go; send as base64 in the OpenAI vision API call to oMLX
  • Store the original photo in a local temp directory only until the NetBox record is created; do not persist photos in HWLab itself
  • Gemma 4 E4B fits comfortably in 16GB; Gemma 4 26B A4B needs TurboQuant KV offload — benchmark before committing to 26B

For NetBox custom fields:

  • go-netbox v4 represents custom fields as map[string]interface{}; define typed wrapper structs in your own code to handle hw_id, condition, quality_gate etc.
  • Custom fields must be created in NetBox admin before the Go code can write them — treat this as infrastructure provisioning (Phase 1 task)

Version Compatibility

Package Compatible With Notes
go-netbox/v4 NetBox 4.x Generated from NetBox 4.x OpenAPI; not compatible with NetBox 3.x API responses
mattn/go-sqlite3 v1.14+ Go 1.21+ Requires cgo; needs gcc or Xcode CLT on macOS
shadcn/ui React 18, Tailwind 3.x shadcn v2+ requires Tailwind 3.x; not yet tested with Tailwind 4 alpha
oMLX macOS 15+, Apple Silicon M1+ Won't run on Intel Mac or Linux
go-openai v1.x OpenAI API v1, OpenRouter, oMLX Any OpenAI-compatible endpoint works; set BaseURL in ClientConfig

Sources

  • github.com/jundot/omlx — oMLX feature set, Gemma 4 VLM support confirmed (HIGH confidence)
  • github.com/netbox-community/go-netbox — Official Go client, v4 confirmed (HIGH confidence)
  • go.bug.st/serial pkg.go.dev — Active maintenance confirmed, preferred over tarm/serial (HIGH confidence)
  • omlx.ai — macOS 15+ requirement, 16GB minimum RAM, MLX backend (HIGH confidence)
  • WebSearch: tarm/serial maintenance status — last substantive commit 2018, multiple forks active (MEDIUM confidence)
  • Training data: gin, TanStack Query, Zustand, Vite, shadcn/ui versions — standard 2025 React/Go stack (MEDIUM confidence, verify pinned versions before first install)

Stack research for: HWLab — self-hosted AI hardware inventory (Go + React + oMLX + NetBox) Researched: 2026-04-09