Writing / Notes August 26, 2026

How to design a useful primitive

The best primitive compresses complexity into a capability that other people can build upon.

  • product-design
  • developer-experience
  • software-factories

Feature or primitive?

The easiest question to ask in product development is: What feature should we build next? Features are visible and easy to put on a roadmap. They can also turn a product into a monolith when each new workflow becomes another screen, setting, or branch of logic.

A primitive starts with a different question: What capability should others be able to build upon?

Draw the boundary

HashiCorp built its products around this idea. The technology was an implementation detail. The important work was finding an abstraction that captured the underlying workflow while hiding unnecessary complexity.

The hard part is deciding where to draw that line. They offer four steps to finding it:

  1. Start with the workflow. Find the repeated work behind an outcome. The primitive should reflect the nouns and actions people already understand.
  2. Find the repeated complexity. Ask which decisions stay the same, where the work varies, and what every user rebuilds.
  3. Create a small contract. Define its inputs, outputs, constraints, and failure states. Make it useful alone and composable with other components.
  4. Codify the behavior. Keep it readable, versioned, and observable so machines can execute it while people can audit and recover it.

Take an approval. A procurement team routes a purchase order to a manager. A claims team routes a payout to a specialist. A publisher routes a draft to an editor. The surrounding workflows are different, but the underlying capability is the same: submit something, identify who can review it, apply a policy, and record who decided what and when. That reusable capability is the primitive.

Why agents care

This becomes more important as more people and agents build software. Agents become more reliable when capabilities have explicit inputs, outputs, and errors. Small contracts make it easier to select an action, inspect the result, and compose a larger system.

A primitive is not the whole product. People still need onboarding, support, and a useful interface. A clean underlying capability simply lets that experience evolve without rebuilding the foundation.

The goal is to find a capability simple enough to trust, expressive enough to reuse, and stable enough for other people to build upon.

Sources

Nishu Lahoti
Nishu Lahoti