Files
GearBox/.planning/research/STACK.md

12 KiB

Stack Research

Domain: Single-user gear management and purchase planning web app Researched: 2026-03-14 Confidence: HIGH

Core Technologies

Technology Version Purpose Why Recommended
Bun 1.3.x Runtime, package manager, bundler User constraint. Built-in SQLite, fast installs, native TS support. Eliminates need for separate runtime/bundler/pkg manager.
React 19.2.x UI framework Industry standard, massive ecosystem, stable. Server Components not needed for this SPA -- stick with client-side React.
Vite 8.0.x Dev server, production builds Rolldown-based builds (5-30x faster than Vite 7). Zero-config React support. Bun-compatible. HMR out of the box.
Hono 4.12.x Backend API framework Built on Web Standards, first-class Bun support, zero dependencies, tiny (~12kB). Perfect for a lightweight REST API. Faster than Express on Bun benchmarks.
SQLite (bun:sqlite) Built-in Database Zero-dependency, built into Bun runtime. 3-6x faster than better-sqlite3. Single file database -- perfect for single-user app. No server process to manage.
Drizzle ORM 0.45.x Database ORM, migrations Type-safe SQL, ~7.4kB, zero dependencies. Native bun:sqlite driver support. SQL-like query API (not abstracting SQL away). Built-in migration tooling via drizzle-kit.
Tailwind CSS 4.2.x Styling CSS-native configuration (no JS config file). Auto content detection. Microsecond incremental builds. Perfect for "light, airy, minimalist" design constraint.
TanStack Router 1.167.x Client-side routing Full type-safe routing with typed params and search params. File-based route generation. Better SPA experience than React Router v7 (whose best features require framework mode).
TanStack Query 5.93.x Server state management Handles API data fetching, caching, and synchronization. Eliminates manual loading/error state management. Automatic cache invalidation on mutations.
Zustand 5.0.x Client state management Minimal boilerplate, ~1kB. For UI state like active filters, modal state, theme. TanStack Query handles server state; Zustand handles the rest.
Zod 4.3.x Schema validation Validates API inputs on the server, form data on the client, and shares types between both. Single source of truth for data shapes.
TypeScript 5.x (Bun built-in) Type safety Bun transpiles TS natively -- no tsc needed at runtime. Catches bugs at dev time. Required by Drizzle and TanStack Router for type-safe queries and routes.

Supporting Libraries

Library Version Purpose When to Use
@tanstack/react-query-devtools 5.x Query debugging Development only. Inspect cache state, refetch timing, query status.
drizzle-kit latest DB migrations CLI Run drizzle-kit generate and drizzle-kit migrate for schema changes.
@hono/zod-validator latest Request validation middleware Validate API request bodies/params using Zod schemas in Hono routes.
clsx 2.x Conditional class names When building components with variant styles. Pairs with Tailwind.
@tanstack/react-router-devtools latest Router debugging Development only. Inspect route matches, params, search params.

Development Tools

Tool Purpose Notes
Bun Test runner bun test -- built-in, Jest-compatible API. No need for Vitest or Jest.
Biome Linter + formatter Single tool replacing ESLint + Prettier. Fast (Rust-based), minimal config. biome check --write does both.
Vite React plugin React HMR/JSX @vitejs/plugin-react for Fast Refresh during development.

Installation

# Initialize project
bun init

# Core frontend
bun add react react-dom @tanstack/react-router @tanstack/react-query zustand zod clsx

# Core backend
bun add hono @hono/zod-validator drizzle-orm

# Styling
bun add tailwindcss @tailwindcss/vite

# Build tooling
bun add -d vite @vitejs/plugin-react typescript @types/react @types/react-dom

# Database tooling
bun add -d drizzle-kit

# Linting + formatting
bun add -d @biomejs/biome

# Dev tools (optional but recommended)
bun add -d @tanstack/react-query-devtools @tanstack/react-router-devtools

Architecture Pattern

Monorepo-lite (single package, split directories):

/src
  /client          -- React SPA (Vite entry point)
    /routes         -- TanStack Router file-based routes
    /components     -- Shared UI components
    /stores         -- Zustand stores
    /api            -- TanStack Query hooks (fetch wrappers)
  /server          -- Hono API server
    /routes         -- API route handlers
    /db             -- Drizzle schema, migrations
  /shared          -- Zod schemas shared between client and server
/public            -- Static assets, uploaded images

Bun runs the Hono server, which also serves the Vite-built SPA in production. In development, Vite dev server proxies API calls to the Hono backend.

Alternatives Considered

