Appearance
Code Quality Guide
ESLint
ESLint is a static analysis tool that finds and fixes problems in your code. It catches bugs, enforces coding standards, and improves consistency across your team.
What's Configured
This project uses:
eslint-config-next— Next.js recommended rules including Core Web Vitalseslint-plugin-jsx-a11y— accessibility rules that catch common a11y issues in JSX
Running ESLint
bash
pnpm lint # Check for issues
pnpm lint:fix # Automatically fix issues where possibleWhat eslint-plugin-jsx-a11y Adds
This plugin catches accessibility mistakes like:
- Missing
alttext on images - Non-interactive elements with click handlers (should be buttons)
- Missing
aria-labelon icon-only buttons - Form inputs without associated labels
Prettier
Prettier is an opinionated code formatter. It enforces a consistent style across all files — no more debating tabs vs spaces or where to put semicolons.
Configured Rules
| Rule | Value | What It Does |
|---|---|---|
semi | true | Always use semicolons |
singleQuote | true | Use single quotes for strings |
tabWidth | 2 | 2 spaces for indentation |
trailingComma | es5 | Trailing commas where valid in ES5 |
printWidth | 100 | Wrap lines at 100 characters |
Running Prettier
bash
pnpm format # Format all files
pnpm format:check # Check if files are formatted (used in CI)Husky & lint-staged
Husky manages git hooks — scripts that run automatically at certain points in the git workflow.
lint-staged runs linters only on staged files (files you're about to commit), making pre-commit checks fast.
What Happens on Commit
When you run git commit:
pre-commithook runs lint-staged:- ESLint checks and fixes
.tsand.tsxfiles - Prettier formats all staged files
- ESLint checks and fixes
commit-msghook runs commitlint:- Validates your commit message follows Conventional Commits format
If either check fails, the commit is blocked. Fix the issues and try again.
Conventional Commits
All commit messages must follow the Conventional Commits format:
type: descriptionAll Valid Types
| Type | Description | Example |
|---|---|---|
feat | New feature | feat: add search functionality |
fix | Bug fix | fix: correct date formatting |
docs | Documentation changes | docs: update deployment guide |
style | Formatting only (no logic change) | style: fix indentation in utils |
refactor | Code reorganization (no feature/fix) | refactor: simplify auth logic |
test | Adding or updating tests | test: add button component tests |
chore | Maintenance tasks | chore: update dependencies |
perf | Performance improvement | perf: lazy load dashboard charts |
ci | CI/CD changes | ci: add preview deployment step |
build | Build system changes | build: upgrade Tailwind to v4 |
revert | Revert a previous commit | revert: undo auth flow changes |
When a Commit Is Blocked
If your commit is rejected:
- Linting failure: Run
pnpm lint:fixandpnpm format, then re-stage and commit - Commit message failure: Rewrite your message following the format above
- Tip: Use
git commit -m "feat: your description"to ensure the format is correct
Extending the Configuration
Adding ESLint Rules
Edit eslint.config.mjs to add or override rules:
javascript
{
rules: {
'no-console': 'warn', // Warn on console.log usage
},
}Changing Prettier Rules
Edit .prettierrc to adjust formatting preferences. See Prettier Options for all available options.
Useful Resources
Export Doc Comment Convention
All exported symbols in application code should have a JSDoc-style block comment directly above the export.
Required Structure
- First line: A short purpose statement (what this export does)
@paramtags: Required for function/component/hook parameters@returnstag: Required for function/component/hook return behavior- Types and constants: Use a concise intent statement (no
@param/@returnsneeded)
Recommended Templates
ts
/**
* Executes the <action> operation.
* @param input - Input payload for the operation.
* @returns The computed result.
*/
export function example(input: string): string {
return input;
}ts
/**
* Defines the shape of <domain object>.
*/
export interface Example {
id: string;
}ts
/**
* Defines the <CONSTANT_NAME> constant.
*/
export const EXAMPLE_LIMIT = 10;