5 Tips for Building the Best Developer Experience Possible
Tags: applicationdevelopment, design
Published: 2023-02-15 13:48:20


In May of 2022, I was invited to a customer summit for [Postman](https://postman.com) to talk with industry leaders about APIs. While I was there I was asked to be on a panel to talk about developer experience (DX). I was a little taken aback because developer experience wasn't something I had any experience with. I reluctantly agreed, hoping in my mind that I was going to be able to pull something out of thin air in front of all the summit attendees.

Much to my surprise, I was highly opinionated on the topic. Turns out, all the exposure I've had to third-party APIs coupled with my stint as a development manager has instilled a strong sense of "*what is a good developer experience*" in me. Phew!

I recently had the pleasure of talking to [Lars Jacobsson](https://twitter.com/lajacobsson) about building a better developer experience on [episode #3 of the Ready, Set, Cloud podcast](https://readysetcloud.io/podcast/3). Among other things, we concluded a good DX will:

* Boost developer productivity
* Expose new features to consumers
* Encourage users to continue using it

Lars and I discussed these points as the main drivers behind a good DX, but we didn't talk about *how* to make your API, SDK, or service do these things. It's one thing to know what makes up a good DX, but it's another thing entirely to know how to build (and execute on) the main drivers. 

Here are five tips I've learned the hard way on how to build the best DX possible.

## 1. Use the Power of Story to Document Everything

There are two things I know developers hate doing: *writing documentation* and *building unit tests*. But the truth is, both are necessary and crucial to the long-term success of any production application. 

Time and time again, I see APIs, frameworks, and platforms that have treated documentation as a second-class citizen. Sometimes the docs are generated from the code, sometimes they are handwritten. But you can always tell when the docs weren't made a priority. They might be stale, lacking context, or void of any meaningful examples.

> Documentation is your first chance to make a good impression.

You know what they say about first impressions? You only get one. Many developers will read the front page of your documentation and decide whether or not to use your app *in the first 30 seconds*. Generated or complex documentation will not win over a potential new consumer. You must build engaging documentation that hooks the reader and convinces them to give you a go.

A couple of years ago (to the day!) I wrote about [using metaphors to build a story in tech](https://dev.to/aws-builders/the-mighty-metaphor-your-new-secret-weapon-in-tech-30a2). You reach larger audiences and connect at an emotional level if you can articulate ideas in a way that is relatable. If you can build a story or a relatable reference that you keep coming back to, your consumers will be more engaged and much more likely to understand and try your product.

Let's take my [release note blog for collection data types](https://www.gomomento.com/blog/did-someone-say-collection-data-types-oh-we-did) for [Momento](https://gomomento.com) as an example. The post talks about three new data types you can cache and interact with in new ways. By itself, not the most exciting topic.

However, throughout the post I talk about building a fictional game called *Acorn Hunt*. I provide meaningful use cases that relate to a fun example and tie the whole release together. The post is fun, energetic, and relatable because everyone plays (or has played) games. With an overall lighthearted tone, readers are much more likely to read to the end instead of skimming to get highlights and understanding the detail of the release.

*Do this with your documentation!* Build a narrative that keeps potential consumers engaged and reading about the features you have to offer. A reference your reader can relate to will drive a better sense of understanding and ultimately will increase the likelihood of them trying it out.

## 2. Stale Documentation Loses People Immediately

I recently [built a newsletter platform](https://dev.to/aws-heroes/how-i-built-an-open-source-serverless-newsletter-platform-3bm2) to send my weekly newsletter, [Serverless Picks of the Week](https://readysetcloud.io/newsletter).

Part of the solution was integrating with the email provider [SendGrid](https://sendgrid.com). Twilio acquired SendGrid in early 2019, which made me excited about building the integration. I've often considered Twilio as the cream of the crop regarding DX. Their documentation is incredible, they provide meaningful, business-focused use cases on their site, and things just tend to work. So naturally, I assumed SendGrid would be this way since they were 4 years post-acquisition.

Boy was I wrong.

The docs had a similar feel to Twilio, but that was about the only overlap. The documentation available on the site, in some cases, was incorrect and the explanations were stale. There would be properties defined on an endpoint that did not exist or the data type was just plain wrong.

I was able to work my way around these issues slowly but surely. However, *it did not instill a sense of trust in the API*! 

Once I stumbled upon the first incorrect piece of documentation, I immediately began to doubt the rest of it. How would I know what worked and what didn't? Is the one I found a one-off? There was no way to know how or why it was wrong and I wasn't about to try to find someone at SendGrid to talk me through it. 

This lesson goes to show the incredible weight that up-to-date documentation brings to the table. 

Documentation doesn't stop at API references! The examples you use to illustrate how your code works are equally, if not more, important than the docs themselves. I was exploring a new package the other day and copied the example from npm into a script I had locally to try it out. 

Much to my disappointment, the example didn't work! It was word-for-word from the documentation, yet when I ran it I received a runtime error. I didn't write this package, so I had no idea how to troubleshoot the issue. I quickly abandoned the it in search of another one that gave me the impression it was better supported.

All this to say, *please make sure you treat documentation as a top priority!*

## 3. Fundamentalism Kills Developer Experience

Fundamentalism is great when you're learning something new. By fundamentalism, I mean doing something strict and by the books. Follow the rules exactly as they are defined and offer no leniency in breaking them.

I can't think of a better way to learn. Staying within the bounds without "doing your own thing" will make sure you understand the nitty-gritty details of a topic or concept.

That said, I've been quoted a few times telling people not to be fundamentalists.

{% twitter https://twitter.com/andmoredev/status/1621497660325740553 %}

When building for developer experience, fundamentalism doesn't work. Take shortcuts where you can. For example, REST APIs are entity-based access mechanisms with strict rules about how to create, update, read, and delete. But if you're building an API that aims to make a developer's life as easy as possible, it might make sense to combine a few actions. 

If you have an API that creates a newsletter - instead of having separate endpoints for `POST /newsletters`, `POST /newsletters/{id}/subscribers`, and `PUT /newsletters/{id}/profile` you could make a single endpoint that does everything in one shot - `POST /import-newsletter`. The single endpoint does the work of all three: creating the newsletter, adding subscribers, and setting profile information - but the caller is only hitting the API once. It results in a nicer experience because it takes on orchestration on behalf of the caller and manages errors, retries, and rollbacks if things go south.

Software is all about tradeoffs. *Take the ones that favor usability for your consumers.*

When you combine features into one, you also get the ability to introduce your consumers to new functionality they may not have used before. Provide a simple way to try out a new feature by incorporating it into something they might already use. The lower the barrier to entry, the higher the usage.

## 4. Meet Your Consumers Where They Are

I recently was in a meeting where we discussed building an SDK in several different programming languages. The SDKs wrap the same API, they would just be available in languages like Go, Python, Java, .NET, and Node.js.

Our initial thought was to make these SDKs the exact same, just written in their respective languages. Same function names, same inputs, same outputs. But that would result in some odd experiences that felt against the grain in certain programming languages. 

For example, if an SDK client was optimized for a .NET user, it might feel too wordy and structured for a JavaScript user. If the client feels like it takes too much effort to initialize and use, your standard JavaScript developer will abandon it pretty quickly (at least I would).

With that in mind, we started talking about letting the SDKs "drift". Changing the inputs and outputs of the API calls to best match the experiences the developers are used to in each programming language. Strongly-type and separate every component in the .NET client. Move fast and be flexible with JavaScript. You get the idea.

Chances are low that a single developer will be using the same SDK in different languages anyway. Optimize for the behaviors of the devs, they are the ones you need to keep happy with developer experience.

You want to create as low of a barrier to entry as possible. The easier and more familiar you make the overall experience, the happier your consumers will be. The happier your consumers are, the more they will use it and the higher likelihood of them sharing it with their friends.

## 5. Provide An Observable Experience

I've mentioned in every blog post I've written this year that [we need to emphasize observability](https://dev.to/aws-heroes/serverless-in-2023-a-shift-in-focus-30gp). But what does that mean for developer experience?

In this case, I'm not talking about how we add tools in our backend to track KPIs. I'm referring to the ability of a consumer to get a glimpse into their usage of your service. How much are they consuming? Who is using which features? Can users have access given or revoked through a dashboard?

These features often live on the *control plane*. Some might refer to it as an "administration dashboard", but ultimately the idea is to provide an easy way to centralize access and control data requests. To take an example, think about the AWS console for SQS. 

![SQS dashboard in the AWS console](https://readysetcloud.s3.amazonaws.com/5_tips_for_building_the_best_dx_feature_1.png)

You have a dashboard that allows you to create, update, and delete queues. You can set up queue triggers or purge items. You can even get some metadata about them like created date, number of messages available, and the encryption settings. These are all control plane features. They control the operations that drive the data. *You should have this for your service!*

Adding visibility into usage provides comfort to users. They like knowing there aren't going to be any surprises at the end of the month when the bill comes in. Administrative views like this might not solve business problems for your consumers, but it does provide invaluable statistics into usage. 

## Summary

Developer experience matters! You could have the best product on the market but if the DX is poor, you're going to have a hard time getting adoption. 

AWS Step Functions is [the perfect example of this](https://dev.to/aws-heroes/success-with-step-functions-finding-a-way-to-build-that-doesnt-suck-27p3). The team built an amazing user interface, the [workflow studio](https://docs.aws.amazon.com/step-functions/latest/dg/workflow-studio.html), that allows users to drag-and-drop workflow steps in the browser, but it does not integrate with local `asl` files. You must take the definition from the browser and update your code manually, being sure to add in the appropriate definition substitutions every time. 

The experience of the workflow studio is incredible. To me, it's the best experience in the AWS console by far. But because of the disjointed experience of manually copying code to local `asl` files, people push back on using it and opt for using Lambda functions instead, despite some of the [operational benefits](https://dev.to/aws-builders/lamba-vs-step-functions-the-battle-of-cost-and-performance-lim). 

Think about the developer experience end to end. It's not about making a single piece of it great and ignoring the rest. It's about making your entire service easy to use and intuitive. It's about enabling the discovery of new features. It's about making the lives easier of developers by combining small, related commands to boost the power of your API calls. 

Your documentation is the gateway to your service. If it's stale, incorrect, or poorly written, you won't convince developers to try you out. Make sure it's clean, follows business processes, *and works!* If you're looking for inspiration, I've never come across better developer documentation than [Stripe](https://stripe.com/docs/api) and [Twilio](https://www.twilio.com/docs/api). Be like them!

Building SaaS is much more than solving a business problem. As SaaS providers, we owe it to consumers to provide a rich experience when building on top of our services. Imagine you were building a LEGO set and the instructions were wrong (or missing!). Or maybe the instructions were correct but written for NASA engineers as the target audience. Kids wouldn't be very successful with the build.

Meet your audience where they are. Build for them. Provide meaningful, up-to-date docs to get them going. Give them the tools to be successful.

Happy coding!