1. Keep Files Close to Their Usage
Organize files within the smallest relevant scope to maintain clarity and reduce complexity.
Avoid placing helper functions or components at the global scope unnecessarily.
Example: If a utility function is only used by
CreateForm.jsxandEditForm.jsx, place it insidecomponents/Form/utils.jsinstead ofsrc/utils.js.Global utilities should only be used if shared across multiple unrelated modules.
2. Semantic Naming with PascalCase
Name components and folders semantically using PascalCase.
Avoid vague or arbitrary names; names should reflect the purpose of the component.
-
Examples:
// Bad const Right_Section = () => {}; const snake_case_component = () => {}; // Good const UserDetails = () => {}; const UserProfileDetails = () => {};
3. Use index.ts / index.tsx in Component Folders
Use
indexfiles to consolidate exports within a folder, simplifying imports.-
Example:
// src/components/commons/index.js import Header from "./Header"; import PageLoader from "./PageLoader"; export { Header, PageLoader };Then, in other files:
import { Header, PageLoader } from "components/commons";
4. Export Conventions
Use default export for single components.
Use named exports only when exporting multiple entities from the same file.
-
Example:
// Default export export default EmptyState; // Named exports export const Header = () => {}; export const Footer = () => {};
5. Group Related State Inside Objects
Combine related state variables into a single object to reduce boilerplate.
-
Example:
const [ticketDetails, setTicketDetails] = useState({ title: "", description: "", count: null, assignee: null, }); -
Always use functional updates to avoid race conditions when updating multiple states asynchronously:
setTicketDetails(prev => ({ ...prev, title: newTitle }));
6. Organize Hooks Properly
Keep all
useStatehooks at the top of the component.Follow with other hooks (
useEffect,useMemo, custom hooks) for readability.Group hooks logically and separate them visually with new lines.
Exceptions are allowed if
useStatedepends on a context or router value.
7. Destructure Props & API Responses
-
Destructure props in the component signature for cleaner code and better IDE support:
// Bad const UserProfile = props => <h1>{props.name}</h1>; // Good const UserProfile = ({ name, title }) => <h1>{name}</h1>; -
Destructure API responses to simplify state updates:
const { ticket: { title, description } } = await api.getTickets(); setTicketTitle(title); setTicketDescription(description);
8. Avoid Unnecessary <div> Wrappers
-
Return the component directly if no wrapper is needed:
// Bad return <div><Button /></div>; // Good return <Button />;
9. Use Modern JSX & JavaScript Patterns
-
Template literals for dynamic strings:
const userDetails = `${user.name} works at ${user.company}`; -
Self-closing tags for components with no children:
<Button label="Submit" /> -
Object literals for conditional rendering when ternaries or switch statements become messy:
const components = { ADMIN: Admin, AGENT: Agent, CUSTOMER: Customer }; const Component = components[role]; return <Component />;
10. Place API Routes Correctly (Next.js)
-
Store backend route handlers inside the
app/apifolder following Next.js conventions:src/app/api/products.js src/app/api/orders.js
11. Additional Tips
Keep code DRY: Reduce duplication using reusable functions or components.
Minimal logic in JSX: Keep render code simple, move complex logic to helper functions.
-
Use boolean shorthand for props:
<Button disabled /> // instead of disabled={true} Semantic props naming: Use camelCase for props (e.g.,
phoneNumber,userName).-
Spread operator for forwarding remaining props:
const Button = ({ label, ...otherProps }) => <Child {...otherProps} />;