Back to the blog

Naming Things So Future You Survives

Practical rules for naming variables, components, and files so a codebase stays readable months after the clever jokes fade.


Naming Things So Future You Survives

Naming is the daily tax of programming. Good names shrink the need for comments and make refactors safer. Bad names turn every file into archaeology.

Name after meaning, not after mechanics

A name should say what a value represents in the domain, not how you happened to compute it. filteredPosts is weaker than publishedPosts if the filter’s intent is publication state. data and info are almost always a stall—push one noun further.

Helpful questions:

  • What would a teammate call this in a sentence?
  • Is the boolean named for the true case (isOpen, hasError)?
  • Does the list name pluralize the item (tags, not tagList unless you need the distinction)?
  • Are units visible where they matter (timeoutMs, maxSizeBytes)?

Avoid encoding types into names (strName, arrUsers) unless you are in an untyped context where it prevents real confusion. Prefer clear nouns and let the type system—or nearby code—carry structure.

Be careful with humor and memes in identifiers. yeetUser is funny until it appears in a stack trace during an incident. Reserve personality for commit messages or UI copy if you need it; keep code vocabulary dull and precise.

Abbreviations are a tax. btn, msg, and ctx are fine in tiny scopes; as exports they force every reader to expand them. If an abbreviation is standard in your domain (url, id, html), use it consistently. If it is only standard in your head, spell it out.

Keep a small, consistent vocabulary

Projects drift when the same concept collects synonyms. If you call it a “paste” in the UI, do not call the same entity snippet, blob, and document across modules without a reason.

Build a lightweight glossary for the repo’s core nouns—even five entries help:

  • What is a Post vs a Page?
  • What is an App vs a Tool?
  • What is transient client state vs persisted settings?

Reuse those words in component names, route segments, analytics events, and test descriptions. Consistency lets people predict where code lives. PasteBin.vue beside a store field named snippetText is a tiny tax that compounds.

When you rename a concept, rename it everywhere you can in one pass—or alias briefly with a comment that the alias is temporary. Half-migrations (User in new code, Account in old) are how bugs hide in mapping layers.

Shared language also helps non-code surfaces: support replies, blog posts about the feature, and commit subjects. When everyone says “paste,” search works. When half the team says “bin entry,” you maintain a thesaurus instead of a product.

Choose names that age through change

Overly specific names go stale. fetchPostsFromBlogJson becomes a lie when the source changes. Prefer stability at the boundary (loadPosts) and keep source details inside the function body or a private helper.

Conversely, vague names rot in the other direction. Manager, Helper, Util, and Handler dump responsibilities into junk drawers. If you need a util, name the capability: formatDate, parseExportZip, clamp. Files named helpers.js attract every leftover function until nobody dares open them.

Component naming benefits from the same pressure. Prefer BlogCard over Card2. Prefer ThemeToggle over Toggle. If two components share a shape, name the difference that matters to readers—AppCard vs BlogCard—instead of numbering.

For booleans and state enums, prefer positive forms and exhaustive sets. isDisabled nested under double negatives (if (!isDisabled)) creates mental debt. status: 'idle' | 'pending' | 'error' often beats a pile of loosely related flags.

Rename early, document only what names cannot

If a name bothers you during a change, rename it while the context is fresh—especially before merging. Fear of updating imports keeps wrong names immortal. Modern editors make renames cheap; living with temp2 is expensive.

Comments should explain why, not restate the name. // get posts above getPosts() is noise. // Cloudflare Pages serves this with a trailing slash; keep paths consistent is signal. When you need a comment to decode an identifier, the identifier usually failed first.

Tests are a second naming surface. it('returns null when slug is missing') documents behavior better than it('works'). Matching domain words between implementation and tests makes failures readable in CI.

Allow short names in tiny scopes: loop indices, very local coordinates, brief callbacks. Length should scale with distance—the farther a name travels (exported APIs, shared components), the more precise it should be.

Event names and analytics keys deserve the same care. click_stuff helps no one in a dashboard three months later. Prefer stable, human phrases you would still understand without the codebase open: blog_post_share_clicked, paste_created, theme_toggled. Those strings become part of your product history—name them like it.

Wrap-up

Names that survive are meaningful, consistent, stable at boundaries, and cheap to correct. Spend a few extra seconds choosing words you would still accept in a year. Future you will not remember the joke—but they will remember whether the codebase felt navigable.