React (Vite)

reactWeb37 lines

Single-page React application built with Vite. No server — everything ships to the browser.

Current — as published in v1.3.2. Written by hand for React (Vite), not generated.

The rule

Everything here is public

There is no server. The bundle ships to the browser in full.

  • No secret in a VITE_* variable — it is inlined and readable by anyone.
  • Authorisation is enforced by the API. Hiding a button is presentation, not security.

Components

  • Function components with typed props. One screen per file; extract at ~150 lines.
  • Lazy-load route components, or every visitor downloads every screen.
  • Keys on lists must be stable ids, never the array index.

State and effects

  • Effects run twice in development under StrictMode, deliberately. Make them idempotent rather than working around it.
  • Cancel in-flight requests on unmount, or use a query library that does.
  • Do not fetch in useEffect without cancellation — races and leaks.
  • Server state and UI state are different concerns; do not store fetched data alongside form state.

Structure

  • Group by feature, not by file type.
  • API access lives in src/services/. Components call services, never fetch directly.

Never

  • Never trust anything the client computed for an authorisation decision.
  • Never ship source maps publicly without deciding to.
  • Never verify only against npm run dev — the build behaves differently.

As each tool receives it

The same guidance, in the shape each editor reads. Cursor and Claude Code are written separately by hand; the rest are derived from the Cursor rule.

.cursor/rules/react.mdchand-written for this tool
.cursor/rules/react.mdc
---
description: React and Vite conventions
globs: ["src/**/*.tsx", "src/**/*.ts", "vite.config.*"]
alwaysApply: false
---

# React (Vite)

## Everything here is public

There is no server. The bundle ships to the browser in full.

- No secret in a `VITE_*` variable — it is inlined and readable by anyone.
- Authorisation is enforced by the API. Hiding a button is presentation, not
  security.

## Components

- Function components with typed props. One screen per file; extract at ~150
  lines.
- Lazy-load route components, or every visitor downloads every screen.
- Keys on lists must be stable ids, never the array index.

## State and effects

- Effects run twice in development under StrictMode, deliberately. Make them
  idempotent rather than working around it.
- Cancel in-flight requests on unmount, or use a query library that does.
- Do not fetch in `useEffect` without cancellation — races and leaks.
- Server state and UI state are different concerns; do not store fetched data
  alongside form state.

## Structure

- Group by feature, not by file type.
- API access lives in `src/services/`. Components call services, never `fetch`
  directly.

## Never

- Never trust anything the client computed for an authorisation decision.
- Never ship source maps publicly without deciding to.
- Never verify only against `npm run dev` — the build behaves differently.

What else this module writes

Selecting React (Vite) contributes more than a rule file — all of it merged with every other module you pick, with conflicts resolved rather than duplicated.

Environment
VITE_API_URLrequiredBase URL of the API this app calls.
VITE_APP_ENVoptionalEnvironment label used for diagnostics and feature gating.
Dependencies
react^19.2.3react-dom^19.2.3react-router-dom^7.18.0vite^8.2.0dev@vitejs/plugin-react^6.0.0dev@types/react^19.2.0dev@types/react-dom^19.2.0dev
Folders
src/components/src/features/src/hooks/src/services/src/lib/public/

Related

Put this in your repo

Adds React (Vite) to a project this tool generated, without starting over. Files you have hand-edited are left alone.