Let Kody automatically check quality, security and performance in every pull request—cloud or self-hosted, in under 2 minutes.
A practical guide for developers and reviewers to keep JavaScript code clean, secure, and high-performing.
Here’s what this checklist helps you review before approving a pull request.
✅ Code & Design Quality – correctness, logic, structure, and style
✅ Security & Performance – vulnerabilities, efficiency, and scalability
✅ Operational Readiness – testing, observability, and feature rollouts
✅ Integration & Boundaries – APIs, data handling, and external contract
Use these points as a starting guide to automate code reviews with your agent.
PR goal is clearly explained (what, why, linked issue/ticket).
Scope is focused: one problem or feature per PR.
Branch name, title, and description follow team conventions.
Includes tests, screenshots, or storybook/playwright story if relevant.
Migrations/feature flags/rollback strategy described.
Happy and failure paths covered; no unreachable code.
Guard clauses and conditions are clear; avoid deep if
nesting.
Functions are pure where possible; side effects explicit.
Names match behavior—functions do exactly what their name implies.
Avoid null
/undefined
pitfalls (use ??
and ?.
when appropriate).
No dead code, leftover logs, or TODOs without a linked issue.
Inputs/outputs validated (Zod/Yup/manual) at all external boundaries.
XSS: Never inject unsanitized user input into the DOM (innerHTML
, dangerouslySetInnerHTML
).
Injection: No string-built SQL/command calls—use placeholders/ORM.
Secrets: No API keys or credentials in client or repo; use environment variables.
AuthN/AuthZ: Checks happen on the server; routes/handlers protected.
CSRF: State-changing endpoints protected with tokens or SameSite
.
Open redirect / URL validation: Validate next
/redirect
query params.
Dependencies: No known vulnerabilities (npm audit
, Snyk, etc.).
SSR/Edge: Never leak sensitive data to the client.
Headers: Content-Security-Policy
, X-Frame-Options
, Strict-Transport-Security
configured at the server/proxy.
Algorithms and data structures chosen with complexity in mind (O(n) vs O(n²)).
Avoid repeated traversals; use memoization when useful.
Async I/O: Parallelize with Promise.all
/allSettled
when calls are independent.
Debounce/Throttle heavy UI events (scroll, resize, input).
Minimize unnecessary renders/reflows (state batching, list virtualization).
Bundle: Granular imports, code-splitting, lazy loading of heavy routes/pages.
Assets: Modern image formats, proper sizing, loading="lazy"
.
Node: Don’t block the event loop—CPU tasks → worker threads/queues.
await
used correctly; errors handled (try/catch
or Promise.catch
).
External calls have timeouts, retries, and cancellation (AbortController
).
Guard against race conditions (check state before/after await
; use light locks if needed).
In streams/event emitters: remove listeners and close connections.
Matches team style guide (automatic formatter in place).
Prefer immutability; don’t mutate params/props.
Functions are small and cohesive; extract helpers when complexity grows.
Favor early returns over nested if
pyramids.
Comments only where they add context (don’t explain the obvious).
Naming: nouns for data, verbs for actions; avoid cryptic abbreviations.
Public functions/utilities have JSDoc or clear contracts.
Use JSDoc/typedefs for public APIs and complex objects.
Defensive type checks (Array.isArray
, typeof
, in
).
Functions always return a predictable type (no “sometimes null, sometimes object”).
If using TypeScript: any
is justified and isolated; strict
enabled.
Errors carry clear messages and context.
No silent exception swallowing; justified where you must silence.
Log levels are correct (debug/info/warn/error) and never expose sensitive data.
Browser: error boundaries and network error capture;
Node: handle unhandledRejection
/uncaughtException
with graceful shutdown.
Metrics/tracing for critical paths (latency, error rate).
Validate all payloads (schema-driven).
Preserve versioning/backward compatibility.
Idempotent operations for retries.
Consistent error format (HTTP codes, {code,message,details}
shape).
Normalize/sanitize dates, numbers, and locales.
Unit tests cover critical logic (branch conditions included).
Integration tests for endpoints/DB basics.
Essential end-to-end tests for key revenue/risk flows.
Tests are stable, fast, and independent; fixtures/mocks realistic.
Snapshot tests minimal and readable.
Each flag has an owner, scope, and planned lifetime; rollback is simple.
Flagged code is clean; removal is scheduled.
Metrics connected to flag adoption/impact.
await
inside loops when Promise.all
would be better.
JSON.parse/stringify
for deep clone without considering dates/Map/Set.
Direct mutation of req
/res
/props
/state
.
Disabling ESLint rules without justification.
Using Date
without timezone awareness; toLocaleString
without locale.
setInterval
/setTimeout
left orphaned; clear on unmount/shutdown.
Adding a heavy library for a trivial task (e.g., whole lodash for one function).
Let Kody automatically check quality, security and performance in every pull request—cloud or self-hosted, in under 2 minutes.