Skip to content

Naming

Every name is read at its call sites by people who will never open the file where it was chosen. It is the one piece of documentation nobody can skip, and its cost falls on every reader for as long as the identifier exists, while the cost of choosing it well falls once, on one person, on an afternoon nobody will remember. Almost no rule below is checked by a tool. The reader is the check here, so run the sieve before the name reaches a file.

Run a candidate through these in order. The first failure sends the name back.

  • Does the field already have a term for this thing? Use that term. Never invent vocabulary.
  • Among the established terms, is this the plainest one? Esoteric terms of art are out even when they are correct.
  • Does the word come from a dependency? Then keep it exactly as the dependency spells it.
  • Is it a function? Then it starts with a verb.
  • Is every word spelled in full, free of units, free of qualifier tails?
  • Would a reader who has never opened this file guess what the value holds?

An invented word has to be learned before it can be used, and it teaches nothing once learned, because it leads nowhere. But a borrowed one arrives already explained, with documentation behind it that somebody else wrote and somebody else maintains. So a name here comes from the standards of the field the thing belongs to, and finding it costs one search.

Process lifecycle is the clearest case. POSIX is where a process terminates and a signal asks it to, so termination is the word and kill stays only where it is the literal platform call. Kubernetes calls emptying a node kubectl drain and calls the wind-down of a workload pod termination, which settles drain as well. Load accounting borrows from load balancers, so a worker has load and capacity, and work is started, settled or dropped. Whatever waits to take a message off a channel is a receiver. So PendingReceive was rejected as an invention for a thing that already had a name.

Among established terms, take the most ordinary one. oracle and parity are the standing counter-examples: both are real terms of art. But both were rejected, because the plain word reaches more people and the term of art costs everyone else a lookup.

Metaphors borrowed from another domain are out entirely, whether that is economics for durations, hydraulics for schedulers or embedded-systems vocabulary anywhere near a supervisor. A metaphor is legible only to a reader who already knows what it stands for, and that reader never needed the name.

When a name is contested, do not guess twice. Gather the candidates the field already offers, then pick the one whose source you can name.

Those rules govern the words this repository coins. But none of them has any authority over a word that arrived from somewhere else. isolate stays because isolated-vm and V8 name it so. RpcStub stays because capnweb names it so. A protocol value spelled stub on the wire stays because the wire contract says so. Rename a borrowed word and you cut the reader’s path back to the documentation that would have answered their question.

A function performs an action, so its name opens with the verb for that action: createIsolate, decodeDispatchValue, installDispatch. Names built on Of are banned everywhere, and messageOf is the counter-example: it reads as a noun, so the call site never says that work is about to happen.

A step too small to justify a name gets no name at all. Inline it into its caller instead of dressing it in a verb.

Never abbreviate. Write options, never opts. The full word is read once and understood, and the saved characters buy nothing that anyone can point at.

No identifier carries its unit. Write timeout, not timeoutMs; memory, not memoryBytes. A unit in a name couples every consumer to that unit, so the day bytes become kilobytes the rename runs through the whole tree, and whatever the rename missed still compiles while meaning something else entirely. Names state what the value is; the platform and the documentation carry the unit. Where a name expresses arithmetic, it states that arithmetic in its own domain. So totalTimeout is the timeout plus the grace period.

A name carries no glued qualifier suffix, neither a Flag tail nor a ForTesting tail. Assert functions state the condition itself, so assertNoNodeSnapshot is already complete, and the Flag tail would only name the mechanism the condition happens to travel on.

Privacy lives in TypeScript’s private modifier and nowhere else. Class members carry no sigil. # moves the rule down into the runtime, where no rule here needs it enforced, and _ says nothing the type system has not already said. The lint lane rejects a leading _.

Test vocabulary stays out of production identifiers

Section titled “Test vocabulary stays out of production identifiers”

stub, fixture and failpoint name testing mechanics. Production identifiers wearing one of them describe the harness and not the thing, and the next reader goes looking for a test that does not exist. Name the role instead: the dispatch, the outbound function, the receiver. A class never stores a test flag and never names one; the repository has a single helper that answers whether the current process is a test environment, and Testing owns that mechanism.

Values passed through a call keep their name on both sides, so that grepping one name finds the whole path. Only a derived value earns a new name, and the new name says what the derivation produced.

Inside the layer that owns a mechanism, the mechanism is named for its purpose. Only an outward-facing seam takes a domain-fact name, because a producer names the seam after the fact it emits and never after one subscriber’s use for it. Name it after the subscriber and the second subscriber arrives under a name that lies about them.

Project and package names say what is under test or what is served. executor-testbed names its subject; conformance names a ritual and leaves the subject unsaid. An npm alias glues the version straight onto the name without a hyphen, following npm’s own alias pattern: codemode0.3.

Every row here is a decision the sieve has already produced, written down so nobody has the same argument twice.

Avoid Write Why
opts options No abbreviations.
timeoutMs, memoryBytes, memoryLimitMb timeout, memory, memoryLimit The unit belongs to the platform and the documentation.
rss memory Reads as web feeds first; the platform call site keeps its name.
budget for a duration totalTimeout States the arithmetic in the time domain.
oracle, parity the ordinary word for the thing Correct terms of art, still the harder read.
inflight running The plain word for work that is executing.
arm, re-arm, armed schedule, set, pending The vocabulary of the setTimeout family, which sets a timer and schedules a callback.
watchdog, recycle, kill lifecycle, retire, drain, termination Process lifecycle standards; child.kill stays as the platform call.
SlotTable, acquire, release, forget WorkerLoad, hasCapacity, start, settle, drop Load-balancer vocabulary; nothing hands out a permit here.
waiter, PendingReceive the noun the field already uses, such as Receiver Invented and metaphorical names for a concept that has one.
messageOf, any noun-first function name verb-first names such as decodeDispatchValue A function performs an action.
deliver for a trivial private step no name; inline the step Too small to justify a name.
assertNoNodeSnapshotFlag assertNoNodeSnapshot An assert name states the condition itself.
any ForTesting or Flag tail the plain name Qualifier tails decorate instead of naming.
ad-hoc checks around a complex invariant an assertXXX function naming the condition Not for trivial checks; complex invariants earn a name.
stub in this repository’s identifiers the role word, such as dispatch or outbound function Library and wire vocabulary keep their own spelling.
#field, _field the private modifier Privacy lives in the type system.
telemetry, any consumer-named seam hooks with lifecycle names such as onExecutionSettled A producer names seams after the facts it emits.
codemode-0-3 codemode0.3 npm’s own alias pattern joins the version directly.
conformance in a project name what is under test, such as executor-testbed Say the subject, not the ritual.
.test.ts .spec.ts The single test-file suffix every config recognizes.