192 lines
12 KiB
Markdown
192 lines
12 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
```typescript
|
|
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:
|
|
```css
|
|
@import "tailwindcss";
|
|
@theme {
|
|
--color-primary: #2563eb;
|
|
--font-sans: "Inter", sans-serif;
|
|
}
|
|
```
|
|
|
|
### Drizzle Schema Example (bun:sqlite)
|
|
```typescript
|
|
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](https://bun.com/docs) -- bun:sqlite features, runtime capabilities (HIGH confidence)
|
|
- [Hono official docs](https://hono.dev/docs) -- Bun integration, static serving (HIGH confidence)
|
|
- [Drizzle ORM docs - Bun SQLite](https://orm.drizzle.team/docs/connect-bun-sqlite) -- driver support verified (HIGH confidence)
|
|
- [Vite releases](https://vite.dev/releases) -- v8.0 with Rolldown confirmed (HIGH confidence)
|
|
- [Tailwind CSS v4.2 blog](https://tailwindcss.com/blog/tailwindcss-v4) -- CSS-native config, Vite plugin (HIGH confidence)
|
|
- [TanStack Router docs](https://tanstack.com/router/latest) -- v1.167.x confirmed (HIGH confidence)
|
|
- [TanStack Query docs](https://tanstack.com/query/latest) -- v5.93.x for React (HIGH confidence)
|
|
- [Zustand npm](https://www.npmjs.com/package/zustand) -- v5.0.x confirmed (HIGH confidence)
|
|
- [Zod v4 release notes](https://zod.dev/v4) -- v4.3.x confirmed (MEDIUM confidence -- verify @hono/zod-validator compatibility)
|
|
- [React versions](https://react.dev/versions) -- v19.2.x confirmed (HIGH confidence)
|
|
- [Bun SQLite vs better-sqlite3 benchmarks](https://bun.com/docs/runtime/sqlite) -- 3-6x performance advantage (HIGH confidence)
|
|
|
|
---
|
|
*Stack research for: GearBox -- gear management and purchase planning web app*
|
|
*Researched: 2026-03-14*
|