Drew Barontini

Product Builder

Issue #54
10m read

Product Codex

My oldest son (almost 7!) just got into chess. He’s in a Chess Club at school, so we bought him a chess board to practice at home. I remember my Dad teaching me to play when I was young, but all the moves and rules were hazy to me. After a quick refresher on the rules, we played over the weekend. It was such a blast. He’s very good, and plays as over-confident and aggressive as a six-year-old would. You don’t know what he’s going to do—Chaos Chess as we call it.

The strategy involved was visceral. You don’t just make a move. You see the multiple possibilities, the second-order effects of each move. You sometimes sacrifice a piece to gain positioning; you sometimes get too greedy and lose a key piece. But as you play, you develop an ability to see the hidden structure behind the placement of the pieces. You know the rules, the movements, the positions. It’s an art.

Now I’m no Chess Master, but it reminded me of what I’m going through in my new role at a new company. I’m learning a new and complex product. I need to understand how it works so I can develop a winning strategy. Let’s call it chess in the digital realm.

I’m used to building new products zero-to-one, so having to get up to speed on a new product with a large surface area is different. I’ve spent the last two weeks using the product, asking questions, and building my knowledge of the inherent pattern language. Through the process, I’ve developed a new system and way of thinking about understanding software products. I even created a new notation for describing software so PMs, designers, and engineers—the product builders—can consistently communicate about the product. This new notation even allowed me to spot inconsistencies and opportunities for improving the product. Win!

This idea is called Product Codex. It lives in the 🦉 Clarity Codex of the Claritorium.

(You can read more about the Claritorium at claritorium.com.)

There are three parts to the Product Codex:

  1. Screens: The surface area of the product.
  2. Schemas: The hidden structure of the software.
  3. Sequences: The structural flow as a sequence of events.

Screens

The software product I’m leading product for is a responsive web application, but this applies to native mobile applications as well. The screens are the surface area of the product. This product has a large surface area, so I started by taking inventory of all the pages. I created stickies in a FigJam board and was able to start grouping them to understand the categories. This also helped identify areas where the information architecture (at a high level) was confusing.

Screens

You start zoomed out at the macro level before you zoom in. This is like the floor plan of your house—it shows you the rooms (the screens) without all the exact details inside.

That’s where schemas come in.

Schemas

In chess, there’s a specific notation for each move based on the grid of squares that make up the board. The horizontal axis is labeled from the letter A to the letter H. The vertical axis is labeled from 1 to 8 (from the perspective of the white pieces). That means when you move a piece, you can mark it like “Ra4” (Rook to a4). You can visualize a game based just on the notations.

While I was looking closer at the core features of the product, I had an idea to create a text notation to describe the functionality of the features. It could show the affordances on each page and help me spot inconsistencies and improvements in the product.

And as I do with almost everything, I went really far on this one. Throughout the week, I took screenshots of the product, brought them into a FigJam board, and then wrote and experimented with these notations to describe the product.

I started at the component level for each screen (search input, filters, search results, etc.), so I notated three specific parts:

  1. Components: The building blocks like a search input or filters.
  2. Actions: The events that users take when they interact with the software.
  3. States: The changes in the components based on what happens.

Here’s what the notation looks like:

::Component.SubComponent@state.action()

And using our SearchInput example, here’s that component’s notation:

::SearchInput@idle.type()
::SearchInput@active.SubmitButton.click()
::SearchInput@idle.SubmitButton@disabled

It’s a sort of “pseudo-code” I made up, but I’m sharing it because I found this to be really valuable when designing and understanding software. And I think this can help bridge the gap across all product builders to:

Sequences

The screens visualize the surface and the schemas the individual details, but we’re missing the flow that occurs between the screens caused by the interactions.

These are the sequences.

At the screen level, you can simply draw arrows to show a sequence, which is a basic flow that takes a user from one place to another in order to accomplish an objective.

Sequences

Getting closer to the component level, we can go back to our schema example for the SearchInput to see how the sequences come into play.

::SearchInput@active.SubmitButton.click() => [SearchResults]

