Justin Duke

Everything I got wrong with Buttondown's launch

I want to do an earnest, thorough analysis of Buttondown’s launch at some point in the future: what the traffic was like, conversion rates, et cetera. (Truth be told, I haven’t even looked at those numbers yet — there were a bunch of visitors, there were a bunch of signups, and that’s pretty much all I know because I’ve been so in the weeds with work the past week and a half.)

That’s not what this post is, though that post is coming! Instead, I wanted to talk about the question that I always wished more people talked about during launch postmortems:

Where did I mess up?

Read more →

So good it makes you angry

Sometimes there are things that are so good it actively makes me angry, because it presents a version of the form that seems unimpeachable.

Money Things is like that — it is such a good newsletter, so dense and interesting and funny that it makes me mad, because having to read, like, Hot Pod or Pro Rata or other industry newsletters after it is just an exercise in dwindling returns.

Lincoln in the Bardo was like that — it was such an interesting and beautiful and novel piece of work that it retroactively invalidated so much of what I had consumed beforehand. It was my first audiobook, too, and it basically ruined audiobooks for me, because how do you top that?

And now, this. This product page for Transmit 5.

Let’s run through all the things it does well:

  • There’s a really dope spinning truck on the top. You can move it with your cursor. It captures the eyes, it is pretty, it is neat. It is a great truck.
  • The copy is clear, concise, and large.
  • There are screenshots of the product front and center, because obviously there should be.
  • It’s got those nice little infographics about why you should upgrade (answering probably the third most important question this page has to answer, which is Why should I upgrade?)
  • The page flows nicely, with the little arrows between each content block that lends a little flow.
  • All of those features! And the nice snippet screenshots for the keynote features (but the nice little icons for all the features.)

And the subtler things, too:

  • It is dynamic, but not busy. There is only ever one thing to look at at once.
  • Super responsive, and not in a “uh, I guess everything is gonna be in a smaller font now” kind of responsive way.
  • The way it repositions the entire product from most folks’ perception of it:

Now, long ago we’d call Transmit an “FTP client”, but today, with Transmit 5, we connect to lots of different server types and cloud services. For example, Amazon S3 dramatically changed the way files are served on the internet, and Transmit is a great way to manage your Amazon S3 buckets.

  • Seriously, that truck is so cool!

Like, ugh.

This is like a heat check of a product page. I have bookmarked it and will revisit it every week or so when I need reminding that these types of things can be so much better than they usually are.


Response Times

Jakob Nielsen wrote in 1993 about the three important demarcations in response time. This is a terrific article that I come back to every year or so and see how my interpretation of it has evolved, like reading an old book to see how your perspective of the narrative changes over time.

0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.

1.0 second is about the limit for the user’s flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.

10 seconds is about the limit for keeping the user’s attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.

Those three benchmarks were set in 1968; Nielsen was commenting on how remarkable it was that 25 years later they still held mostly true.

Now it’s a bit more than 25 years after 1993, and even now these seem pretty accurate, right?

You can argue that web applications (and, even more so, native apps) demand a certain level of vivacity that you can’t achieve with a full second or even a tenth of a second, but I think Jakob precisely nails the important way to look at “sluggishness” in his 2014 update to the piece:

0.1 second: Limit for users feeling that they are directly manipulating objects in the UI. For example, this is the limit from the time the user selects a column in a table until that column should highlight or otherwise give feedback that it’s selected. Ideally, this would also be the response time for sorting the column — if so, users would feel that they are sorting the table. (As opposed to feeling that they are ordering the computer to do the sorting for them.)

Sorting the table, as opposed to ordering the computer to sort the table.

It’s not about the speed: it’s about the directness — about the frictionlessness — about the sensation that there are no layers or conduits between you and your task.


Simply put

Chris Eidhof tweeted a good thing:

One of the replies to the tweet was also very good:

This reminds me of a lesson learned back when I was an English major 1.

I’d turn in papers filled littered with clearly and obviously binding a piece of evidence and a conclusion, like:

Obviously, Shelley’s ending for the Creature — like much of the action prior — mirrors the fall of Satan as depicted by Milton. The passage by which Viktor remarks, “the fallen angel becomes a malignant devil”, is an homage to Paradise Lost (and clearly, by extension, the greater English canon, and the way by which author’s literary creations assume lives of their own, for good or for ill.)

Each time I did that, my professor would correctly point out:

We use words like “obviously” to point out things that are not necessarily obvious; we use words like “clearly” in absence of a better way to provide clarity.

