CUPID

An assessment of CUPID: the five properties tested against the assessment requirement their author set, and against the standards that define engineering.

CUPID is a set of five software properties — Composable, Unix philosophy, Predictable, Idiomatic, Domain-based — proposed by Dan Terhorst-North in 2022 as an alternative to SOLID [1], in the line of earlier critiques of that set [2], [3], [4], [5]. He frames them not as principles but as properties: qualities of code that a team moves towards [1]. Principles, he argues, are rule-like — you are either compliant or you are not — and produce bounded sets of rule-followers; properties instead define a centre, so that code is only closer to or further from it, with a clear direction of travel [1].

He states three criteria a property should meet: it should be practical (easy to articulate, assess, and adopt), human (read from the perspective of people, not code), and layered (obvious by name, deep in use) [1]. The assessment requirement is the sharpest: a reviewer should be able to easily decide how much of the property the code exhibits [1].

This page tests the five properties against that requirement, and then against two standards the criteria do not include — grounding in a theory or a model, and falsifiability.

1 At a glance

The glosses and the assessments below are read off the essay [1].

Property Gloss Meets the assessment requirement?
Composable “plays well with others” No: no measure of the centre
Unix philosophy “does one thing well” No: no test for “one purpose”
Predictable “does what you expect” Partial: sub-properties only
Idiomatic “feels natural” Conditional: needs an external standard
Domain-based “the solution domain models the problem domain” No: no criterion

2 Composable

Composable is developed through three characteristics — a small surface area, intention-revealing naming, and minimal dependencies — under a governing statement: the characteristics “are neither necessary nor sufficient to make any guarantees”, and “more is not necessarily better; it is all trade-offs”, with a “sweet spot” between fragmented and bloated [1].

That caution is not, on its own, what makes the property hard to assess. A characteristic can be neither necessary nor sufficient and still support a graded comparison, provided the characteristics share an axis on which to order them. What blocks the comparison is that no such axis is supplied. “More is not necessarily better” denies that more of a characteristic means more of the property; the sweet spot is named but not measured; and the characteristics pull against one another, so improving one can worsen another. With no measure of the centre, a reviewer cannot decide how much of the property a component exhibits.

3 Unix philosophy

The Unix philosophy is glossed as “does one thing well”, grounded in the Unix tool tradition [1]. Its criterion is “a specific, well-defined, and comprehensive purpose”, and each adjective demands the judgment it is meant to guide. “Specific” and “well-defined” restate the goal — a clear boundary — without a test for when the boundary is clear. “Comprehensive” requires the purpose to be broad enough to be complete yet narrow enough to remain one, with no way to tell when it is broad enough. The example illustrates a design judgment and supplies no test: a designer who kept two tools together would still satisfy the criterion. The property therefore gives no rule for when a purpose counts as one and comprehensive enough.

4 Predictable

Predictable is glossed as “does what you expect”, with three sub-properties: it should behave as expected, be deterministic, and be observable [1].

Determinism and observability can be assessed against a specification the reviewer states from the component itself — determinism against its functional bounds, observability against a stated output-and-state specification. The headline sub-property is different. “Behaves as expected” is relative to an observer the essay does not fix: obviousness is held by a reader, and readers differ. Its own example — confidence in a low-coverage trading codebase — reports a judgment, not a measure, and credits two properties at once [1]. Predictable is therefore assessable in its deterministic and observable sub-properties, but not in its headline gloss.

5 Idiomatic

Idiomatic is glossed as “feels natural”, defined against a target audience: an experienced programmer fluent in the language, its libraries, its toolchain, and its ecosystem [1].

How much a reviewer can assess depends on the language. Some languages have strong opinions about how code should look, and a canonical formatter settles syntactic quirks — though idioms reach further than the language definition. Others are deliberately multi-paradigm, where it is left to the team to decide what good looks like [1]. The standard comes from a language community, a tool, or the team, never from CUPID, which supplies the name and the observation that consistency matters but no standard against which idiomaticness is judged.

6 Domain-based

Domain-based is glossed as “the solution domain models the problem domain in language and structure”, with three parts: language, structure, and boundaries [1].

The advice is actionable: grouping a design by use case rather than by technical type, because type-grouping scatters a change across the codebase [1]. Whether the property lets a reviewer decide how much of it the code exhibits is a narrower question, and it is not answered. All three parts take “the domain” as given: identifying it, and deciding where its parts divide, is the hard problem, and no criterion is given for it. The worked example names several areas but no rule for finding them; a different designer could name others. The level of boundary is likewise left to the judgment the property is meant to guide, and the success criterion — that a casual observer cannot tell whether people are discussing the code or the domain — describes an outcome, not a test [1].

7 The set against its own criteria

