Naming Conventions skill for Codex
Names a reader can predict without opening the file. Codex names things the way the repository and the language already do, then applies precise rules: booleans read as questions, units live in the name, expensive calls are not called get, and one domain concept gets one term everywhere. Renames are classified as internal or serialized, done with the language server or a codemod, and given a compatibility path when stored data or clients depend on them.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- naming-conventions Installs to ~/.agents/skills/naming-conventions/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install naming-conventions The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project naming-conventions Installs to .agents/skills/naming-conventions/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/naming-conventions.zipunzip -o naming-conventions.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) naming-conventions PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $naming-conventions, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Names variables, functions, types, files, modules, database columns, API fields, CLI flags and environment variables consistently - following each language's idiomatic casing (PEP 8, Go, Rust, TypeScript, Java), the repo's existing vocabulary, and rules for booleans, units, collections, async functions and abbreviations - and renames safely across code, configs and serialized data. Use when asked to name something, review or fix naming, rename a symbol or file across a codebase, set naming rules in AGENTS.md or a style guide, or resolve inconsistent terms like user, account and customer meaning the same thing.
Use it when
- You need a good name for a new function, type, file or field
- Naming across the codebase is inconsistent
- A rename has to happen across code, configs and serialized data
- The team wants naming rules written into AGENTS.md or a style guide
Use something else when
- You are designing REST resource paths and payloads as a whole: use rest-api-design
- The rename touches thousands of files and needs AST tooling: use codemods
How to check the result
A search for the old name returns only intentional compatibility aliases, and build, typecheck, lint and tests pass after the rename.
The mistake it prevents
Renaming a JSON field or database column like an internal variable, silently breaking clients and stored data that still use the old name.
A name is right when a reader can predict what the thing is and does without opening it, the same concept has the same name everywhere in the codebase, and the casing matches the language and the layer it lives in. Consistency with the repo beats personal preference and beats this skill’s defaults.
Before naming anything
- Read
AGENTS.md, style guides and lint config (eslintnaming-convention rules, ruffNrules,golangci-lintrevive,.editorconfig). - Search for the concept’s existing name:
rg -n -i "customer|client|account" src | head. Reuse the term already in use; if two terms compete, ask the user which wins. - Check the domain language: names used by product, support and the database. Code should
say
invoiceif the business says invoice, notbillin one module andchargein another.
Casing by language and layer
| Context | Convention | Example |
|---|---|---|
| Python variables, functions, modules | snake_case | fetch_orders, order_service.py |
| Python classes, exceptions | PascalCase; exceptions end in Error | OrderService, PaymentDeclinedError |
| Python constants | UPPER_SNAKE_CASE | MAX_RETRIES |
| TypeScript/JS variables, functions | camelCase | fetchOrders |
| TypeScript types, interfaces, classes, React components | PascalCase, no I prefix | Order, OrderList |
| TS/JS files | Follow the repo; common: kebab-case.ts, components PascalCase.tsx | order-service.ts |
| Go exported / unexported | MixedCaps / mixedCaps; initialisms all caps | ServeHTTP, userID, parseURL |
| Go packages | short, lowercase, no underscores, not plural | orders, httputil |
| Rust | snake_case fns, vars, modules; PascalCase types and traits; SCREAMING_SNAKE_CASE consts | fn parse_line, struct LineParser |
| Java / Kotlin | camelCase members, PascalCase classes, lower.dot packages | com.acme.orders |
| SQL tables, columns | snake_case; pick plural or singular tables once and keep it | order_items.unit_price_cents |
| JSON / REST fields | Match existing API; default camelCase for JS consumers, snake_case if the API already uses it | createdAt |
| URLs and paths | lowercase kebab-case, plural collections | /v1/order-items/{id} |
| CLI flags | --kebab-case, short flags only for the most common | --dry-run, -n |
| Environment variables | UPPER_SNAKE_CASE, prefixed by app | ACME_DATABASE_URL |
| CSS classes | Follow the system in use (BEM, utility classes, CSS modules) | order-card__title |
Rules that make names predictable
| Kind | Rule | Good | Bad |
|---|---|---|---|
| Booleans | Read as a yes/no question: is, has, can, should | isActive, hasAccess | active, flag, status |
| Negation | Positive names; negate at the call site | isEnabled | isNotDisabled |
| Functions | Verb + object; side effects in the verb | sendInvoice, computeTotal | invoice, doStuff |
| Getters vs work | get is cheap and pure; expensive or remote work uses fetch, load, compute | fetchUser (HTTP) | getUser that does HTTP |
| Collections | Plural nouns; maps name both sides | orders, priceBySku | orderList, map1 |
| Counts and indices | count, index, total suffix or prefix | retryCount, pageIndex | num, n beyond tiny scopes |
| Units | Put the unit in the name when the type does not carry it | timeoutMs, priceCents, sizeBytes | timeout, price |
| Time | Instants vs durations | createdAt, expiresAt, ttlSeconds | created, expiry |
| Async | Follow the repo: either no suffix (TS default) or a consistent one | loadConfig() returning Promise | mixed loadConfigAsync and loadConfig |
| Abbreviations | Spell out unless universal (id, url, http, db) | customerAddress | custAddr |
| Scope length | Short names in tiny scopes, descriptive names in wide ones | i in a 3-line loop | i across a 60-line function |
| Generic words | Avoid data, info, manager, helper, util, handle without a noun | invoiceRenderer | InvoiceManager doing five things |
A name that needs And (validateAndSave) usually signals a function that should be two.
Files and modules
- One naming scheme per directory; check five neighbouring files before adding one.
- Name modules after what they contain (
pricing,invoice_pdf), not their layer alone (utils,common,miscgrow without bound). - Test files mirror the source file:
pricing.py->test_pricing.py,pricing.ts->pricing.test.ts,pricing.go->pricing_test.go. - Avoid names that differ only by case (
Order.tsandorder.ts): macOS and Windows default filesystems are case-insensitive and git will misbehave.
Renaming safely
Renames look trivial and break things outside the type checker’s view.
- [ ] 1. Find every occurrence in every form: camelCase, snake_case, kebab, plural, strings
- [ ] 2. Classify: internal symbol / public API / serialized (JSON, DB, events, cache keys, env, URLs)
- [ ] 3. Internal: use the IDE or language server rename, then rg for leftovers
- [ ] 4. Public or serialized: keep the old name working (alias, deprecation, dual-read)
- [ ] 5. Rename files with git mv so history follows
- [ ] 6. Build, typecheck, tests; rg again for the old name
rg -n -i "cust(omer)?_?addr(ess)?|customer-address" --hidden -g '!node_modules'
git mv src/custAddr.ts src/customer-address.ts
For mechanical renames across many files, a codemod or ast-grep rewrite is safer than
regex replacement (see codemods). For serialized names, renaming a database column, JSON
field, event type or env var is a migration: add the new name, write both, move readers,
then remove the old name in a later release. Ask the user before changing any name that
external clients, stored data or other services depend on.
Gotchas
- Text search misses dynamic access (
obj[field],getattr, reflection, ORM string fields, templates). Search strings, configs and templates too. - Renaming a Go exported identifier or a Python public function is a breaking change for library users (see semantic-versioning).
- Case-only file renames on case-insensitive filesystems need two steps:
git mv order.ts order.tmp.ts && git mv order.tmp.ts Order.ts. - Changing JSON field names in API responses breaks clients silently; contract tests or OpenAPI diffs catch it, eyes do not.
- Do not mix a broad rename with behaviour changes in one commit; reviewers cannot see the real change.
Output
When reviewing or proposing names:
| Location | Current | Proposed | Reason | Risk |
|---|---|---|---|---|
| src/billing/calc.ts:12 | `amt` | `amountCents` | unit and abbreviation | internal |
| api/orders.py:40 | `active` | `is_active` | boolean reads as question | JSON field - needs dual-write |
| (glossary) | user / account / customer | `customer` for paying orgs, `user` for logins | three terms for two concepts | discuss |
Offer to add agreed rules to AGENTS.md so future changes follow them; ask first.
Verification
rgfor the old name returns only intentional compatibility aliases and changelog lines.- Build, typecheck, lint (with naming rules if configured) and tests pass.
- Serialized renames have a compatibility path and a removal date.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Naming Conventions"
short_description: "Names a reader can predict without opening the file"
default_prompt: "$naming-conventions Review the naming in this module and suggest clearer names" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.