Skip to content

Primitive design: Designing fundamental objects and associations well to make software intuitive and poweful

January 9, 2025 at 03:22 PM

Note: This is not a blog, it's a semi-private digital garden with mostly first drafts that are often co-written with an LLM. Unless I shared this link with you directly, you might be missing important context or reading an outdated perspective.


Understanding Primitive Design in Software

Product design extends far beyond aesthetics. There’s a crucial aspect of software development that exists at the intersection of product management, design, and engineering - what we at Quora called “mechanics design.” This concept, influenced by Rebekah Cox’s broader definition of design as “the set of all choices made for a product,” focuses on selecting and implementing the right primitives.

What are Software Primitives?

Software primitives are the fundamental objects and their associations that form the foundation of a system while remaining intuitive to end users. The skill lies in choosing these building blocks carefully and defining how they relate to each other.

Case Studies in Primitive Design

Spotify

Quora

Reddit

Technical Products

GitHub

Figma

Principles of Good Primitive Design

  1. Entropy Reduction in Object Selection

    • Make the most entropy-reducing cuts upfront when choosing initial objects
    • Aim to match users’ mental models as closely as possible
    • It’ll never be perfect because no two users have exactly the same mental models
    • Recognize diminishing returns in object granularity
    • Accept that perfect coherence across all users is impossible
    • Focus on doing “the right thing” upfront with lowest cognitive load across the most users
  2. Primitive Categories (via chat with Markus)

    • Familiar Units: Reduce cognitive load through recognizable interaction patterns
    • Composable Units: Provide flexibility and power through combinable building blocks
    • Constraint-Driven Units: Address technical requirements of the problem space (e.g., robotics, ML systems)
  3. Expertise-Based Progressive Disclosure (via chat with Markus)

    • Adjust primitive exposure based on user expertise level
    • Create a natural curriculum of product usage
    • Layer primitives from high-level abstractions to more granular control
    • Consider dynamic adjustment of interface based on user proficiency
    • Balance between immediate usability and advanced capabilities
  4. Instantly grokkable objects

    • Build on time-tested concepts (e.g., songs, git commits)
    • Use metaphors and skeuomorphism for new concepts
  5. Association Design: Prioritize common user paths

    • Prioritize common user paths
    • Balance between prescription and flexibility based on user type
  6. User-Centric Approach

    • Consumer Products: More opinionated, reduced friction
    • Developer Products: Greater flexibility and optionality

Managing Complexity

  1. System Documentation

    • Maintain abstract system diagrams
    • Track object and association graphs
    • Keep object space minimal but sufficient
  2. User Consideration

    • Consider user cognitive load (System 1 vs System 2 thinking)
    • For casual users:
      • Provide intuitive defaults
      • Hide complexity in overflow menus
    • For power users:
      • Offer more flexibility
      • Provide consistent patterns for complex interactions

Technical Debt Considerations

Conclusion

Successful primitive design requires understanding your users, carefully choosing your basic objects, and thoughtfully defining their relationships. The key is finding the sweet spot between simplicity and power, always keeping your user’s needs and capabilities in mind.

Raw

