Skip to content

Bootstrap: Vite + React + TS + Tailwind v4 + Biome + Vitest - #1

Merged
unforced merged 1 commit into
mainfrom
bootstrap-scaffold
Apr 18, 2026
Merged

Bootstrap: Vite + React + TS + Tailwind v4 + Biome + Vitest#1
unforced merged 1 commit into
mainfrom
bootstrap-scaffold

Conversation

@unforced

Copy link
Copy Markdown
Contributor

Why

First PR in the Lens serialization. Gets the foundations in place so each subsequent PR can focus on one user-visible slice — vault client + OAuth, note list, note view, editor, graph, etc. — without re-litigating tooling.

Stack choices

Choice Why
Bun Matches the vault's runtime; one less thing to explain to contributors.
Vite 6 + React 19 + TS strict Current baseline; project-reference tsconfigs keep tsc -b fast.
Tailwind v4 Matches Prism; @theme lets us express the design tokens directly in CSS.
Biome One tool for lint + format + import-organize. Config is ~20 lines.
Vitest 3 + Testing Library Vitest 3 aligns with Vite 6 (Vitest 2 pinned to Vite 5, caused type conflicts in the config).

Theme tokens

Palette, typography, and idiom borrowed from parachute.computer so Lens feels like a sibling, not a stranger:

  • sage --color-accent: #4a7c59
  • warm off-white --color-bg: #faf8f4
  • Instrument Serif (display) / DM Sans (body) / JetBrains Mono (code)
  • Dark mode wired via @media (prefers-color-scheme: dark) at the theme level. The explicit light/dark toggle lands in the theme-polish PR (Hotfix: header label fallback + VITE_EXPOSE gate #10 in the serialization).

Layout

src/
  app/App.tsx        – placeholder landing
  styles/index.css   – tailwind entry + @theme tokens
  test/setup.ts      – testing-library/jest-dom
  main.tsx           – React entry
vite.config.ts       – build
vitest.config.ts     – test (kept separate to avoid vite/vitest version drift)
tsconfig.{app,node}  – strict references

@/ path alias to src/ for readable imports.

What this PR deliberately does not do

  • No vault client, no OAuth, no API calls — PR Vault client + OAuth 2.1 PKCE + multi-vault switcher #2.
  • No router — wait until we have more than one route.
  • No TanStack Query — wait until we have server state.
  • No global state — wait until the store's shape is motivated by a real use case.

Keeping PR #1 small and landable is the point.

Gates

  • bun run typecheck — clean
  • bun run lint — clean
  • bun run test — 2/2 pass (smoke test for the landing shell)
  • bun run build — 196 kB JS / 10 kB CSS gzipped
  • bun run dev — starts on :5173, entry module transforms

Test plan

  • bun install && bun run dev, visit http://localhost:5173, confirm the placeholder renders with the parachute.computer palette
  • Check dark mode via system preference
  • bun run test — expect 2 passing tests
  • bun run build — expect no warnings

🤖 Generated with Claude Code

Sets the foundations so the remaining work can focus on the vault client,
OAuth, and UI. Choices:

- Bun as package manager (matches the vault's runtime).
- Vite 6 + React 19 + TypeScript strict + project-reference tsconfigs.
- Tailwind v4 with theme tokens borrowed from parachute.computer (sage
  accent, warm off-white, Instrument Serif / DM Sans / JetBrains Mono).
  Dark mode via @media (prefers-color-scheme: dark) — the explicit toggle
  lands in the theme-polish PR.
- Biome for lint + format (one tool, one config).
- Vitest 3 + Testing Library for unit tests; vite.config and vitest.config
  split to keep vite's type-check clean under Vite 6.
- @/ path alias to src/ for readable imports.

Landing page is intentionally a placeholder explaining the scaffold state;
vault URL entry and PKCE OAuth land next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant