React Standards

by Convext

Public

Code standards and best practices for React projects

typescript react

Rules (60)

Angular

high Use standalone components

Standalone components are the default (Angular 17+). NgModules are legacy. Use Signals for reactive state. Deferrable views for lazy loading.

high Use Angular CLI

`ng generate` for scaffolding. `ng build --configuration production`. Schematics for custom generators.

high Use RxJS properly

Observables for async. Use async pipe in templates. Unsubscribe or use takeUntilDestroyed. Signals for simple state.

medium Use Angular services for shared logic

Injectable services for business logic. `providedIn: 'root'` for singletons. Inject with constructor or inject().

Config

high Use environment variables for configuration

Config in env vars, not code. Never commit .env. Commit .env.example. Never hardcode secrets.

Database

critical Never store sensitive data in plain text

Passwords: bcrypt. API keys: encrypt. PII: field-level encryption. Never log sensitive data.

Dependencies

critical Always use latest dependency versions

Use latest stable versions. Fix breaking changes—don't avoid upgrades. Check official registries.

Express

high Use Express middleware properly

Middleware order matters. Error handlers last with 4 params. Use helmet, cors, compression.

high Handle async errors

Wrap async handlers or use express-async-errors. Central error handler. Return proper status codes.

medium Use Express Router for modularity

Router for route groups. Mount with `app.use('/api', router)`. Keep routes thin, logic in services.

Formatting

high Use Prettier for code formatting

Prettier for JS/TS/CSS/HTML/JSON. Minimal config. Run on save. Pre-commit hook. CI check.

Git

medium Atomic commits with Conventional Commits

Small, focused commits. Use: feat/fix/refactor/test/docs/chore. Each commit independently deployable.

Javascript

high Use const and let, never var

`const` by default, `let` for reassignment. Never `var` (hoisting bugs).

high Use async/await over callbacks and .then()

async/await for all async code. Easier to read, proper try/catch, works with loops.

high Use TypeScript for all new projects

TypeScript, not JS. Enable `strict: true`, `noImplicitAny`, `strictNullChecks`.

medium Use ESLint with strict configuration

ESLint + @typescript-eslint recommended rules. No `any`, no unused vars. Run in CI.

Linting

medium Use Biome for JS/TS linting and formatting

Biome: fast all-in-one linter+formatter. Replaces ESLint+Prettier. Single config. Rust-based.

Llm Behavior

critical Own all code in the repository

You wrote every line. No 'pre-existing issues'—only issues you haven't fixed yet.

critical No rationalizations

No excuses: 'pre-existing', 'unrelated', 'tedious', 'for now'. Recognize and continue working.

critical User defines success

User and tests define done. Don't redefine scope or declare partial progress as complete.

Nestjs

high Use NestJS dependency injection

Constructor injection. @Injectable() on services. Custom providers for factories. Scope: DEFAULT unless needed.

high Use NestJS modules properly

Feature modules for domain boundaries. CoreModule for singletons. SharedModule for reusable providers.

medium Use NestJS pipes and guards

ValidationPipe with class-validator DTOs. Guards for auth. Interceptors for transforms. Exception filters.

Nextjs

high Use App Router

App Router over Pages Router (Next.js 13+). Server Components by default. 'use client' only when needed.

high Use Next.js data fetching

Fetch in Server Components. Use `cache: 'force-cache'` or `revalidate`. generateStaticParams for static paths.

high Use Server Actions

Server Actions for mutations. `'use server'` directive. Form actions. Revalidate with revalidatePath/revalidateTag.

medium Use Next.js Image and Link

next/image for optimized images. next/link for client navigation. Automatic prefetching.

Package Manager

high Use npm properly

package-lock.json (commit it). `npm ci` in CI. Audit for vulnerabilities. Scripts for common tasks.

medium Use Yarn properly

yarn.lock (commit it). Workspaces for monorepos. `yarn install --frozen-lockfile` in CI. Yarn Berry for PnP.

medium Use pnpm for efficiency

pnpm: fast, disk-efficient. pnpm-lock.yaml. Workspaces for monorepos. Strict node_modules by default.

Rails

critical Use Rails credentials for secrets

Rails.application.credentials for secrets. `rails credentials:edit`. Environment-specific credentials. Never commit master.key.

React

high Use React Query for server state

