agentleFS
MartinKChenMartinKChen/harness-claude-code/skills/pattern-engineer-vite/SKILL.md

pattern-engineer-vite

Skill0 starsChanged 5 months agoMITView on GitHub

Vite implementation bullets: pick Vite for pure CSR (no SSR/SSG/SEO); env vars via `import.meta.env` with `VITE_` prefix (NOT a security boundary); `vite-plugin-checker` or `tsc --noEmit` in CI — `vite build` does not type-check; `vite-tsconfig-paths` over hand-rolled aliases; `build.sourcemap: false` in prod; `server.host: true` for containerized dev; avoid barrel files; route-boundary splitting via `lazy()` + `<Suspense>`. Activate when editing `vite.config.*` or scaffolding a Vite React app.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

11 rules. About 0 are common, 2 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-vite.md in the consuming project (resolve …

    line 14
  2. Very specific:

    Don't reach for Next.js "just in case." If today's requirements are CSR-only, ship Vite.

    line 22
  3. Very specific:

    Read each import.meta.env.VITE_* through a single typed accessor module so the call site doesn't repeat the prefix.

    line 28
  4. Very specific:

    Don't put route-specific logic in vite.config — that belongs in the app code.

    line 36
  5. Very specific:

    Use vite-tsconfig-paths instead of hand-rolling resolve.alias entries that already exist in tsconfig.json paths — one source of truth.

    line 38
  6. Very specific:

    Add vite-plugin-checker (or run tsc --noEmit in CI).

    line 39
  7. Very specific:

    Use Vitest for unit tests.

    line 46
  8. Distinctive:

    Don't lazy-load the landing route — it pays cost on the critical path.

    line 56
  9. Very specific:

    Import images / fonts as ES modules to get hashed URLs: import logoUrl from './logo.svg'.

    line 60
  10. Very specific:

    Avoid barrel files (index.ts re-exporting everything from a directory) — importing one symbol forces Vite to load every re-export.

    line 66
  11. Distinctive:

    Don't override the port via shell env to dodge a one-time conflict — that's the slice-isolation rule from the engineer-pre-push hook, not a …

    line 72

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

pattern-engineer-vite

When to activate

Activate when editing vite.config.ts / vite.config.js, vitest.config.ts, scaffolding a Vite-based React app, switching between Vite and Next.js, configuring dev-server proxy / plugins / aliases, or touching import.meta.env. Skip for Next.js apps (use Next-specific patterns instead) or non-frontend code.

Project memory overlay

After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-vite.md in the consuming project (resolve MAIN_ROOT="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"). If present, load it as an additive overlay to the rules below; if absent, skip silently. See memory-convention for the full contract (additivity, severity floor, conflict surfacing).

Patterns

Stack choice

  • Pick Vite when the app is pure CSR: internal tools, dashboards behind auth, embedded widgets, prototypes, SPAs where SEO doesn't matter.
  • Pick Next.js when the app needs SSR / SSG / ISR, edge runtime, file-based routing, server components, SEO-critical pages, image optimization, or first-class API routes.
  • Don't reach for Next.js "just in case." If today's requirements are CSR-only, ship Vite; migrating later is straightforward.

Env vars

  • import.meta.env.VITE_<NAME> for env vars exposed to the client. The VITE_ prefix is mandatory — without it Vite won't inline the value.
  • Server-only secrets never get the VITE_ prefix (Vite refuses to expose them); they live in the backend.
  • Read each import.meta.env.VITE_* through a single typed accessor module so the call site doesn't repeat the prefix.
  • .env, .env.local, .env.<mode>.local are in .gitignore; only .env.example (placeholders) committed; mirror every import.meta.env.VITE_* key.
  • loadEnv(mode, root, ['VITE_']) — always pass an explicit prefix list. loadEnv(mode, root, '') loads ALL env vars (including server secrets), and a define: {...} mistake can then inline them into the client bundle.
  • The VITE_ prefix is NOT a security boundary. Any VITE_* value is statically inlined into the shipped JS and trivially extractable; only public values (API URLs, feature flags, public keys) belong there.

Vite config

  • vite.config.ts owns: build target (browser baseline), resolve.alias for @/..., dev-server proxy to the backend, plugins (React, Tailwind, etc.), server.port if non-default needed.
  • Don't put route-specific logic in vite.config — that belongs in the app code.
  • Proxy backend calls in dev: server.proxy = { "/api": "http://localhost:8000" } so the SPA sees same-origin and cookies / CSRF work.
  • Use vite-tsconfig-paths instead of hand-rolling resolve.alias entries that already exist in tsconfig.json paths — one source of truth.
  • Add vite-plugin-checker (or run tsc --noEmit in CI). vite build transpiles but does not type-check; type errors silently ship.
  • build.sourcemap: false for production unless you upload to an error tracker (Sentry, Bugsnag). Public source maps leak the original code.
  • Containerized dev: server.host: true so the container binds 0.0.0.0 and the host can reach it. Default localhost binding is unreachable from outside the container.
  • Clear node_modules/.vite after dep changes / branch switches with non-trivial dep diffs — the pre-bundle cache causes phantom errors when stale.

Vitest

  • Use Vitest for unit tests; configure via vitest.config.ts (or merge into vite.config.ts with defineConfig).
  • test.globals: true if the project uses globals; matching compilerOptions.types entry for TS.
  • test.environment: 'jsdom' for component tests; 'node' for pure-logic tests.
  • Setup file (vitest.setup.ts) registers @testing-library/jest-dom matchers, MSW handlers, etc.
  • vi.mock(...) only when there is no seam to inject a fake; prefer dependency injection.

Code splitting

  • Split at route boundaries via lazy(() => import('./pages/Settings')) paired with a meaningful <Suspense fallback={<PageSkeleton />}>.
  • Heavy conditional UI (modals, editors, charts) lazy-loads too; tiny components don't.
  • Don't lazy-load the landing route — it pays cost on the critical path.

Static assets

  • Import images / fonts as ES modules to get hashed URLs: import logoUrl from './logo.svg'.
  • Public assets that need a stable URL go in public/ (served as-is, no hashing).
  • ?url / ?raw / ?worker query-suffix imports for explicit handling.

Module-resolution performance

  • Avoid barrel files (index.ts re-exporting everything from a directory) — importing one symbol forces Vite to load every re-export. This is the #1 dev-server slowdown.
  • Be explicit with import extensions (./Component.tsx, not ./Component); each implicit extension triggers up to 6 filesystem checks via resolve.extensions.

Dev server

  • server.port defaults to 5173; override in vite.config.ts (committed) only if the standard collides with another local service.
  • Don't override the port via shell env to dodge a one-time conflict — that's the slice-isolation rule from the engineer-pre-push hook, not a permanent config change.
  • HMR works out of the box; don't disable it.

Building for production

  • npm run build produces hashed assets in dist/.
  • The container image's final stage copies dist/ into nginx.
  • vite preview is for sanity-checking the built bundle locally; never serve preview in production.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.