The articulation leg of the practical criterion is met: each property is stated in a sentence, with examples and counterexamples [1]. The human criterion is met: the five names are chosen for the perspective of people, not code. The assessment leg is not met for the property as a whole, and the adoption leg does not compensate — a direction whose centre the property does not locate is easy to adopt for the same reason it is hard to assess.

The layered criterion holds in form only. The depth is real, but it is the same content whose assessment fails, so it adds no independent support.

Terhorst-North makes two remarks about how the properties combine: that everything is a trade-off, so context should always be considered; and that the properties are mutually reinforcing [1]. Both can hold, but the essay does not join them, and states no procedure for the case the first describes — two properties pulling in opposite directions on the same code.

What the analysis leaves is a vocabulary and a stance: memorable names for outcomes practitioners value, and guidance as a centre to move towards, with no gate to pass. None of the five properties meets the assessment requirement as a whole.

8 Beyond the author’s criteria

The assessment above used Terhorst-North’s criteria, and is confined to them. That method cannot place CUPID against the standards of a technical discipline, because the properties answer to no standard outside the essay. Two standards define engineering practice: grounding in a theory or a model [6], [7], [8], and falsifiability [9].

On grounding, the five properties are selected, not derived. They were chosen because they “feel foundational” and stated as beliefs and preferences, with no model, theory, or empirical result behind them [1]. The choice is arbitrary on its own account — CUPID is a backronym, and several candidates existed for each letter — so there is no principled reason to prefer these five [1].

On falsifiability, a claim is falsifiable when some observation could refute it [9]. The properties are stated as centres, and the trade-off remark answers any apparent violation: a codebase that appears to violate a property is either a trade-off or too far from the centre, never a counterexample [1]. No observation can fail a property, and none can be checked against a model because none is offered.

As a replacement for SOLID, CUPID also fails on coverage. SOLID poses five design questions — responsibility boundary, extension, substitutability, interface granularity, dependency direction — and a replacement should engage the same questions [10]. It does not: only the Unix philosophy approaches one, single purpose, and even that is presented as a different, outside-in property [1]. Nothing in the five says how to extend a design, when a substitution is sound, how to split an interface, or which way a dependency should point. The packaging principles that accompany SOLID are untouched as well [10].

The expected reply is that CUPID never claimed to be rigorous, so this section attacks a claim its author does not make. That is correct, and the objection is not to CUPID’s informality. It is to the opposite move: presenting the properties as a replacement for SOLID, and claiming an effect — that the more code has these qualities, the more joyful it is to work with [1] — while disclaiming the standards on which design guidance is judged. The disclaimer cannot have it both ways: if CUPID claims no results and no grounds, it can claim neither to replace SOLID nor to improve anything.

9 What remains

On its author’s own terms, CUPID fails the assessment requirement he set: the articulation and human criteria are met, the assessment requirement fails for Composable and the Unix philosophy, holds only in part for Predictable, holds for Idiomatic only against an external standard, and has no criterion for Domain-based, while layering adds no independent support [1].

On the standards that define engineering [6], [7], [8], the five properties rest on no model or result and are not falsifiable [9], so they give no basis for expecting improvement. The result is narrow: it does not say the five names are useless, that the recommendations behind them are unsound, or that CUPID is worse than SOLID. Several recommendations have merit on their own — narrow interfaces, observability, domain language, consistent formatting.

What CUPID is, on its own presentation, is a statement of what its author values in code, with no result demonstrated [1]. It belongs to a third category — practitioner advice — legitimate, but neither engineering nor science, and with no reason to believe it is right.

References

[1]
D. Terhorst-North, “CUPID: For joyful coding.” https://web.archive.org/web/20260909112809/https://dannorth.net/blog/cupid-for-joyful-coding/, Feb. 2022.
[2]
K. Henney, “SOLID deconstruction.” Jan. 2016.
[3]
C. Oldwood, “KISSing SOLID goodbye,” ACCU Overload, vol. 22, no. 122, Aug. 2014.
[4]
T. Kaminski, “Deconstructing SOLID design principles.” Apr. 2019. Accessed: Oct. 14, 2026. [Online]. Available: https://web.archive.org/web/20261014151413/https://www.tedinski.com/2019/04/02/solid-critique.html
[5]
J. Miller, “Putting SOLID into perspective.” Aug. 2022. Accessed: Oct. 14, 2026. [Online]. Available: https://web.archive.org/web/20250221104923/https://jeremydmiller.com/2022/08/10/putting-solid-into-perspective/
[6]
[7]
IEEE, IEEE standard glossary of software engineering terminology. New York: IEEE, 1990.
[8]
W. G. Vincenti, What engineers know and how they know it: Analytical studies from aeronautical history. Baltimore: Johns Hopkins University Press, 1990.
[9]
K. R. Popper, The logic of scientific discovery. London: Hutchinson, 1959.
[10]
R. C. Martin, Clean architecture: A craftsman’s guide to software structure and design. Prentice Hall, 2017.