Recommended Alternative When to Use Alternative
Hono Elysia If you want end-to-end type safety with Eden Treaty. Elysia is Bun-native but heavier, more opinionated, and has a smaller ecosystem than Hono.
Hono Express Never for new Bun projects. Express is Node-centric, not built on Web Standards, slower on Bun.
TanStack Router React Router v7 If you want the simplest possible routing with minimal type safety. React Router v7's best features (loaders, type safety) require framework mode which adds complexity.
Drizzle ORM Prisma If you have a complex relational model and want auto-generated migrations. But Prisma is heavy (~8MB), generates a query engine binary, and has weaker SQLite support.
Drizzle ORM Kysely If you want a pure query builder without ORM features. Kysely is lighter but lacks built-in migration tooling.
Zustand Jotai If you prefer atomic state (bottom-up). Zustand is simpler for this app's needs -- a few global stores, not many independent atoms.
Tailwind CSS Vanilla CSS / CSS Modules If you strongly prefer writing plain CSS. But Tailwind accelerates building consistent minimalist UIs and requires less design system setup.
bun:sqlite PostgreSQL If you later need multi-user with concurrent writes. Overkill for single-user. Adds a database server dependency.
Biome ESLint + Prettier If you need specific ESLint plugins not yet in Biome. But Biome covers 95% of use cases with zero config.
Vite Bun's built-in bundler Bun can serve HTML directly as of 1.3, but Vite's ecosystem (plugins, HMR, proxy) is far more mature for SPA development.

What NOT to Use

Avoid Why Use Instead
Next.js Server-centric framework. Massive overhead for a single-user SPA. Forces Node.js patterns. No benefit without SSR/SSG needs. Vite + React + Hono
Remix / React Router framework mode Adds server framework complexity. This is a simple SPA with a separate API -- framework routing is unnecessary overhead. TanStack Router (SPA mode)
better-sqlite3 Requires native compilation, compatibility issues with Bun. bun:sqlite is built-in and 3-6x faster. bun:sqlite (built into Bun)
Redux / Redux Toolkit Massive boilerplate for a small app. Actions, reducers, slices -- all unnecessary when Zustand does the same in 10 lines. Zustand
Mongoose / MongoDB Document DB is wrong fit. Gear items have relational structure (items belong to setups, threads reference items). SQL is the right model. Drizzle + SQLite
Axios Unnecessary abstraction over fetch. Bun and browsers both have native fetch. TanStack Query wraps fetch already. Native fetch
styled-components / Emotion CSS-in-JS adds runtime overhead and bundle size. Tailwind is faster (zero runtime) and better for consistent minimalist design. Tailwind CSS
Jest / Vitest Bun has a built-in test runner with Jest-compatible API. No need for external test frameworks. bun test
ESLint + Prettier Two tools, complex configuration, slow (JS-based). Biome does both in one tool, faster. Biome

Version Compatibility

Package A Compatible With Notes
Bun 1.3.x bun:sqlite (built-in) SQLite driver is part of the runtime, always compatible.
Drizzle ORM 0.45.x bun:sqlite via drizzle-orm/bun-sqlite Official driver. Import from drizzle-orm/bun-sqlite.
Drizzle ORM 0.45.x drizzle-kit (latest) drizzle-kit handles migration generation/execution. Must match major drizzle-orm version.
React 19.2.x TanStack Router 1.x TanStack Router 1.x supports React 18+ and 19.x.
React 19.2.x TanStack Query 5.x TanStack Query 5.x supports React 18+ and 19.x.
React 19.2.x Zustand 5.x Zustand 5.x supports React 18+ and 19.x.
Vite 8.x @vitejs/plugin-react Check plugin version matches Vite major. Use latest plugin for Vite 8.
Tailwind CSS 4.2.x @tailwindcss/vite v4 uses Vite plugin instead of PostCSS. Import as @tailwindcss/vite in vite config.
Zod 4.x @hono/zod-validator Verify @hono/zod-validator supports Zod 4. If not, pin Zod 3.23.x until updated.

Key Configuration Notes

Bun + Vite Setup

Vite runs as the dev server for the frontend. The Hono API server runs separately. Use Vite's server.proxy to forward /api/* requests to the Hono backend during development.

SQLite WAL Mode

Enable WAL mode on database initialization for better performance:

import { Database } from "bun:sqlite";
const db = new Database("gearbox.db");
db.run("PRAGMA journal_mode = WAL");
db.run("PRAGMA foreign_keys = ON");

Tailwind v4 (No Config File)

Tailwind v4 uses CSS-native configuration. No tailwind.config.js needed:

@import "tailwindcss";
@theme {
  --color-primary: #2563eb;
  --font-sans: "Inter", sans-serif;
}

Drizzle Schema Example (bun:sqlite)

import { sqliteTable, text, integer, real } from "drizzle-orm/sqlite-core";

export const gearItems = sqliteTable("gear_items", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  name: text("name").notNull(),
  category: text("category").notNull(),
  weightGrams: real("weight_grams"),
  priceCents: integer("price_cents"),
  source: text("source"),
  notes: text("notes"),
  createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
});

Sources


Stack research for: GearBox -- gear management and purchase planning web app Researched: 2026-03-14