conventions

SKILL.md

Coding Conventions Skill

Overview

This skill centralizes general coding conventions and best practices that apply across multiple technologies and frameworks. It covers code organization, documentation, naming, and type import strategies.

Objective

Ensure consistent coding practices across the codebase regardless of technology stack. This skill delegates technology-specific conventions to their respective skills (e.g., TypeScript, React, MUI).


When to Use

Use this skill when:

  • Establishing general code organization patterns
  • Defining naming conventions across technologies
  • Setting up documentation standards
  • Creating project structure guidelines
  • Reviewing code for general best practices

Don't use this skill for:

  • Technology-specific patterns (use typescript, react, etc.)
  • Accessibility rules (use a11y skill)
  • Framework-specific conventions (use framework skill)
  • Architecture patterns (use architecture-patterns when project already uses SOLID, Clean Architecture, DDD)

Scope Rule

conventions covers what applies to ALL/MOST technologies. If a convention is specific to one technology (e.g., React hooks rules, TypeScript generics), it belongs in that technology's skill.

Skills That Build on conventions

This skill is a dependency for 40+ skills. Technology skills extend these conventions with their own specifics:

  • typescript → Adds strict typing, generics, utility types
  • react → Adds component naming, hook rules, JSX patterns
  • nodejs → Adds module patterns, error handling, async patterns
  • code-quality → Adds linting/formatting tool configuration
  • architecture-patterns → Adds layer organization, SOLID, DIP

Critical Patterns

✅ REQUIRED: Consistent Naming Conventions

// ✅ CORRECT: Proper naming by type
const userId = 123; // camelCase for variables
function getUserData() {} // camelCase for functions
class UserService {} // PascalCase for classes
const MAX_RETRY_COUNT = 3; // UPPER_SNAKE_CASE for constants

// ❌ WRONG: Inconsistent naming
const UserID = 123; // Wrong case
function GetUserData() {} // Wrong case
class userService {} // Wrong case
const maxRetryCount = 3; // Wrong case for constant

✅ REQUIRED: Group and Organize Imports

// ✅ CORRECT: Grouped imports
// External libraries
import React from "react";
import { Button } from "@mui/material";

// Internal modules
import { UserService } from "./services/UserService";
import { formatDate } from "./utils/date";

// Types
import type { User } from "./types";

// ❌ WRONG: Random import order
import type { User } from "./types";
import { formatDate } from "./utils/date";
import React from "react";
import { Button } from "@mui/material";

✅ REQUIRED: Single Responsibility Principle

// ✅ CORRECT: Each file has one clear purpose
// UserService.ts - handles user operations
// UserValidator.ts - validates user data
// UserTypes.ts - defines user types

// ❌ WRONG: Everything in one file
// utils.ts - contains validation, API calls, formatting, types...

✅ REQUIRED: Named Imports Over Namespace Imports

// ✅ CORRECT: Named imports — explicit, tree-shakeable
import { readFileSync, existsSync } from 'fs';
import { join, resolve } from 'path';
import { load, dump } from 'js-yaml';

// ❌ WRONG: Namespace import when only using a few exports
import * as fs from 'fs';
import * as path from 'path';
import * as yaml from 'js-yaml';

// ✅ EXCEPTION: Namespace import OK when using many exports (6+)
import * as p from '@clack/prompts'; // uses intro, spinner, select, multiselect, confirm, cancel, note, log, outro

✅ REQUIRED: Separate Type Imports

// ✅ CORRECT: import type for type-only imports
import { UserService } from './services/UserService';
import type { User, UserRole } from './types';

// ✅ CORRECT: Inline type import when mixing values and types
import { Installer, type Model } from '../core/installer';

// ❌ WRONG: Importing types as values (emits unnecessary JS)
import { User, UserRole } from './types';

✅ REQUIRED: No Dead Code

// ❌ WRONG: Unused variables, imports, functions
import { something } from './lib'; // never used
const unused = 42;
function neverCalled() {}

// ✅ CORRECT: Every import, variable, and function is used
import { needed } from './lib';
const count = needed();

✅ REQUIRED: No any Type

// ❌ WRONG: Disables type safety
function process(data: any) { return data.value; }
let presetInfo: any = null;

// ✅ CORRECT: Use specific types or unknown
function process(data: unknown) { /* narrow with guards */ }
let presetInfo: PresetInfo | null = null;

✅ REQUIRED: Avoid Variable Shadowing

// ❌ WRONG: inner `p` shadows outer import
import * as p from '@clack/prompts';
const result = items.find(p => p.id === selected); // shadows p

// ✅ CORRECT: Use distinct names
import * as p from '@clack/prompts';
const result = items.find(item => item.id === selected);

✅ REQUIRED: Prefer Static Imports

// ❌ WRONG: Dynamic import/require when static works
async function doWork() {
  const fs = await import('fs');   // unnecessary dynamic import
  const yaml = require('js-yaml'); // CJS require in TS
}

// ✅ CORRECT: Static import at module top
import fs from 'fs';
import { load } from 'js-yaml';

Decision Tree

Does this convention apply to ALL/MOST technologies?
→ Yes: Belongs here (conventions)
→ No: Belongs in technology-specific skill

Which concern?
  Naming (variables, functions, classes)  → See Naming section
  Import organization                     → See Imports section
  File/folder structure                   → See Code Organization
  Documentation standards                 → See Documentation
  Type imports (TypeScript)               → See Type Imports
  React-specific (hooks, JSX)             → Use react skill
  Architecture (layers, SOLID)            → Use architecture-patterns skill
  Linting/formatting tools                → Use code-quality skill

Quick reference:

  • New file? → Check naming (camelCase/PascalCase), place in appropriate directory
  • Adding imports? → Group: external → internal → types. Use import type for TS
  • Complex logic? → Comment the "why", not "what". Refactor if SRP violated
  • Naming unclear? → Descriptive names revealing intent. No custom abbreviations
  • Unused code? → Delete it. No dead code
  • Variable name conflict? → Rename to avoid shadowing
  • <6 exports? → Named imports. 6+ exports? → Namespace import OK

Edge Cases

Abbreviations: Use well-known abbreviations (HTTP, API, URL, ID) but avoid custom ones. userId is OK, usrId is not.

Acronyms in names: Treat as words: HttpService not HTTPService, apiKey not aPIKey.

File naming: Match export name: UserService.ts exports UserService, index.ts for barrel exports.

Boolean naming: Use is, has, should prefixes: isActive, hasPermission, shouldRender.

Callback naming: Use handle or on prefix: handleClick, onSubmit.


Resources

See references/README.md for complete navigation.

Related skills: typescript, code-quality, architecture-patterns

Weekly Installs
4
GitHub Stars
3
First Seen
Feb 4, 2026
Installed on
cline4
antigravity4
opencode4
mcpjam3
openhands3
zencoder3