lean-web · git:20261019.da88d4b · 2026-10-19 · sha256 c6bceec6022c8390
lean-web git:20261019.da88d4bA
Immutable. This exact content never changes and is served at /api/v1/blob/c6bceec6022c8390.
--- name: lean-web description: "Load lean-web when working on web or Node.js projects: JavaScript, TypeScript, HTML/CSS, React, Next.js, Fastify, backend APIs, authentication/OAuth, monorepos, tooling, testing, or web performance. Apply framework-specific rules only when that stack is present." --- # lean-web ## Contract Use `AGENTS.md` for agent roles/delegation; this skill covers web/Node implementation only. Executing agent loads it (ORCHESTRATOR on direct work; CODER on delegated work). Do not add frameworks/tools/features just because listed here. Detect existing stack before deciding. Target: smallest correct patch + relevant proof. ## Detect → locate → fix → verify Identify `package.json`, lockfile/package manager, Node version, framework, tsconfig, lint/test/build scripts, deployment target; respect existing conventions, runtime/browser support and CI. Use project scripts and local binaries (`npm run ...`, `pnpm ...`, `yarn ...`, `bun ...`) rather than inventing commands. Locate the failure boundary and patch minimally. Don't change generated files, lockfile or dependencies without reason; don't mix package managers. For behavior changes add regression tests covering positive, negative and error cases. Run focused tests/typecheck/lint/build as relevant; report exact exits, not inferred passes. Prioritize correctness, accessibility, security and performance in that order. ## JavaScript / TypeScript Keep modules explicit: follow existing ESM/CJS convention, exports, import extensions, module resolution and browser/Node targets. Prefer `const`, pure/local functions and early return; avoid hidden mutation and unnecessary abstractions. TS: derive types from runtime sources (`as const`/`typeof`), use `keyof`, `T[K]`, generics/utility types only when they clarify the contract; narrow `unknown` at untrusted boundaries with runtime validation. Avoid `any`, unsafe assertions, `@ts-ignore`, duplicated type definitions and type gymnastics for ordinary problems. Reproduce actual diagnostics with repo typecheck (`tsc --noEmit` when applicable), repair callers and rerun. For Node native TS type stripping, first verify Node version/support and repository setup; use `import type`, compatible erasable syntax and proper file extensions, not enums/parameter properties requiring transpilation. Do not replace an existing TS build pipeline merely to use native stripping. ## Async / Node.js reliability Run independent I/O concurrently (`Promise.all`/settled according to partial-failure policy); await dependent work in order; propagate errors and cancellation. Never fire-and-forget required writes. Bound concurrency, requests, queues, timeouts and retries (backoff + idempotency); avoid blocking event loop with sync I/O/CPU work. For large files/ETL use `node:stream/promises` `pipeline()` and async transforms with backpressure; avoid buffering entire input. Cache only measured repeat work: bounded LRU for reusable results, inflight promise dedup for repeated async requests, expiry/invalidation and user-scope isolation; never cache private request data globally. On shutdown stop intake → drain work → close DB/network/timers → exit; test open handles and flaky async cleanup. Use structured log context without secrets; classify operational vs programming errors; do not swallow rejections. Profile representative workloads (`node --cpu-prof`, heap snapshots/inspector when safe) and benchmark before optimizing. ## Web UI / HTML / CSS Semantic HTML, accessible names/labels, keyboard + focus states, correct heading order, contrast and responsive layouts. Prefer CSS layout (grid/flex) and existing tokens/components over JS positioning and new design systems. Keep SSR and client markup consistent; avoid hydration flicker, layout shifts and unnecessary reflows. Defer noncritical scripts, optimize images (dimensions, lazy below-fold, correct formats), fonts, and critical resource loading. For long offscreen content, consider `content-visibility` only with accessibility and scroll behavior tested. Preserve user interaction and reduced-motion preferences. ## React / Next.js only **Highest ROI:** eliminate serial network waterfalls; begin independent requests early, run in parallel, stream/Suspense when supported. Reduce client JS: keep server-side work server-side; use narrow imports, dynamic import for heavy optional UI, defer third-party libraries, check real bundle output. Auth-check server actions, loaders and routes; never trust client-only gates. Cache request-scoped dedup with correct lifetimes; cross-request cache only with explicit keys/invalidation and no data bleed. Minimize server→client serialized props; never use shared mutable request state at module scope. **Rendering:** derive state during render rather than syncing it via effects; event-driven updates belong in handlers. Localize state, stabilize keys; `memo`/`useMemo`/`useCallback` only when profiling shows value, not reflexively. Use functional state setters, refs for transient nonvisual values, and transitions/deferred values for nonurgent expensive updates. Avoid nested component declarations and duplicate global listeners. Respect installed React/Next APIs; React 19 ref-as-prop and `use()` behavior are version-gated, not mandatory upgrades. **Composition:** many boolean behavior props → explicit variants or compound components when they reduce complexity; provider owns shared state/actions, children compose UI. Prefer `children` to needless render-prop callbacks. Avoid forcing context or a component library for a simple component. ## HTTP APIs / Fastify only Version-match framework docs and existing architecture. For Fastify: compose encapsulated plugins/routes/decorators; register hooks in correct scope and lifecycle; schema-validate input + serialize output, set sensible content types/statuses and centralized errors. Prefer async handlers, Pino structured logging, official plugins, route-level authentication/authorization; correct CORS allowlist and secure headers; limit body size and rate. Validate unknown input, parametrize DB queries, close resources, use transactions where needed. Test with `app.inject()` and real service/database tests for wiring; avoid booting a network server just to test handlers. For WebSocket/streams, handle disconnects, backpressure and cleanup. ## Auth / OAuth / Better Auth only Server verifies identity **and** authorization for each sensitive operation. Cookies: HttpOnly + Secure + appropriate SameSite, CSRF/origin controls, safe session invalidation; never put secrets/tokens in logs, URLs or public bundles. OAuth: authorization-code + PKCE (`S256`) for public clients; verify `state`, exact allowed redirect URIs, issuer/audience/expiry/signature of JWTs via trusted keys/JWKS; use correct refresh rotation/revocation and client-credential scope. No implicit token flow or disabling CSRF/origin validation to silence errors. Better Auth: detect resolved installed version (lockfile first) and consult matching documentation; use existing DB adapter and `BETTER_AUTH_SECRET`/`BETTER_AUTH_URL` securely. Schema generation/migration after plugin changes; distinguish ORM model names from SQL table names; understand `secondaryStorage` session precedence and cookie-cache limits. Align server/client plugins, allowed origins, rate limits and provider callbacks; verify sign-in, sign-out, expired/invalid sessions, privilege boundaries and migration. Never run destructive migrations unapproved. ## Monorepo / Turborepo only Inspect workspace manifests, `turbo.json`, package manager and installed `turbo` docs (`node_modules/turbo/docs/README.md` or resolved package path); use **installed-version** syntax. Preserve task graph (`dependsOn`), outputs, inputs, environment hash, cache isolation and lockfile consistency. Cache only deterministic tasks; don't share secrets via remote cache. Use affected-package filters and run necessary dependent builds/tests. CI must use reproducible lockfile install and clean cache behavior. ## Tooling / lint / tests Keep current ESLint/Prettier/neostandard config; ESLint 9 uses flat `eslint.config.*` when project opts in. Do not migrate or apply `--fix` across unrelated files without request. Prefer existing formatter, consistent import sorting and scoped lint/typecheck. Tests: use repo's Jest/Vitest/node:test/Playwright/Cypress; deterministic fixtures and cleanup. Isolate hanging/flaky tests, check timers, global state, worker teardown and open sockets; repeated retries diagnose, not fix. Test key browser paths with keyboard navigation, responsive size and async failure states. Build is not proof of runtime correctness. For performance, compare controlled baselines (bundle sizes, Core Web Vitals, request p95, CPU/memory); change one hypothesis, benchmark again; never invent numbers. ## Node core / native ONLY when implicated For `nodejs/node`, N-API addons, libuv or V8 issues: inspect matching core contribution/build/test conventions, engine version and ABI. Use `node-gyp`/`binding.gyp` and native debugging only for native tasks. Diagnose event loop stalls, thread pool saturation, GC pressure, hidden-class/deopt changes with profiles before tuning; protect Node internals from prototype pollution where primordials required. Never impose Node-core build conventions on ordinary Node apps. ## Other requested tasks only Docs: choose tutorial (learning), how-to (procedure), reference (facts/API), explanation (concept); one purpose per page, test commands/examples. Repo agent instructions: keep `AGENTS.md` for non-discoverable actionable conventions rather than repeating code/README; prune stale rules. Skill optimization: measure skill-off/on verified task results, regressions, token cost; keep high-signal triggers. Git/GitHub: prefer `gh`/scoped git evidence, preserve history/signing, no destructive changes or public disclosure of embargoed advisories. Snippet graphics: when expressly requested, use installed renderer/config and verify actual output. None of these peripheral workflows should activate for an ordinary feature fix. ## Result Report `STATUS` (PASS/UNVERIFIED/BLOCKED/FAILED), changed paths, exact checks/exits, residual runtime/security risks. Separate source-backed measurements from estimates. Stop after the requested, verified scope.