Those little bridge words don’t just belittle (and, on occasion, befuddle) your reader: they are bad prose and betray your lack of mastery of a subject. The next time you find yourself writing “simply”, ask yourself: is it that simple? Or are you just trying to will simplicity into existence?

  1. Oh, those halcyon days! [return]

Code Reviews

I’ve seen three different iterations of “code review culture”, and all of them have been positive with minor tweaks and changes. What follows is a general list of observations and advice:

“Finding and preventing bugs” is a secondary goal of code reviews, not a primary one.

You shouldn’t be relying on your code reviewers to find bugs; it’s nice to have an extra set of eyes who can point them out, but it’s your job as the implementer and tester to ensure correctness.

Everyone and everything should be subject to code reviews.

An atmosphere where senior engineers don’t have to go through CRs is bad: it implies poor things about your development hierarchy, like the idea that seniority means your code is immune to critique.

An atmosphere where critical bug fixes don’t have to go through CRs is bad: it implies you don’t have a testing/rollback framework set up to avoid the need to push unreviewed code.

Code reviews should not be more than X lines of code.

Anything more than X and diminishing returns set in. What X is varies from language to language and context to context, but 200 is a pretty good number. (If your immediate reaction to this is “but most changes are more than 200 lines of code”, my immediate reaction is: nah.)

Super-basic style comments should not be in code reviews.

Like, they will be — someone (you!) is going to leave out a semicolon or mess up spacing, and that should be addressed in a review comment.

But if that’s the norm and not a occassional slip-up, then that’s a sign that you don’t have a documented code style. Whenever you or someone else comments we prefer null coalescing to ternaries here or whatever, that comment should go into a wiki and a lintfile so such issues can be automatically detected. 1 The goal is to avoid work that can (and should) be automated so reviewers can focus on the important stuff.

(Automation is always preferable to documentation: it’s nice to have a central resource for these things, but it’s much nicer to have that central resource be your IDE or a pre-commit hook.)

Don’t be an asshole.

People have a wide range of how they internalize code reviews, and it is often hard to separate critique of code from critique of the coder. The best way to do this is to approach code reviews not as an adversarial process, but as a collaborative discovery of the best possible implementation.

A great way to do this that some folks gloss over: write positive comments in CRs. Positive reinforcement is just as helpful as constructive criticism: praising someone’s tests or the way they structured some tricky business logic doesn’t just make them feel good, it enforces that behavior for themselves and others.

Be prompt.

The largest personal and institutional grievance folks have with code reviews is that they gum up the works and increase the time it takes to deploy code. Set team-wide practices on healthy expectations for when code should be reviewed and stick to them.

Be rigorous.

The woooooooorst thing to experience as a review-ee:

  1. You post some code.
  2. A reviewer makes comments A, B, and C.
  3. You address those comments and post the new code, asking for a new round of review.
  4. The same reviewer makes comments D, E, and F, all of which could have been made during the original review pass.

The woooooooorst thing to experience as a reviewer:

  1. Someone posts some code.
  2. You make comments A, B, C, and D.
  3. They address only A and D and post the new code, asking for another round of review.

Keep at it!

Code reviews can be long and they can be difficult but they are good for the long term health of your code base, just like building out a test suite or documentation.

Some further reading:

Thanks to Kelly Sutton, Iheanyi Ekechukwu, and Chad Little for reviewing this post. (And thanks to Michelle, Daniel, Andy, and countless others for reviewing my code over the years, and teaching me how to review well. 2)

  1. Hound is also great for this. [return]
  2. And occasionally putting up with my terrible code. [return]

"We're just ordinary and forever"

Everyone is rightfully super pumped about 17776, the newest project by Jon Bois.

It’s awesome to see Bois get wider recognition. His work on the Tim Tebow CFL Chronicles, Breaking Madden, and other things have been plumbing the depths of absurdist storytelling for a few years now, but this is his most ambitious project, and it’s kind of amazing to watch him get linked by a bunch of media and tech guys. 1

And, to talk briefly about the actual content of the piece: it’s halfway-ish published at this point, and it’s really really great. It jumps from the aesthetics of lunchables to a Vonnegut-esque humanity of machines to the quiet crises of immortality in a way that is totally dextrous and entertaining.

Emma Phipps has a good take on its place in the landscape of Internet Content:

Because, on its surface, 17776 is bad content. It’s weird, it’s long, it demands attention. It’s not skimmable. In the age of virality, this is the kind of that would probably get laughed out of most pitch meetings, if anyone even had the courage to bring it up in a pitch meeting. Going purely off of the established rules of Good Internet Content, this should not even exist.

This is a valuable idea to mine: that the same media economy that justifies the existence of something as value-neutral as The Ringer can also allow the existence of this. 2