Taking it further, we can look at a simple sign-up flow in a product:

[Home]::SignUpButton.click()   => [SignUp]
[SignUp]::SubmitButton.click() => [Dashboard]

In addition to the => notation for showing the sequence, you may notice the [Screen] notation for the top-level screens. When I added this notation, it created a higher-level notation framework for fully defining the entire Product Codex.

That’s why I created Anatomica.

Anatomica

Anatomica is a tiny, text-first notation for describing the anatomy of software products.

It models Screens, Components, Actions, States, and Flows so teams can design, discuss, and evolve products before pixels or code. Anatomica is to software what Leonardo da Vinci’s notebooks were to anatomy: a way to expose structure, motion, and hidden order.

Here is the general overview:

[Screen]                      # screen
[Screen@state]                # screen in a state
[Screen]::Component           # component on a screen
::Component.SubComponent      # nested component
::Component@state             # component in a state
::Component.action()          # action on a component
.action() => [Screen]         # navigate to a screen
.action() => ::Component      # focus/open a component (e.g., modal)
.action() => .action()        # chain to another action
.action() => @state           # transition to a state
// comment                    # commentary above a line

And when you apply it to a real example like the ChatGPT prompt input UI, you can see the anatomy of the seemingly simple design expressed more directly.

ChatGPT Prompt

::PromptInput
  .AddButton
    .click()                              => ::AddMenu

  @idle
    ::VoiceModeButton
      .start()                            => ::PromptInput@recording
    ::RecordButton
      .on()                               => ::PromptInput@recording

  @typing
    .SubmitButton
      .click()                            => [Chat]
    ::VoiceModeButton@hidden
    .AcceptButton@hidden

  @recording
    ::RecordButton
      .cancel()                           => ::PromptInput@idle
    .AddButton@disabled
    .SubmitButton@hidden
    .AcceptButton
      .accept()                           => ::PromptInput@typing

You see the language of the product. When the team is talking, they can say “Voice Mode Button” and all understand what it’s referring to. This also extends to sales, marketing, customer success, and any other groups talking about the product. The language represents the unique lexicon of your product. Anatomica is a method for defining this lexicon, and for jump-starting the design and development process through clear schemas. It goes beyond the naming. It shows you the structural elements you need to represent in the holistic design.

Overlays

Another reason I wanted to build out this Product Codex concept (and Anatomica) was to identify high-leverage opportunities in the product—the areas of the product where specific changes would have an outsized impact. This would take customer feedback and usage behavior to define clear bets that help hit business objectives.

Think of it like a heat map: the warmer the area, the higher the opportunity. A customer expressed frustration, requested functionality, or the quantitative data showed it clearly.

The side-effect of this is creating natural event names you can use in your analytics:

prompt_input.add_button.click
prompt_input.idle.voice_mode_button.start
prompt_input.idle.record_button.on
prompt_input.typing.submit_button.click
prompt_input.recording.record_button.cancel
prompt_input.recording.accept_button.accept

And then call out specific data points as comments:

::PromptInput
	# Only 12% of sessions are using this.
  .AddButton
    .click()                              => ::AddMenu

  @idle
	  # Voice Mode increases session time by 5 minutes.
    ::VoiceModeButton
      .start()                            => ::PromptInput@recording
    #
    ::RecordButton
      .on()                               => ::PromptInput@recording

  @recording
    ::RecordButton
	    # This button is routinely hit immediately.
	    # Users might be confusing this with Voice Mode?
      .cancel()                           => ::PromptInput@idle

Continued Iteration

This is the first version of Anatomica. I intend to keep iterating and refining it. Getting it into a documented GitHub repo was the first step, but I’m going to put it through the paces and see if this scales beyond just something I want to see. I also want to build an application to render wireframes based off of the notation. More to come!

This is a new way to describe software and improve the language, communication, and clarity in the product. I’m excited to keep refining it and sharing more.

Clarity Codex Quality Refinement

Enjoying this issue? Sign up to get weekly insights in your inbox: