Problem: AI Tools Use Different Naming Styles
You merged code from ChatGPT, Claude, and Copilot into one codebase. Now you have userData, user_data, and UserData all referring to the same concept, making the code confusing to maintain.
You'll learn:
- Why AI models produce inconsistent naming
- How to enforce naming conventions with ESLint
- Automated refactoring techniques for large codebases
Time: 20 min | Level: Intermediate
Why This Happens
Different AI models were trained on different code repositories with varying conventions. ChatGPT favors camelCase (JavaScript heavy training), Claude sometimes uses snake_case (Python influence), and Copilot matches your file's existing style but inconsistently.
Common symptoms:
- Same concept named 3+ different ways in one file
findUser()butget_order()in the same class- PR reviews flagging style inconsistencies
- Developers unsure which convention to follow
Solution
Step 1: Audit Your Naming Patterns
# Find all variable naming patterns
grep -rE "(let|const|var|function) [a-zA-Z_]+" src/ | \
sed 's/.*\(let\|const\|var\|function\) \([a-zA-Z_][a-zA-Z0-9_]*\).*/\2/' | \
sort | uniq -c | sort -rn > naming-audit.txt
Expected: A sorted list showing your most common patterns. Look for duplicates like userData (23 times) and user_data (17 times).
Step 2: Set Up ESLint Naming Rules
npm install --save-dev eslint @typescript-eslint/eslint-plugin
Create .eslintrc.json:
{
"extends": ["eslint:recommended"],
"rules": {
"camelcase": ["error", {
"properties": "always",
"ignoreDestructuring": false,
"ignoreImports": false
}],
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"],
"leadingUnderscore": "allow"
},
{
"selector": "function",
"format": ["camelCase"]
},
{
"selector": "typeLike",
"format": ["PascalCase"]
}
]
}
}
Why this works: Enforces camelCase for variables/functions (JavaScript standard), PascalCase for types, and allows UPPER_CASE for constants. This catches new violations in PRs.
Step 3: Automated Refactoring for Existing Code
# Install refactoring tools
npm install --save-dev jscodeshift @codemod/cli
Create fix-naming.codemod.js:
// Converts snake_case to camelCase for variables
module.exports = function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);
// Convert variable declarations
root.find(j.VariableDeclarator)
.forEach(path => {
const name = path.value.id.name;
if (name.includes('_') && name !== name.toUpperCase()) {
// user_data → userData
const camelName = name.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
// Rename all references in scope
j(path)
.closestScope()
.find(j.Identifier, { name: name })
.forEach(identPath => {
identPath.value.name = camelName;
});
}
});
return root.toSource();
};
Run the codemod:
npx jscodeshift -t fix-naming.codemod.js src/
Expected: Transforms user_data → userData, api_key → apiKey across all files.
If it fails:
- Error: "Cannot read property 'name'": Some variables use destructuring. Add destructuring pattern handling.
- Breaks tests: Constants like
API_KEYshould stay uppercase. Update codemod to skip UPPER_CASE.
Step 4: Create Pre-Commit Hook
# Install husky for git hooks
npx husky init
Add to .husky/pre-commit:
#!/bin/sh
npx eslint --fix src/
git add -u
Why this works: Automatically fixes naming violations before commits reach your main branch. Prevents new AI-generated code from introducing inconsistencies.
Verification
# Run linter
npx eslint src/
# Check for remaining snake_case
grep -r "[a-z]_[a-z]" src/ --include="*.js" --include="*.ts"
You should see: Zero ESLint errors, no snake_case in grep results (except in strings/comments).
What You Learned
- AI models inherit naming styles from their training data
- ESLint enforces conventions for new code, codemods fix existing code
- Pre-commit hooks prevent regressions
Limitation: This doesn't catch naming logic issues (like handleSubmit() doing validation). Review AI code for semantic correctness separately.
Bonus: Naming Convention Quick Reference
// ✅ JavaScript/TypeScript Standard
const userData = {}; // camelCase for variables
function fetchUser() {} // camelCase for functions
class UserService {} // PascalCase for classes
const API_KEY = "secret"; // UPPER_CASE for constants
interface UserData {} // PascalCase for types
// ⌠Avoid mixing
const user_data = {}; // snake_case (Python style)
function FetchUser() {} // PascalCase functions (Go style)
const apiKey = "secret"; // Constant not uppercase
When to deviate:
- External APIs using snake_case (keep as-is, convert at boundary)
- Database column names (match schema, use ORMs to map)
- Environment variables (always UPPER_CASE)
Tested with ESLint 9.x, jscodeshift 17.x, Node.js 22.x, TypeScript 5.5+