code-naming
Skill3 starsChanged 3 months agoMITView on GitHub
Use when naming or renaming TypeScript code: an export, a public API or barrel file, a type, an API request or response type, a function, a variable, a boolean flag, a result field, a constant, or a file. Also use when asked to propose better names, or when a proposed rename only adds a word to the old name.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- smileynet/code-spicetheir own version, first seen Oct 13, 2026
- keitakn/engineering-skillstheir own version, first seen Oct 8, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- keitakn/engineering-skills★ 14same name
- smileynet/code-spice★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository9 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agentfolio-operatorSkill
- branch-portSkill
- code-commentsSkill
- cognitive-refactorSkill
- memory-palaceSkill
- natural-copy-editingSkill
- testing-business-rulesSkill
- thorough-pr-reviewSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 11 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 18
If you need two sentences, the code answers two questions.
- Very specific: line 20
Write the line where the name is read.
- Distinctive: line 29
Search the codebase for each word.
- Distinctive: line 30
Use one word for one idea.
- Very specific: line 31
Prefer the word a person sees in the product to the word for the mechanism: "wait time", not "cooldown".
- Distinctive: line 53
Put these in the name:
- Distinctive: line 67
When you cannot decide whether a fact is missing, choose the longer name.
- Very specific: line 75
When the code decides a label that the product shows, such as a status or an outcome, use that label's word.
- Distinctive: line 87
Read every caller before you name an export.
- Very specific: line 88
Put the complete action in the name.
- Very specific: line 91
Use one verb for one operation across the module.
- Very specific: line 92
When a convention or a lint rule fixes an entrance file name (index.ts, client.ts), keep the name.
- Distinctive: line 93
Before you export a new name, show the user the name at its call site.
- Distinctive: line 114
Follow the case style the project uses for file names.
- Very specific: line 124
Write an acronym as one word: loadHttpUrl, parseJsonBody.
- Distinctive: line 125
Do not use an abbreviation a reader outside the project would not know.
- Distinctive: line 133
When the double meaning comes from a table or type you can still rename, propose that rename.
- Distinctive: line 161
Every caller calls one export right after another export.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Code Naming
A name is read in imports, calls, conditions, and log lines. The definition, the file path, and the comment are not there. The name alone must tell the reader what they need to know at that line.
A good name is clear: the reader knows what it refers to. It is also precise: the reader knows what it does not refer to. It is long enough to say both at the place it is read, and no longer.
Find a name
- Describe the thing in one sentence, using the product's words. Include what it is or does, who did it, and what it is compared against, but only the parts the reader acts on.
Example: "Someone other than this call signed in and saved this session."
- The sentence says what happens, not how. How the code decides, and which items it picks today, go in a comment. See
code-comments. - If you need two sentences, the code answers two questions. Split it before you name it. The sign: a result with two fields, and a parameter that only one of them uses.
- Two steps of one action still fit in one sentence:
signInAndSaveSession.
- The sentence says what happens, not how. How the code decides, and which items it picks today, go in a comment. See
- Write the line where the name is read. For an export, write the call without the import path. For a field, write it after its container. For a boolean, write the
if. Example: a function returns a signed-in session, and we are naming its boolean field:const session = await getSignedInSession(login) if (session.___) - Compare the sentence with the line. Whatever the sentence says that the line doesn't is what the name has to add.
Example:
sessionalready covers "this session". What's still missing is "saved by someone other than this call", so the field issavedByOtherActor. - Look for words the product or the codebase already uses: a UI label, a type, a union member, a reason code, a log line, a CLI flag, a README. A reader recognizes those and can search for them. A new word is fine when none of them fits.
- Search the codebase for each word. If it already names a different thing, pick another word, even for a verb. See "Words that mean two things".
- Use one word for one idea. If the module says "result", do not name the same thing "read".
- Prefer the word a person sees in the product to the word for the mechanism: "wait time", not "cooldown". A library term is the last choice:
hasUnsavedChanges, notisDirty.
Example
Naming the boolean field on a payer login that says the payer suspended it.
Sentence: "The payer suspended this login."
Line: if (login.___)
| Candidate | Fails because |
active | It is true for the usual case, so the caller writes if (!login.active). Make the flag true for the case the caller branches on. |
loginSuspended | It repeats the container. |
blocked | It coins a word where the codebase already says "suspended". |
suspendedByAvaility | It is narrower than the fact. It ties a field that every payer's login has to one payer. |
suspended | It leaves out who, when our own code can also suspend a login. |
suspendedByPayer | Passes. |
What a name carries
A name carries each fact the reader needs at the place it is read, and only those facts.
Put these in the name:
- what the function returns, or what the type or flag is
- a side effect the caller has to know about, when the verb doesn't already say it. A caller has to know when the effect changes what it can safely do: call twice, retry, skip in a dry run, run in a request.
signIn()hides that it saves a session, so the name issignInAndSaveSession().deleteLogin()already says it deletes, so it needs nothing more. - the source or the target, when the place of use does not show it
Leave these out:
- what the place of use already says: the container, the parameter type, the module, the file path
- the rule that picks the items today, the order, and the edge cases. Name the role of the result. The comment holds the rule.
- the mechanism: the library call, the SQL clause, the data structure
- the type:
holidays, notholidayDateList. A unit is not a type:timeoutMs,widthInPixels. - effects only the function cares about: logging, metrics, a cache it fills and reads itself.
When you cannot decide whether a fact is missing, choose the longer name. A name that is too long costs one line. A name that misses a fact costs each reader a trip into the body.
| Name | Problem | Better |
loadOpenUnpaidClaimsOlderThan30Days | It spells out today's filter. The name goes false when the filter changes. | loadClaimsToFollowUp |
hasPostedAtSet(payment) | It names the column the code reads. The page says "Posted". | isPosted(payment) |
signIn() | It hides that it writes a session. | signInAndSaveSession() |
When the code decides a label that the product shows, such as a status or an outcome, use that label's word. Do not add how the code decides it. If the page shows "Posted", the function is isPosted.
Length follows scope
- An export, a type, or a field is read far from its definition. Its name carries every fact from "What a name carries".
- A local can be short when the reader sees where it is set and every use on one screen:
rowin a five-line loop,errin acatch. - A local in a long function, or one used far from where it is set, is read like a field. Name it in full:
signedInSession, notresult.
Exports
The exports of a module are its API contract. A reader of the call site must understand what an export does and returns without opening it.
- Read every caller before you name an export. If every caller calls the same exports in the same order, they are one operation. Export one function that returns one result. A query on that result becomes a field of it:
isExpired(session)becomessession.expired. - Put the complete action in the name. Stack verbs and objects when one verb is not enough:
lookUpAndStoreClaimStatuses. - Do not shorten a name by removing a fact: the service, the product, the source, the target, the side effect. Do not remove a word because an argument at one call site repeats it. Imports, stack traces, and other call sites do not show that argument.
- Count facts, not words. A word from the file path or the parameter type adds no fact. For each rename, write the question the new name answers that the old name left open. If you cannot write it, the rename failed.
- Use one verb for one operation across the module. Do not use
load,fetch, andgetfor the same operation. When the module already uses a verb for this operation, keep that verb and change only the facts after it:loadFailedRunCountSincebesideloadRunStats, notcountFailedRunsSince. - When a convention or a lint rule fixes an entrance file name (
index.ts,client.ts), keep the name. State what the file guarantees in its header comment. - Before you export a new name, show the user the name at its call site. Offer alternatives when the first name needs a comment to be understood.
| Name | At the call site | Problem | Better |
checkClaims(claims) | const result = await checkClaims(claims) | Checks what, against what, and returns what? | lookUpClaimStatusForClaims(claims) |
isUnchanged(diff) | if (isUnchanged(diff)) | Unchanged against what? Every caller calls it right after the diff. | A field of the diff result: diff.matchesCheckedIn |
Types and fields
- A type is named by what it is.
- A type's plurality matches what one instance holds.
CignaWatchlistItemsToExpiredescribed one item. The plural read as a list. - A field completes its container and does not repeat it:
session.savedByOtherActor, notsession.sessionSavedByOtherActor. - The fields of a write type are the actions the write does:
fulfill,expire.fulfillmentnames a record, not an action. - Name the types of one API endpoint
<name>Requestand<name>Response. The request is what we send. The response is what the other system answers. Use this pair for every endpoint in the module. Do not mix inParams,Input,Result, or a bare name. - A prefix such as the service name goes on every type of the module, or on none. Follow what the module already does.
- A constant is named by its role, not its value:
MAX_LOOKUPS_PER_STEP, notTEN. It uses the format word the codebase already uses. An expired reason is<code>: <detail>, so the constant isREREAD_CAP_EXPIRED_REASON_CODE, notREREAD_CAP_REASON_PREFIX.
Files
- A file name says what the file holds. Use the word a person searches for: the product's or the page's word.
- A file that wraps an external endpoint keeps the endpoint's word and adds the product word in front. The Stripe transfers endpoint behind the Payouts page is
payouts-transfers.ts. - Follow the case style the project uses for file names.
Functions by role
- A function is named by what it does, not by when it runs.
handleUploadandonSyncname the trigger. Name the effect:storeFileAndQueueVirusScan. - In React, a component's event handler keeps the convention: the prop is
onSubmit, and the local function ishandleSubmit. - A boolean is true for the case the caller branches on, so the caller never writes
!flag.
Spelling
- Write an acronym as one word:
loadHttpUrl,parseJsonBody. Keep the platform's spelling only when an API requires it:XMLHttpRequest. - Do not use an abbreviation a reader outside the project would not know. Do not drop letters from a word.
- These words name no fact. Do not use them as a name or as the noun of a name:
data,info,item,entry,result,value,state,evidence,manager,helper,util,process,handle. Use what the thing is.
Words that mean two things
- List the words that mean two things in the module. Example: "claim" is the payer's printed entry on an EOP and also our submitted claim record. "Sync" can be the act of syncing and also a stored sync record.
- Whichever meaning the codebase already uses on its own keeps the plain word, like
claimIdfor our claim. The other meaning always gets its owner in front:eopClaimRow,derivedEopClaims. When the two meanings are a noun and a verb, avoid the word in new names altogether. If "sync" already names a stored record, a new function shouldn't "sync" anything. It "copies" or "pulls" instead. Older names can keep the word until someone gets around to renaming them. - When the double meaning comes from a table or type you can still rename, propose that rename. Every name built on it inherits the confusion.
- A name for a relation names both ends and puts a word between them:
EopToClaimMatch,linksFromDocumentToRecord,rowsPayingClaim. Read the name as one compound noun.EopClaimMatchreads as "(EOP claim) match", so it fails.EopToClaimMatchcannot be read that way, so it passes.
A field inside the type cannot repair the type's name. The name appears without its fields in imports and signatures.
Rationalizations
| Excuse | Reality |
| "The longer name is more exact" | Count facts. A filter, an order, or a mechanism in the name is a fact for the comment. |
| "The name must say how it decides" | The caller needs what it decides. The comment says how. |
| "The argument at the call site already says it" | Imports, stack traces, and other call sites do not show the argument. |
| "The current name is fine, keep it" | Write the sentence from step 1. If the call does not say all of it, the name is not fine. |
| "The current name is the product's word" | Keep it. If it misses a fact, flag that to the user. |
| "The comment explains the flag" | The if and the log line do not show the comment. |
| "A new word is clearer than the codebase's word" | A reader cannot search for a word only your name uses. |
Red flags
- A word in the name appears nowhere else in the codebase or the product.
- A word in the name already names a different thing in the module, as a verb or as a noun.
- The name lists a filter, an order, a condition, or a constant value:
WithoutInvoiceYet,SortedByDueDate,OlderThan30Days,retryThreeTimes. - The name uses a library or database term where the product has a word.
- The rename keeps the verb and adds a noun from the file path or the type.
- The rename is shorter because it removed the service, the product, the source, or the target.
- The caller reads a boolean as
!flag. - A field name repeats what its container already says.
- A short local name used across a long function.
- Every caller calls one export right after another export.
- A relation name reads as one compound noun.
- A plural type name whose fields describe one instance.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

