< expLog

DevTools > A checklist for a well-built tool

2021-06-11 – This series is a work in progress: I'm not as experienced at writing as I would like to be, and making something valuable, coherent and readable takes time.

To begin I'm simply trying get all my ideas typed out; I'll work on better composition and expression later. Send any feedback my way @kunalbhalla.

Design and build your tools thoughtfully, with care; and that clearly shines through when they are put to use.


As toolsmiths, we have way too much space in our heads for the tools we use; often enough we're evaluating how the tool is built, how it works, why it works, how to make it better.

Engineers trying to do their day jobs have a significantly different perspective: they encounter dozens1 of tools every day, and more often than not – each of these tools is yet another annoyance they need to navigate as quickly as possible. 1 Several web apps, some form of IDE, source control, some compilation/build mechanism – just to get started. Then there'll be tools for deployment, data management, and actual business logic.

Make obvious tools that use the least amount of energy and time to use correctly. Aim to build a minimal and functional user experience and lightweight design – which you can read more about from far more

Magical, but transparent

I greatly appreciate tools that configure themselves to my circumstances automatically and tells me the best options; at the same time – it should also explain why these options are the best options.

Magical tools are amazing right until the point I want to do something their creator didn't anticipate. Providing information around why the tool is taking certain decisions – potentially with inline logs, tooltips, or even a "Run log" that captures everything that happened and can be looked up.

Make the common workflows easy

Things are need to be done frequenly, particularly by new users should be trivial and intuitive; without overwhelming them. Things should just work – and be magical. This is also often referred to as building a "pit of success" – the tool pushes you in the right direction.

Layer complexity: additional, deep customization should be possible, but doesn't need to be immediately thrown at a user doing something trivial.

Make the rare workflows possible

At the same time, leave space for power users who need to do significantly more complex/extra-ordinary work. Don't neuter the tool to keep it easy for new users. It's a bit too easy to accidentally hobble tools too much with the idea of the

Leave space for people to completely override the tool's decisions if they're willing to accept the consequences of doing so. This is where transparency plays a very important role. Respect your power users as the ultimate experts and let them do what they need to.

Enable customization

One of the balances tool builders have to maintain is deciding to add very team/edge-case specific features vs building something much more general2. 2 This is important enough that I'll talk about it again in traps to avoid.

Instead of painfully trying to navigate this dilemma leading to unhappy compromises, I prefer to make it possible for users to customize tools to their satisfaction instead. At the end of the day, the customers are engineers too, and I'd much rather let them use their skills to maximize the value of the tool instead of trying to maintain iron handed control over the tool's behavior.

As always, there are tradeoffs with this approach – particularly around ownership when things break, as well as the added cost of maintaining an interface that customers can rely on.

Enable composition

Command line tools almost get this for free, thanks to pipes, shell scripting, and the ability to quickly duct tape together text parsing. Explicitly supporting this – with JSON outputs, clean interfaces and treating flags as an explicit API – makes tools far more valuable and useful.

UIs, unfortunately, have generally been terrible it terms of easy composition. Even then, there are some things you can enable – Jupyter notebook like interactivity with the raw data; deep links that can be created from other tools; the ability to embed and configure the important pieces in other tools.

Persist interactions for sharing

This is important for UIs – particularly web based ones. Interesting information is often hidden behind several clicks – a well behaved tool should represent this navigation in the URL, or some internal, shareable state instead of forcing users to click through again.

An easy sign is if tool links are passed around with a set of instructions asking others to manually follow a bunch of steps to reach the desired state – allow deep linking to the right state instead.

Fast, or at least asychronous

Fairly self explanatory – the whole point of building tools is to make everyone more effective, and a painfully slow tool that eats into everyone's time is hardly valuable (except for when the alternatives are even worse).

In case it's prohibitively costly to be faster, try to hide the slow parts instead – by pre-computing values, guessing what they'll need and caching that; and never, ever forcing them to be stuck waiting for results – allow them to exit and return smoothly.

The last thing I want is for my laptop to go to sleep and accidentally discard the results I spent an hour waiting for.

Reliable & Trustworthy

Broken tools lead to unhappy engineers; particularly those investigating something complex. You never want to be in a position where you're not quite sure if you've identified a problem, or it's simply an artifact of tool being used to investigate.

It's very easy to have subtle, yet extremely troublesome problems. For example, a tool I wrote to render JSON ended up silently mangling large numbers beyond Number.MAX_SAFE_INTEGER; which would silently corrupt large ID numbers. Identify these and fix them as soon as possible; better yet, anticipate the ones that break the core value added by the tool and solve them before release.

To quote Kent Beck: Make it work, Make it right, Make it fast.


You can drop me a email or catch me on Twitter. (I still haven't found a comment system for static blogs that I particularly like.)