TanStack Query for server state. Auto caching/revalidation. useQuery for reads, useMutation for writes.

high Use functional components with hooks

Functional components + hooks only. No class components. Hooks enable reuse without HOCs.

high Use React Query or SWR for data fetching

TanStack Query or SWR for fetching. Auto caching, revalidation, loading/error states. Not useEffect+fetch.

high Use React 19 features

Server Components for data fetching. Actions for mutations. use() hook for promises. Optimistic updates. React Compiler for auto-memoization.

medium Use Zustand for React state

Zustand for simple global state. No boilerplate. Hooks-based. Persist middleware for storage.

medium Avoid prop drilling with Context or state management

Context for static data, Zustand/Jotai for simple state, Redux Toolkit for complex. No deep prop drilling.

Security

critical Use HTTPS everywhere

Force SSL, redirect HTTP→HTTPS, secure cookies (Secure/HttpOnly/SameSite), HSTS headers.

critical Implement proper authentication and authorization

Auth: bcrypt/argon2 for passwords, rate limiting, secure sessions/tokens. Authz: check permissions on every request, use policy objects or middleware.

critical Validate and sanitize all user input

Allowlists, not denylists. Validate type/length/format. Sanitize HTML. Parameterized queries only.

Svelte

high Use Svelte reactivity

$: for reactive statements. Stores for shared state. Runes ($state, $derived) in Svelte 5. Two-way binding with bind:.

high Use SvelteKit for applications

SvelteKit for routing, SSR, API routes. +page.svelte for pages. +layout.svelte for shared UI. Load functions for data.

Testing

critical No mocking the class under test

Test real instances. Mocking the class under test hides bugs.

critical Never ignore failing tests

Fix failures immediately. No skipping, no "pre-existing issues." Own the codebase state—a test suite with ignored tests can't be trusted.

high Use Jest for JavaScript testing

Jest for unit/integration tests. `describe`/`it` blocks. Mock with jest.mock(). Snapshot testing sparingly.

high Test behavior, not implementation

Test public interfaces, inputs/outputs. Tests must survive refactoring. Don't test private methods.

high Use Vitest for Vite projects

Vitest for Vite-based projects. Jest-compatible API. Native ESM. Use @testing-library for components.

high Use Cypress for E2E testing

Cypress for E2E tests. Commands for reusable actions. cy.intercept() for network. Avoid flaky selectors.

high Use Playwright for cross-browser E2E

Playwright for multi-browser E2E. Auto-wait for elements. Trace viewer for debugging. Parallel execution.

high TDD: Red -> Green -> Refactor

1) Write failing test 2) Minimum code to pass 3) Refactor. Every line has a reason.

high Mock only at external boundaries

Mock only: external HTTP APIs, time, filesystem side effects, third-party services. Use real implementations for internal services, database, and business logic.

medium Use Mocha for Node.js testing

Mocha with Chai assertions. describe/it blocks. Sinon for mocking. async/await in tests.

medium One assertion per test (conceptually)

One logical concept per test. Multiple asserts OK if same concept. Clear test names describing behavior.

medium Use fixtures or factories for test data

Use consistent test data setup: fixtures for stable reference data, factories for dynamic scenarios. Avoid inline object creation scattered throughout tests.

Typescript

high Use Zod for TypeScript validation

Zod schemas for runtime validation. Infer types from schemas. Composable. Works with React Hook Form.

Vue

high Use Vue 3 Composition API

Composition API over Options API. `<script setup>` for SFCs. Composables for reusable logic. ref/reactive for state.

high Use Pinia for state management

Pinia over Vuex. Define stores with `defineStore`. Composable pattern. DevTools integration.

medium Use Vue Router properly

Named routes, navigation guards. Lazy-load routes with dynamic imports. Use route meta for permissions.

Workflow

critical Code must work locally before pushing

Verify changes locally: run app, run tests, check for errors. CI catches environment issues, not basic bugs.

high Run formatter, linter, and tests before commit

Format → Lint → Test before every commit. Never rely on CI for basic checks.

Language Standards (1)

typescript
Framework: react Linter: eslint Formatter: prettier

Use this Ruleset

Sign in to adopt or fork this ruleset

Sign in with GitHub

Statistics

Rules
60
Standards
1
Projects using
1
Created
Jan 15, 2026