Few professions rival programming when it comes to the frequency at which we are tasked with naming things. We name things so often that it is common for the prevailing sentiment within a team to devolve into something like “naming things is hard, so just pick something and move on”. I reject this.
Naming things is hard because it is important. Our packages / classes / functions / methods / variables / etc become the API of our shared tool belt. Good names keep our work shop orderly, and help us catalog which resources we have at our disposal.
My favorite engineers to work with are the ones that strike a mythical balance of context, conventions, style, and humor in their naming of things. They understand that authoring code gives them the very special power of controlling what flows from their colleagues fingertips (sort of like the kids book my son enjoys, where the characters figure out that they can get the “reader” to say whatever they want).
This is an intimate power. The “language” of our codebase changes how we reason about the code we write. The same way that the language we use in society shapes our collective thinking about issues.
That said, here is a list of attributes that I think are common to well named things.
They are “SEO” friendly
They lean into convention
They prefer terseness without sacrificing meaning
They are considerate of collisions
They are guessable
They make you smile from time to time
I’ll expound on these below.
“SEO” Friendly
Big code bases, with lots of contributors get searched. Most engineers, especially in established projects, will default to using what’s there already. Common tasks like authentication, authorization, error handling, logging, etc should have very obvious and highly searchable names. For example, “auth.DecodeJWT(…)” would be a solid name for a function in the “auth” package that handles the decoding of JWTs. Whereas “helpers.Validate(jwt)” misses the mark.
Leaning Into Convention
Good convention is really powerful and might be the highest leverage tactic for naming things. I’ve worked in a big mono-repo that adopted a fun convention of adding an “-y” suffix to core utility libraries. Think “stringy” for string helper functions, “timey” for date/time stuff, or “randy” for… you guessed it, randomness utils.
This had a few benefits:
It made naming new packages a non-thought
It increased readability, as util funcs were name-spaced with the obvious convention
Utility code discovery was easy, just look for the appropriate “-y” lib
Gaps in utilities were obvious (no “-y” for the category you wanted? time to add one!)
Terse, but Meaningful
Long names are well intentioned, but often un-helpful. For example, if you are making a SaaS app for veterinary clinics, you probably don’t want a bunch of functions like:
“CreateNewVeterinarian”
“DeleteVeterinarian”
“UpdateVeterinarianContactDetails”
These convey plenty of meaning, but there is a lot of extra over-head when it comes to typing and line length that we can 86. The better way would be:
“CreateVet”
“DeleteVet”
“UpdateVetContact”
That’s easier on the eyes, the fingers, and the line wrap :)
Considerate of Collisions
Names should lend themselves to being considerate of their caller’s context. For example, maybe you have a database library that exposes a “reset” function. If the reset function is always chained to the package name, or a method on some other class/structure, than I’ve got no beef. But, if it’s a stand alone function call, like in this pseudo javascript code…
Inconsiderate Version 😿
import { reset } from '../lib/db'
const cool = () => {
reset()
}
This is inconsiderate. The “reset” call on it’s own gives no hint that it’s related to the db, and once our “cool” function does some more work, this code will be harder to read and eventually might even run into a collision scenario where there is some more locally scoped “reset” logic that we want to run. Yikes!
Considerate Version 😎
import { resetStore } from '../lib/db'
const cool = () => {
resetStore()
}
This is a considerate function name. No matter how verbose the “cool” function gets, we know that “resetStore” is resetting a data store, not something else.
Guessable
The best names are guessable. Convention helps a lot here, but also, so does logical code division and function implementation.
Let’s consider a “User” class with a handful of methods that send various emails to the user. You want your code to look something like:
// this is cool ✅
user.SendPasswordResetEmail()
user.SendVerificationEmail()
user.SendNewDeviceEmail()
vs
// not so much ❌
user.SendPasswordResetEmail()
user.Verify()
user.NotifyForNewDevice()
The problem here is not the method names themselves, but the fact that they are wildly inconsistent.
Smile!
Remember, our code gets compiled and interpreted by computers, but it gets read by other programmers. With that in mind, you should inject some sunshine into your naming when appropriate.
I once wrote a method for presenting a “Toast” in a web UI called “xplode”. Calling
const toast = new Toast()
toast.xplode()
Would render the toast in it’s “something went very wrong and we have no better options” state.
This name doesn’t exactly follow the guard rails I’ve laid out… it’s not very SEO friendly, doesn’t follow any hard conventions, and yet… it somehow fits the bill, and stuck in the minds of the team. It had some soul, and described what it did poignantly.