Avoiding complexity in a growing product

Michael Skelly
The Stacker Blog
Published in
4 min readJan 9, 2020
Things can get messy
Things can get messy

Dear Stacker –

Right now, despite achieving some complex stuff, our product is actually quite simple. As a team, I think we like products that are simple. Especially ones that are both simple and powerful.

So how do we keep increasing the power of our product, while still keeping complexity down?

Here’s a look at how two of the product we love do this:

Airtable

Airtable is easy to conceptually grasp. It has four main primitives — tables, views, fields and blocks—and it’s easy to understand what each one does.

They hide their complexity by having lots of different types within each primitive. Each type still does the same thing as the other types in the same primitive, but it does it in a very different way.

Take for example, Views. Views display some data fields from a table. Airtable has five different view types (Grid, Form, Calendar, Gallery, Kanban). All of the different views look wildly different. Some only let you view data (Calendar, Gallery) and some only let you create (Form). But they all display data fields from a table.

Or take Blocks. Blocks are really, really different – some display your base as 3d model, others send emails. But they’re all small self-contained widgets that interact with the data in your base.

Airtable’s block library

Airtable has managed to create a great set of well-defined primitives that each act as a bucket for more complex behaviour.

And that means they can add wacky stuff like a 3D-table viewer without having add something like “3D Scenes” to any of their menus.

Trello

In my head, Trello is the the ultimate in simple products. It basically has three main primitives: Board, Lists and Cards.

Each primitive is is really simple,and unlike Airtable, Trello doesn’t have a lot of different types of each primitive: there’s not an Issue Card and a Gallery Card and an Idea Card.

How Trello hides its complexity is through “Power Ups”. Enabling a power-up changes one of its primitives by adding on some extra functionality.

Trello’s Power-up Gallery

So by installing the Voting powerup, Cards can suddenly have a vote score. By installing the Kanban powerup, Lists can suddenly have a maximum number of items.

Power-ups allow Trello to make each of their primitives much more complex than they initially seem, by adding new functionality to them when powerups are enabled.

The lessons of simplicity

  1. Have a small number of primitives
  2. Make the primitives well-defined so it’s easy to understand what they do
  3. Hide the complexity around how they do it, either by having a different types, or by allowing functionality to be switched on and off

How does this apply to Stacker?

Primitives

Firstly, let’s look at our primitives, and what they’re for:

We’ve got: Objects (data schema), Views (displays data for one or more records), Pages (something the user can visit), Blocks (UI components displayed on a Page/View) and maybe Features (an area of an app, maybe containing the other primitives).

I feel like the definition of some of these could still do with a bit of clearing up (where is the boundary between page and view?), but we’re on the right track.

Hiding Complexity

We’ve already got a few areas where we’ve hidden complexity by producing a few different types of each primitive, for example our different List View types, or our Blocks for us to add to detail views.

I think we should actively seek out places where we can increase our product power by only adding new types of each primitive. For example:

  • Allow different display types for detail Views, to allow Product View or Profile View
  • Add more list View types to enable maps, calendars and galleries
  • Enable different functionality on Views (like faceted filtering or like buttons) via powerups
  • Add more types of Blocks to be used in detail Views
  • Allow special Feature types, to bring in more functionality outside of what can be done with our primitives.

TL;DR

Keep power and avoid complexity by having only few well-defined primitives, and use switches or types to hide complexity within them.

--

--

Michael Skelly
The Stacker Blog

Creating Stacker.app to let anyone build apps without code. You can believe he's not butter.