So I want to make a note about product design and why I think of the field is beyond just making things pretty. And there's this important thing that happens in software that happens somewhere in between a PM and a designer and an engineer that doesn't really been given a name. The best teams collaborate really well and do it really well and bad teams actually screw this up in product. At Quora we used to call this mechanics design. A lot of this is influenced by Quora. Rebecca used to have a very general view of what design is. She used to call it the set of all choices made by a product. The way I think about it is choosing the right primitives and one level more specific I think of it as choosing the right objects and associations between objects that both keep the system pressed but intuitive to its end user. So concretely this is making decisions like for example in Spotify choosing the basic artifacts to be a music file, a playlist but beyond that genres and topics, moods, what should be a playlist, what should be a container over a playlist, what should be a radio. I think one of the big reasons why Spotify has managed to stay competitive in a market where Apple has much better pricing is that they have made excellent choices around their objects and then in the user interface the ways in which you can interact with the object like adding a song to a playlist and so on and so forth have been made very low friction and intuitive and always seems to be available at the right place and they all seem to cross link. Other albums and sorry I meant to say that albums and artists are also two basic objects in the system. What I want to do in this post is illustrate a bunch of graph diagrams like nodes and edges of different products and what their objects and associations are. Of course the one I worked on the most was Quora where the objects were questions, answers, users, topics and one of the more interesting things that happened as AI got better was that we were able to remove topics because if you get into it it's actually very difficult to define what the correct and optimal topics are because different people interpret topics differently. Of course spaces was another example that reminds me of Reddit where the primitives are user, post, common thread objects, subreddit being the most critical one that creates strong boundaries for a community. Getting more into technical products I think of two examples GitHub and Figma. Figma is an interesting one because the product is very visual unlike Spotify where the content is actually living on a completely different modality in audio but in Figma the content is largely visual and so the interface design has to get out of the way and give way to content heavily. GitHub is sort of in the middle balancing content and Chrome. You can go all the way back to like a file system being an example of the system design before anything else came along. It's very visibly expressed in IDEs right now so programmers are very close to this. GitHub's primitives are about collaborating asynchronously largely. That's what's really interesting about GitHub as opposed to Figma. Designers heavily rely on real-time collaboration and synchronicity versus programmers prefer asynchronous code reviews or sorry I meant that in addition to that their primitives are the pull request, the issues, wikis, git commits. Essentially starting with the primitives of git and file structure but then building up a collaboration layer for multiple people working on the same project at the same time. Certain realizations I've had about designing a system well is that the objects need to intuitively immediately make sense to people so either you're building off of something that is stood the test of time like a song or a git commit or if you're introducing a new concept you tend to rely more on metaphors or skeuomorphism that a user can recognize from another part of their being. As for associations what you really need to think about is prioritizing the relationship between objects and what paths does a user need to traverse a lot. Sometimes this is prescriptive in interface like Spotify. The more you are close to a consumer product the more opinionated you want to be and reduce friction to doing the most common thing but the more you are towards a developer product or an otherwise power user product where they want the flexibility to use things in different way you want optionality. So a good example of this is how GitHub lets you cross link different objects by simply prefixing it with a hash or a br. People call this field system design or primitive design. I think a good way to keep check of this is to keep an abstract system diagram of your product in something like a fig gem board or a fig gem board is good enough and the most important thing to track is a graph of your objects and associations and make sure that your object space is as small as can be but no smaller to quote the other ones and I think no smaller is actually a very important part of it. But at that point that encompasses every product however it becomes too unintuitive for most regular users to use like of course I can make a film by just storing it as raw video and writing a bunch of scripts to transform it is just not going to enable the best creative expression and the way final guard pro will to give you an example of a tool. So we were talking about designing and choosing the object space as far as the association space goes the principle is to know your user whether it's someone who's a casual user who has limited time and cognitive energy to spend on your products there are they mostly operating out of system one in the psychology sense or system two and if you are dealing with users in casual applications like music where they are largely operating off of their lizard rain then you want to have very intuitive very sensible defaults and you want to hide away the complexity behind an overflow menu or something like that if making it available at all because technical debt starts to become a problem once you offer too much complexity even if you maintain it in the background and you just have edge cases with the interaction of more objects the complexity grows and square obviously and definitely gets too much for a human mind to track off but as you do get into more power user type audiences you need to offer more flexibility in your dissociation design so that means that you do have to open up more of the N squared set of possibilities and to keep this manageable you do start getting more general and abstract for example how github does just general cross linking between types and the user lot of the shared design language for a lot of them because another consideration is that there's only so much visual whiplash a user can deal with and there's only so many different concepts a user is willing to learn in using a new product