But mostly, I’m just happy that something so brazenly weird exists, that I can be still so surprised and delighted by something in form and content, and that everyone else is taking to it so warmly too.

As the deluge of content swells and swells, a question I keep coming back to is “will I remember anything about this book/blog post/podcast/album/game/show in a month? In a year? Does it have any lasting value?”

I don’t see myself forgetting about 17776.

  1. This is definitely the first time SB Nation has been linked on Daring Fireball, right? [return]
  2. Worth noting: 17776 has no ads, as far as I can tell. It’s less profitable than five hundred hastily written words about The House. [return]

Someone who's still on the dock

Michael Crichton, as quoted in The Art of Editing, ostensibly talks about editing but really talks about a great many other things:

In my experience of writing, you generally start out with some overall idea that you can see fairly clearly, as if you were standing on a dock and looking at a ship on the ocean. At first you can see the entire ship, but then as you begin work you’re in the boiler room and you can’t see the ship anymore. All you can see are the pipes and the grease and the fittings of the boiler room and, you have to assume, the ship’s exterior. What you really want in an editor is someone who’s still on the dock, who can say, Hi, I’m looking at your ship, and it’s missing a bow, the front mast is crooked, and it looks to me as if your propellers are going to have to be fixed.


Long before wisdom

I am loathe to applaud venture capitalists for saying sensible things, but Mark Cuban said some very sensible things on Twitter (and was quoted in this relevant Quartz story):

I personally think there’s going to be a greater demand in 10 years for liberal arts majors than there were for programming majors and maybe even engineering, because when the data is all being spit out for you, options are being spit out for you, you need a different perspective in order to have a different view of the data. [You need] someone who is more of a freer thinker.

And, in the tweet itself:

Artficial intelligence will write programs long before they create wisdom.

Steinbeck once wrote that I guess the trouble [with socialism] was that we didn’t have any self-admitted proletarians. Everyone was a temporarily embarrassed capitalist.

Similarly, I think most STEM majors — or at least most programmers — think of themselves less as self-admitted truck drivers who drive a different genre of truck and more as practitioners of something that approaches philosophy.

I don’t think AI is as close as a lot of people think it is; but I don’t think it’s as far away as a lot of people think it is, either.


Ten arguments

I just finished 300 Arguments, a series of aphorisms, vignettes, and truisms.

I recommend it: it’s not perfect, and a lot of the observations tend towards the vacuous, but the process of reading it is so quick and frictionless that it’s worth wading through the banality – like watching an okay movie that has a couple transcendent scenes.

My favorite ten “arguments”:

I don’t miss the city. I miss the place it was in the nineties, when everyone else also was twenty-two and broke.

Only a fire can teach you what survives a fire. No, it teaches you what can survive that fire.

I fret about my lost scarf. Then I miss my flight.

I’ve written whole books in order to avoid writing other books.

The true nobility put their inferiors at ease—by being kind to them? No, by dismantling the system for a moment.

The first beautiful songs you hear tend to stay beautiful because better than beauty, which is everywhere, is the memory of first discovering beauty.

With great and solemn portent, my teacher announced she would tell us something that her teacher had told her, and that her teacher’s teacher had told him, and so on, back to Yeats: The thing to remember is that no one ever finds out that you don’t know what you’re doing.

Bad art is from no one to no one.

Biographies should also contain the events that failed to foreshadow.

Every case is orthogonal to all the others. That’s the entire problem.


Django vs. Flask

A great, thorough writeup on Django vs. Flask has been floating around the past few days. It’s a great technical breakdown, and I agree with the conclusion:

There’s an informal perception that Batteries included may mean a growing list of ill-maintained API’s that get hooked into every request. In the case of Django, everything works across the board. When an internal Django API changes, Django’s testsuites to break and the appropriate changes are made. So stuff integrates. This is something that’s harder to do when there’s a lot of packages from different authors who have to wait for fixes to be released in Flask’s ecosystem.

However, it also glosses over what is probably the strongest weapon in Django’s arsenal: Django Rest Framework. At this point, I essentially consider DRF a first-party package: it is so completely essential to my Python web development toolbox I can’t imagine working without it.

Having such a powerful, extensible approach to REST (and everything that entails: serialization, permissions, filtering…) is invaluable. Flask is great for toy projects, but for a modern application DRF is unreplaceable, and thus so is Django.

(Another important thing that Django does: it forces a certain level of structure and organization to your application. I used to think this was either unnecessarily or actively harmful: now, having seen my fair share of eldritch Python codebases, I know better.)

© 2017 Justin Duke • All rights reserved • I hope you have a nice day.