The challenge/luxury/eccentricity of working independently on a big piece of software is that you make and own all of the design decisions. There is no designer to iterate on mockups; you are the designer. There is no UX researcher to organize A/B testing sessions and wireframing feedback; you can do that, if you'd like, but it often means sacrificing velocity.
I've found that the best work I do comes when I can leverage jumping from design details to implementation details with frightful speed & abandon; this requires a comfort level with making snap decisions very quickly, but often can lead to really, really strong results.
Unfortunately, the reverse is also true. The worst work comes from me tunnel-visioning my way into a design or interaction that 'feels good' not because I think it resonates well with users but because it fits my pre-conceived notions or my desired architecture.
I've changed more in Buttondown in the past quarter than in the seven quarters preceding it! Most of that turned out well; I want to talk about two things that did not.
Buttondown's list views all changed from a pretty opinionated 'default' set of filters (Subscribers should show 'people who are currently opted in') with some janky, hard-coded alternate filters (unsubscribed subscribers! spammy subscribers! and so on) to the very powerful, very expressive filtering paradigm that currently exists on production: show all subscribers, regardless of state, and allow filtering in complex & combinatorial ways.
This is certainly more powerful than what Buttondown used to have, but it's also not what people want. I really wanted to ship uniformity across these list views, and I was too dialed into power users' understanding of the Buttondown state space. Whoops! I forgot to think about the common desire paths: most users, particularly new and onboarding users, just want a few smart filtering options (lets say "Active subscribers", "Recent unsubscribers", and "Paid subscribers") with an escape hatch for all the complex filtering.
So that's what I'll end up building.
If the first mistake was due to insufficient deference to how users actually think about things, the second is undue deference to how things used to be, and an unwillingness on my part to let go of old paradigms.
When I pushed the changes to the new writing interface, I started getting a slew of tickets all with the same question:
I scheduled an email to go out but it's still listed as a "draft". What gives?
The answer is: 'scheduling an email' is the equivalent of "setting a
publish_date on an email", but that
publish_date doesn't mean anything until you hit the "Send" button that actually turns the email from a draft into something more final. I know this is janky — I knew this was janky! (Do you have any idea how much it hurt to type this paragraph?)
But this is how it worked in the old interface, and I wanted to keep that around for, I don't know, convenience's sake.
This is obviously not how people think about scheduling, and the microcopy I used that feinted at 'completion' certainly doesn't help matters. Folks expect to write an email, set some attributes, and then send it out into the ether — and sending it out into the ether does not mean going into two completely unrelated modals.
Here, the broad path forward is obvious (subsume 'scheduling' and 'audience' into a generalized 'publication' step) but the details are very murky. How should I allow editing one of these steps in a post-publication flow? How do I communicate this change efficiently and effectively?
This one is going to be a little more complicated than "just build some smart defaults", but I also think it'll be more important. I want the experience of sending one's first email to be one of the best feelings about using Buttondown; the foundation is there, but the execution is a ways off.