Naming Things: The Rule That Saves Codebases
There are two hard things in computer science. This post is about one of them: naming things, with rules you can apply tomorrow.
Why Names Matter More Than They Should
The most-quoted line in programming is Phil Karlton's: There are only two hard things in Computer Science: cache invalidation and naming things. It is quoted constantly because it is true. Most code I review for beginners would be 50 percent more readable with no logic changes - only better names.
Names matter because they communicate intent. Code is read 10x more than it is written. Every confusing name is a tax paid every time someone reads that line.
Rule 1: Length Should Match Scope
A loop variable used for three lines can be i. A function parameter passed to ten functions should be userEmail. The longer the variable lives and the further it travels, the more descriptive its name needs to be.
This is why for (let i = 0; i < n; i++) is fine but let i = 5 at module top is a smell.
Rule 2: Verbs for Functions, Nouns for Data
users is a noun - appropriate for an array. getUsers() is a verb phrase - appropriate for a function. users() as a function name confuses readers.
Functions returning booleans should usually start with is, has, or can: isAdmin(user), hasPermission(user), canAccess(user, doc).
Rule 3: Avoid the Word Data
data, info, thing, obj, item - these are content-free words. Replacing them with the actual concept they represent makes code self-documenting.
Bad: processData(data). Better: computeMonthlyReport(transactions). The reader of the second version knows what it does without scrolling.
Rule 4: Match Domain Vocabulary
If your business calls them customers, call them customers in code, not users. If accountants call them line items, use that, not products. Code that matches business vocabulary closes the gap between conversations and code.
Rule 5: Use a Convention Consistently
JavaScript uses camelCase. Python uses snake_case. Java uses camelCase. Mixing styles within one codebase looks unprofessional.
Constants in any language use UPPER_SNAKE_CASE. Class names use PascalCase. Pick one and obey it.
Rule 6: Rename Boldly
Beginners are afraid to rename variables. They should not be. Modern editors do safe rename across an entire project in one keystroke (F2 in VS Code). When you find a better name, use it. The 30 seconds saves hours of confusion.
Exception: variable names in public APIs, URLs, or stored data. Those have external dependencies and need a deprecation cycle.
Before-and-After
// BEFORE
function proc(d) {
let r = 0;
for (let i = 0; i < d.length; i++) r += d[i].x * d[i].y;
return r;
}
// AFTER (no logic changes)
function totalRevenue(orders) {
let revenue = 0;
for (const order of orders) revenue += order.price * order.quantity;
return revenue;
}Same code, vastly different cost.
Where to Practice
The variables concept page covers the mechanical rules. The functions concept page covers naming for callables. Robert Martin's Clean Code chapter on names is the canonical reference.
Naming Patterns Worth Stealing
Conventions that show up across well-named codebases:
- Time units in variable names.
timeoutMsis clearer thantimeout.delaySecondsbeatsdelay. The reader never has to guess the unit. - Plural for collections.
usersfor an array,userfor one. Mixing them is a fast way to introduce bugs. - Prefix booleans with is/has/should.
isLoading,hasErrors,shouldRetry. The prefix removes ambiguity at the call site. - Suffix counts with Count.
userCountis clearly a number;usersis a collection. Each tells the reader what to expect. - onClick / handleClick for event handlers.
onClickis the prop you pass;handleClickis the function you write. Both signal handler at a glance.
Naming Files and Folders
The same rules apply at the file level. Three patterns I have seen consistently across well-organized projects:
- Group by feature, not by file type. A folder called
users/with components, hooks, helpers, and tests beats four folders calledcomponents/,hooks/, etc. - Match filename to default export.
UserProfile.jsxexportsUserProfile.useFetchUser.tsexportsuseFetchUser. Predictability over cleverness. - Avoid generic names like
utils.jsorhelpers.js. They become dumping grounds. Be specific:dateFormatting.js,currencyHelpers.js.
Reading on the Topic
If naming interests you (and it should), three references that go deep:
- Robert Martin, "Clean Code" - chapter 2 is the canonical naming guide for the industry.
- Google's JavaScript style guide on naming.
- PEP 8 for Python's official naming conventions.
For the related topic of code that reads well as a whole (not just at the variable level), see how to read other peoples code.
Frequently Asked Questions
Are abbreviations ever OK?
Established ones, yes. id, url, html, db are universally understood. Domain-specific abbreviations (usr, cnt, tx) usually are not - spell them out.
Should comments compensate for bad names?
No. Rename the variable. A good name removes the need for the comment. Comments should explain why, never what.
What about Hungarian notation?
Largely obsolete. Modern languages, IDEs, and types do the work that prefixes used to. The exception: prefixing booleans with is/has/should is still useful.
How long is too long for a name?
About four words. userEmailAddress is fine; currentlyAuthenticatedUserEmailAddress is too long. If a name needs five words, the function or class is probably doing too much.
The One-Line Summary
Names are how code communicates intent. Length should match scope, verbs are for functions, nouns are for data, the word "data" itself is almost always wrong, match domain vocabulary, and rename boldly. Apply those six rules consistently and your codebase becomes 50 percent more readable with no logic changes.
For the other half of "code that reads well," see our post on how to read other peoples code. Half of writing readable code is reading lots of it first.