12 KiB
12 KiB
Stack Research
Domain: Single-user gear management and purchase planning web app Researched: 2026-03-14 Confidence: HIGH
Recommended Stack
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
- Bun official docs -- bun:sqlite features, runtime capabilities (HIGH confidence)
- Hono official docs -- Bun integration, static serving (HIGH confidence)
- Drizzle ORM docs - Bun SQLite -- driver support verified (HIGH confidence)
- Vite releases -- v8.0 with Rolldown confirmed (HIGH confidence)
- Tailwind CSS v4.2 blog -- CSS-native config, Vite plugin (HIGH confidence)
- TanStack Router docs -- v1.167.x confirmed (HIGH confidence)
- TanStack Query docs -- v5.93.x for React (HIGH confidence)
- Zustand npm -- v5.0.x confirmed (HIGH confidence)
- Zod v4 release notes -- v4.3.x confirmed (MEDIUM confidence -- verify @hono/zod-validator compatibility)
- React versions -- v19.2.x confirmed (HIGH confidence)
- Bun SQLite vs better-sqlite3 benchmarks -- 3-6x performance advantage (HIGH confidence)
Stack research for: GearBox -- gear management and purchase planning web app Researched: 2026-03-14