Applied Cartography

Essays, notes, and esoterica from Justin Duke
https://jmduke.com/ (RSS)
visit blog
VC does not guarantee PMF
3 Nov 2024 | original ↗

Two companies that I started following (with no small amount of envy) back in 2021: Hype (fka Pico) sold to an MMA-themed holdco earlier this year. Raised a $4.5m seed from Stripe and Bloomberg Beta and a $10m Series A; crossed the finish line at $200K ARR after eight years. Stir (which raised $16M from a16z at a $100M valuation) informally...

October, 2024
2 Nov 2024 | original ↗

Hello! Lots of writing in October (what early parenthood takes away in terms of deep flow, it gives back in terms of twenty-minute pockets of time and thought): On the content front, I wrote about Monster Sanctuary (a delightful JRPG), The Anderson Tapes (a solid late-period Sean Connery heist), Trust (a rare postmodern novel that I disliked),...

Bozos
1 Nov 2024 | original ↗

Kevin Twohy has a list of heuristics for new projects/clients, and my favorite is simple: No Bozos. Simple policy. No exceptions. You know it when you see it. Every founder has a story about the time that they ignored the red flags and bent over backwards for a particularly standoffish or problematic customer/prospect/client/hire. It's easy to...

Meta's two assets
30 Oct 2024 | original ↗

(Epistemic disclaimer: there are few Extremely Big Tech Companies to whom I feel apathy more vividly than Meta. I had a Facebook account in high school and college and got rid of it at some point post-graduation, though I'd be hard-pressed to tell you when exactly that was.) It was fun to listen to Acquired's six-hour episode on Meta. Ben and...

Projects are things with steps
28 Oct 2024 | original ↗

Lots of kind words poured in as a response to My approach to GTD and PKM, and one question was asked so frequently that I decided to write about it. Why is “Get mom a birthday present” a project and not a task? GTD is very orthodox in what a “project” is: it’s anything that: you think you’ll complete in the next year requires more than one step...

Notebook as marketing primitive
23 Oct 2024 | original ↗

Earlier this week, I stumbled upon this brilliant marketing-slash-documentation idea from SingleStore — notebooks as a first-party page! There are a handful of nice things about this idea: Very easy to fan out. You're not going to really run out of sample notebooks from which you can create pages. Easy to share and 'productize'. Lends itself...

My approach to GTD and PKM
22 Oct 2024 | original ↗

One pernicious thing with writing about productivity and knowledge systems: you only change systems that aren’t working, and you tend to write about things during times of change. So most writing about productivity systems stem from people whose systems have failed them. It is with this ironic prologue that I answer a question I've received from...

Consider the data product
21 Oct 2024 | original ↗

The advice might seem dated these days, but I think the stair step approach to bootstrapping is evergreen: It’s much easier to sell an add-on to an existing ecosystem like a WordPress plugin, a Shopify app, a Heroku add-on – they’re usually small things to build, relatively inexpensive for customers to purchase, and you have built in discovery...

You should build this:
19 Oct 2024 | original ↗

A prior iteration of this site had a page called "Project ideas" that listed a bunch of things that I'd like to build. This was a good idea and useful in its own right (I got a few people to build companies and projects based on them, and it was a useful avenue by which folks could tell me which ideas were already implemented.) I still haven't...

Migrating to Django 5
17 Oct 2024 | original ↗

The total LOC delta to migrate Buttondown from Django 4 to Django 5 was +143, -150. (I was incentivized to do so because our search right now is quite slow, and the lowest hanging piece of fruit is to move some of the tsvector generation out of band, and I'd rather do that using the fancy new GeneratedField abstraction than rolling the SQL...

Applied Cartography × People & Blogs
15 Oct 2024 | original ↗

There are few pleasures greater than getting to be profiled for an interview series that you've been reading for months, and last week I got to do exactly that. To browse Manu's site — not just this interview series — feels a bit like walking on a quiet beach in autumn: there's a sense of peace and timelessness that is hard to find in the hustle...

Talking to customers
13 Oct 2024 | original ↗

You say that these numbers mean dial it down. I say they mean dial it up. You haven't gotten through. There are people you haven't persuaded yet. These number mean dial it up. Otherwise you're like the French radical, watching the crowd run by and saying, "There go my people. I must find out where they're going so I can lead them." I ran into a...

Notes on Zed, revisited
11 Oct 2024 | original ↗

A little over six months ago, I wrote Notes on Zed. My conclusion at that time was that Zed made a lot of great choices and felt really good to use, but lacked parity with VS Code's feature/ecosystem to its detriment. Six months later, I spent a few days using it as my daily driver to see what had changed: It's still really, really fast — and in...

Two weeks of parenthood
10 Oct 2024 | original ↗

We've had Lucy for two weeks, which qualifies us as experts, which means it is time to write about parenthood. (In all seriousness, consider the below descriptive and not prescriptive: mostly, it's a notepad filled with things that were remarkable or surprising or divergent from popular consensus.) American pop culture puts too much emphasis on...

Applied Cartography × Indie Rails
4 Oct 2024 | original ↗

Chatted with Jess and Jeremy about a whole slew of things, from pricing strategy to terrifying and arcane differences between various Markdown parsers (including why I hate Slack.) They were particularly kind and gracious given that the amount of production-quality Rails I've written is ~zero; you'll enjoy this even if Ruby/Rails is not your cup...

Always use an enum for your status field
14 Sept 2024 | original ↗

When I was first starting my career at Amazon — even more bright-eyed and rosy-cheeked than I am now — I was thrilled by the concept of an "architecture review", and by extension the concept of a "Principal Engineer" (Amazon's term for a staff-level engineer, someone beyond career level) who was always treated with some level of mystique and...

Why your marketing site should be separate
12 Sept 2024 | original ↗

In Notes on buttondown.com and How Buttondown uses HAProxy, I outlined the slightly kludgy way we serve buttondown.com both as a marketing site (public-facing, Next/Vercel, largely just content pushed by non-developers) and an author-facing app (behind a login, Django/Heroku/Vue) and recommended developers not do that and instead just do the...

MD5-based uniqueness constraints in Django
5 Sept 2024 | original ↗

Yesterday, I was trying to set a unique constraint for comments in Buttondown to prevent accidental double-commenting, and I ran into a problem that I hadn't seen before: index row size 2816 exceeds btree version 4 maximum 2704 for index "emails_comment_email_id_subscriber_id_text_0542cca9_uniq" DETAIL: Index row references tuple (165,7) in...

Improving Django's default pagination performance
5 Sept 2024 | original ↗

Yesterday, I was trying to set a unique constraint for comments in Buttondown to prevent accidental double-commenting, and I ran into a problem that I hadn't seen before: index row size 2816 exceeds btree version 4 maximum 2704 for index "emails_comment_email_id_subscriber_id_text_0542cca9_uniq" DETAIL: Index row references tuple (165,7) in...

RSS in Next 14
5 Sept 2024 | original ↗

We finished Buttondown’s migration from MDX to Markdoc last week. It went swimmingly, except for one little hitch: our RSS feeds, which sat on top of getServerSideProps and read in the flat .mdoc files, threw 500s in Vercel. (They worked fine locally and in CI, but then those files were purged by Vercel as part of the post-compile deploy.) I was...

Notes on 'Founder Mode' / Lieutenancy
1 Sept 2024 | original ↗

In Paul Graham’s latest essay, he writes: The theme of Brian's talk was that the conventional wisdom about how to run larger companies is mistaken. As Airbnb grew, well-meaning people advised him that he had to run the company in a certain way for it to scale. Their advice could be optimistically summarized as "hire good people and give them room...

Notes on 'Founder Mode' / Lieutenancy
1 Sept 2024 | original ↗

In Paul Graham’s latest essay, he writes: The theme of Brian's talk was that the conventional wisdom about how to run larger companies is mistaken. As Airbnb grew, well-meaning people advised him that he had to run the company in a certain way for it to scale. Their advice could be optimistically summarized as "hire good people and give them room...

Keeping a technical edge
29 Aug 2024 | original ↗

Someone emailed me in response to Two years as an independent technologist, in which I wrote: I miss of being at a large company, which is dealing with deeply cutting-edge technical problems, but my ability to analyze information, make decisions, and perform at a high-level has grown very quickly. They followed up: I had a lot of trepidation...

Keeping a technical edge
29 Aug 2024 | original ↗

Someone emailed me in response to Two years as an independent technologist, in which I wrote: I miss of being at a large company, which is dealing with deeply cutting-edge technical problems, but my ability to analyze information, make decisions, and perform at a high-level has grown very quickly. They followed up: I had a lot of trepidation...

How Buttondown uses HAProxy
27 Aug 2024 | original ↗

There are few technical decisions I regret more with Buttondown than the decision to combine the author-facing app, the subscriber-facing app, and the marketing site all under a single domain. Most technical decisions are reversible with sufficient grit and dedication; this one is not, because it requires customers to change their URLs and...

How Buttondown uses HAProxy
27 Aug 2024 | original ↗

There are few technical decisions I regret more with Buttondown than the decision to combine the author-facing app, the subscriber-facing app, and the marketing site all under a single domain. Most technical decisions are reversible with sufficient grit and dedication; this one is not, because it requires customers to change their URLs and...

Notes on buttondown.com
26 Aug 2024 | original ↗

We spent $85,000 for buttondown.com in April; this was the biggest capital expenditure I've ever made, and though it was coming from cash flow generated by Buttondown rather than my own checking account it was by rough estimation the largest non-house purchase I've ever made. As of August, we're officially migrated over from buttondown.email to...

Notes on buttondown.com
26 Aug 2024 | original ↗

We spent $85,000 for buttondown.com in April; this was the biggest capital expenditure I've ever made, and though it was coming from cash flow generated by Buttondown rather than my own checking account it was by rough estimation the largest non-house purchase I've ever made. As of August, we're officially migrated over from buttondown.email to...

Using Cursor to port Django tests to pytest
25 Aug 2024 | original ↗

When it comes to AI tooling, I am equal parts optimist and cynic. I have no moral qualm with using these tools (Supermaven is a pretty heavy part of my day-to-day work), but have found most tools quite bad by the metric of "do they make me more productive on Buttondown's code base?" I think it's important to be able to taste the kool-aid with...

Using Cursor to port Django tests to pytest
25 Aug 2024 | original ↗

When it comes to AI tooling, I am equal parts optimist and cynic. I have no moral qualm with using these tools (Supermaven is a pretty heavy part of my day-to-day work), but have found most tools quite bad by the metric of "do they make me more productive on Buttondown's code base?" I think it's important to be able to taste the kool-aid with...

Improving Django's default pagination performance
10 Aug 2024 | original ↗

Buttondown's API calls are very fast, and one of the reasons why is that we've removed every single possible database query that we can. The most recent was what looked like a fairly benign COUNT(*) query, coming from the default Django paginator; if you're gonna paginate things, you need to know how many to paginate, fair enough. However, it...

Improving Django's default pagination performance
10 Aug 2024 | original ↗

Buttondown's API calls are very fast, and one of the reasons why is that we've removed every single possible database query that we can. The most recent was what looked like a fairly benign COUNT(*) query, coming from the default Django paginator; if you're gonna paginate things, you need to know how many to paginate, fair enough. However, it...

Peak Newsletter
15 Jul 2024 | original ↗

A handful of folks sent me this quip from Nate Silver a few days ago: Slightly against interest to admit this (I don't want more competition lol) but I think we're still probably a year or two away from Peak Newsletter. It's just a really good distribution mechanism for certain types of writers. It does take some time to build up momentum,...

Peak Newsletter
15 Jul 2024 | original ↗

A handful of folks sent me this quip from Nate Silver a few days ago: Slightly against interest to admit this (I don't want more competition lol) but I think we're still probably a year or two away from Peak Newsletter. It's just a really good distribution mechanism for certain types of writers. It does take some time to build up momentum,...

Incumbency
10 Jul 2024 | original ↗

Andrew Rea with an interesting and increasingly familiar take about how AI will disrupt software-focused private equity: Distribution and brand moats can protect your legacy products for a while (esp in enterprise) but eventually you get lapped by competitors with better products, service, pricing, etc. Software is too competitive and changes too...

Incumbency
10 Jul 2024 | original ↗

Andrew Rea with an interesting and increasingly familiar take about how AI will disrupt software-focused private equity: Distribution and brand moats can protect your legacy products for a while (esp in enterprise) but eventually you get lapped by competitors with better products, service, pricing, etc. Software is too competitive and changes too...

Content debt
8 Jul 2024 | original ↗

There’s a nascent trend of releasing ostensibly-private material (changelogs, public wikis, handbooks, etc.) to the public as a bit of a marketing push. This is essentially a form of debt, to the extent that you’re taking a lump-sum payment now in exchange for the implicit cost of keeping these things “up to date” indefinitely (and if you don’t,...

Content debt
8 Jul 2024 | original ↗

There’s a nascent trend of releasing ostensibly-private material (changelogs, public wikis, handbooks, etc.) to the public as a bit of a marketing push. This is essentially a form of debt, to the extent that you’re taking a lump-sum payment now in exchange for the implicit cost of keeping these things “up to date” indefinitely (and if you don’t,...

Against Against Innovation Tokens
4 Jul 2024 | original ↗

Glyph (whose writing and contributions to the Python ecosystem I am deeply grateful for) wrote Against Innovation Tokens yesterday: In 2015, Dan McKinley laid out a model for software teams selecting technologies. He proposed that each team have a limited supply of “innovation tokens”, and, when selecting a technology, they can choose boring ones...

Against Against Innovation Tokens
4 Jul 2024 | original ↗

Glyph (whose writing and contributions to the Python ecosystem I am deeply grateful for) wrote Against Innovation Tokens yesterday: In 2015, Dan McKinley laid out a model for software teams selecting technologies. He proposed that each team have a limited supply of “innovation tokens”, and, when selecting a technology, they can choose boring ones...

Pytest: test for print statements
27 Jun 2024 | original ↗

Inspired by Adam Johnson's test for pending migrations, and of course in conversation with my own love of weird tests, I offer a similar concept: a test for finding stray print statements in your codebase, with a ratchet array for stuff to ignore. import glob PATH = "**/*.py" irrelevant_paths = ( "/commands/", "node_modules", ) def...

Pytest: test for print statements
27 Jun 2024 | original ↗

Inspired by Adam Johnson's test for pending migrations, and of course in conversation with my own love of weird tests, I offer a similar concept: a test for finding stray print statements in your codebase, with a ratchet array for stuff to ignore. import glob PATH = "**/*.py" irrelevant_paths = ( "/commands/", "node_modules", ) def...

Typesafe routes in Vue
19 Jun 2024 | original ↗

I watched Gary Bernhardt's talk on static routing back a few years ago and — I'm not sure if I would call it formative, but it stuck in my craw as a platonic ideal of sorts, as something I couldn't really justify adopting within Buttondown but really wanted. I built out and open-sourced some feints in this direction — see...

Typesafe routes in Vue
19 Jun 2024 | original ↗

I watched Gary Bernhardt's talk on static routing back a few years ago and — I'm not sure if I would call it formative, but it stuck in my craw as a platonic ideal of sorts, as something I couldn't really justify adopting within Buttondown but really wanted. I built out and open-sourced some feints in this direction — see...

Where to hitch your wagon
14 Jun 2024 | original ↗

When I wrote Your job is to produce value, I got a few responses that could be summed up as something along the lines of: Telling developers to get better at reading and writing and problem solving is sort of like telling them to get better at writing fewer bugs: it might be true, but it's anodyne and unactionable. First off: this is not true,...

Zero draft
12 Jun 2024 | original ↗

This quote from Peter Drucker, via @zetalyrae resonates a lot: Write a report may, for instance, require six or eight hours, at least for the first draft. It is pointless to give seven hours to the task by spending fifteen minutes twice a day for three weeks. All one has at the end is blank paper with some doodles on it. But if one can lock the...

Canned cocktails
4 Jun 2024 | original ↗

Canned cocktails, despite the inherit oxymoron, are on the rise. I have friends ask me which ones they should get, if any — I also have friends and family give me a good amount. In general: they are all bad. There are exactly two exceptions: Tiptop Cocktails and Straightaway Cocktails. Both of these are delicious, well-packaged, and a gift that a...

RIP, Bedkit
3 Jun 2024 | original ↗

In late 2022 I had designs on starting a new little tool, pulling out some useful but gnarly code out of Buttondown for rendering tweets (and other such similar media) and productizing it. It was called Bedkit, and the splash page is still live for the next few days. In a rare display of realism and humility, I am letting the domain name pass....

Notes from May
2 Jun 2024 | original ↗

Lots of writing this month: Why you should use Rails A reminder that things take time How shadcn/ui's previews work Why I hate that 1.01% meme A lovely term, 'grace note' Au revoir, invoke! A quick check-in on 11ty A rant/snippet for auth.js The first edition of what will be a long, living document on ActivityPub A handy git one-liner Why it's...

Notes from May
2 Jun 2024 | original ↗

Lots of writing this month: Why you should use Rails A reminder that things take time How shadcn/ui's previews work Why I hate that 1.01% meme A lovely term, 'grace note' Au revoir, invoke! A quick check-in on 11ty A rant/snippet for auth.js The first edition of what will be a long, living document on ActivityPub A handy git one-liner Why it's...

The taste of beer
31 May 2024 | original ↗

Unlike stories, real life, when it has passed, inclines toward obscurity, not clarity. There’s a relatively famous line from Bezos, circulated first at YC in ’08 and then more recently by the folks at Acquired (a great pod!): Jeff uses this analogy for AWS. He talks about European beer breweries around the turn of the 20th century. Electricity...

The taste of beer
31 May 2024 | original ↗

Unlike stories, real life, when it has passed, inclines toward obscurity, not clarity. There’s a relatively famous line from Bezos, circulated first at YC in ’08 and then more recently by the folks at Acquired (a great pod!): Jeff uses this analogy for AWS. He talks about European beer breweries around the turn of the 20th century. Electricity...

Git one-liner: get the earliest commit from X hours ago
23 May 2024 | original ↗

I wanted to get a commit that was temporally some distance back as part of my experimentation with git cliff. This took some time to do, but here's what I ended up with: git log --since="72 hours ago" --until="now" --reverse --pretty=format:"%h" | head -1 Nothing particularly fancy, but I hope it's useful!

Why can't you just...?
23 May 2024 | original ↗

Buried in a snarky thread about why Google Calendar doesn’t support calendar syncing is a long, detailed explanation of why shipping this sort of thing is hard: Designing a consent experience for the enterprise admin and enterprise end user Creating a special "read only" object type that's only populated via one-way sync from a consumer account....

Git one-liner: get the earliest commit from X hours ago
23 May 2024 | original ↗

I wanted to get a commit that was temporally some distance back as part of my experimentation with git cliff. This took some time to do, but here's what I ended up with: git log --since="72 hours ago" --until="now" --reverse --pretty=format:"%h" | head -1 Nothing particularly fancy, but I hope it's useful!

Why can't you just...?
23 May 2024 | original ↗

Buried in a snarky thread about why Google Calendar doesn’t support calendar syncing is a long, detailed explanation of why shipping this sort of thing is hard: Designing a consent experience for the enterprise admin and enterprise end user Creating a special "read only" object type that's only populated via one-way sync from a consumer account....

Notes on ActivityPub
22 May 2024 | original ↗

By far the single most-fruitful tactic has been "just look at raw GET responses from Mastodon and see what things are shaped like." I know that "ActivityPub is under-specified" is a bit of a meme, but it's wild how little prior art there is. Something that gives distinctly bad vibes: ostatus.org (which ostensibly describes a bunch of the schemae...

Notes on ActivityPub
22 May 2024 | original ↗

By far the single most-fruitful tactic has been "just look at raw GET responses from Mastodon and see what things are shaped like." I know that "ActivityPub is under-specified" is a bit of a meme, but it's wild how little prior art there is. Something that gives distinctly bad vibes: ostatus.org (which ostensibly describes a bunch of the schemae...

Auth.js + Square
20 May 2024 | original ↗

Internal tools and small, well-scoped projects are a great avenue to tinker with technologies on the periphery of your understanding, and a Third South project has led me to spin up a small Next project using Bun [1] and Auth.js (nee next-auth), which has been quite bad and I think successfully dissuaded me from using it in any more serious...

Auth.js + Square
20 May 2024 | original ↗

Internal tools and small, well-scoped projects are a great avenue to tinker with technologies on the periphery of your understanding, and a Third South project has led me to spin up a small Next project using Bun [1] and Auth.js (nee next-auth), which has been quite bad and I think successfully dissuaded me from using it in any more serious...

11ty, three months later
19 May 2024 | original ↗

This weekend marks the three month mark since spending an international flight migrating this blog to 11ty. I think in many ways the true metric by which to gauge the success of a given blogging engine is how much time you spend writing and publishing content relative to how much time you spend futzing with the various knobs, whistles, and...

Au revoir, Invoke
18 May 2024 | original ↗

It's not quite interesting or noteworthy enough to warrant a full-on essay, but yesterday we unshipped the last remaining Invoke commands and ported them over to just. I think Invoke is a good, cool project, and I wish it well. If you're at the precise intersection of "you have shell commands that need to be encapsulated in some source of truth",...

Au revoir, Invoke
18 May 2024 | original ↗

It's not quite interesting or noteworthy enough to warrant a full-on essay, but yesterday we unshipped the last remaining Invoke commands and ported them over to just. I think Invoke is a good, cool project, and I wish it well. If you're at the precise intersection of "you have shell commands that need to be encapsulated in some source of truth",...

Grace notes
14 May 2024 | original ↗

I'm not loving Unreasonable Hospitality, but it did supply me with a phrase that I've been looking for: Eventually, that gesture became one of our steps of service. The host would ask guests, “How’d you get here tonight?” If they responded, “Oh, we drove,” he’d follow up with, “Cool” Where’d you park?” If they told him they were by a meter on the...

Grace notes
14 May 2024 | original ↗

I'm not loving Unreasonable Hospitality, but it did supply me with a phrase that I've been looking for: Eventually, that gesture became one of our steps of service. The host would ask guests, “How’d you get here tonight?” If they responded, “Oh, we drove,” he’d follow up with, “Cool” Where’d you park?” If they told him they were by a meter on the...

44%
13 May 2024 | original ↗

If you spend enough time digesting hackneyed business or self-improvement advice, you've probably seen someone wax poetic about the following image: This is meant to be an illustration of the power of incrementalism (often referred to as kaizen when the writer is trying to be particularly obscure/profound) [1]. Get 1% better every single day, and...

44%
13 May 2024 | original ↗

If you spend enough time digesting hackneyed business or self-improvement advice, you've probably seen someone wax poetic about the following image: This is meant to be an illustration of the power of incrementalism (often referred to as kaizen when the writer is trying to be particularly obscure/profound) [1]. Get 1% better every single day, and...

How shadcn/ui examples work
11 May 2024 | original ↗

I’m increasingly convinced that for developer-first tools, a really good docs experience is a durable, non-trivial advantage. Part of this thesis is that Really Good Docs Experiences, in addition to having great information architecture and strong writing/prose, should be thought of less as ancillary content repositories that can be farmed out to...

How shadcn/ui examples work
11 May 2024 | original ↗

I’m increasingly convinced that for developer-first tools, a really good docs experience is a durable, non-trivial advantage. Part of this thesis is that Really Good Docs Experiences, in addition to having great information architecture and strong writing/prose, should be thought of less as ancillary content repositories that can be farmed out to...

Things take time
8 May 2024 | original ↗

Things take time. Nintendo fairly famously was born in 1889, and the modern incarnation — Yamamuchi Nintendo & Co., LTD — was established nearly fifty years later, in 1933. They spent forty years selling playing cards, then another decade operating merely as a distributor of electronics before coming out with their first piece of electronic...

Things take time
8 May 2024 | original ↗

Things take time. Nintendo fairly famously was born in 1889, and the modern incarnation — Yamamuchi Nintendo & Co., LTD — was established nearly fifty years later, in 1933. They spent forty years selling playing cards, then another decade operating merely as a distributor of electronics before coming out with their first piece of electronic...

Use Rails
6 May 2024 | original ↗

I have a good number of people ask me what software stack they should use. I always have a two-part answer: Use what you're familiar with. If there's something that you've spent a good amount of time using, stick with that one. Rails. People are usually surprised when I say this because I don't use Rails, and while I spent some time writing Ruby...

Use Rails
6 May 2024 | original ↗

I have a good number of people ask me what software stack they should use. I always have a two-part answer: Use what you're familiar with. If there's something that you've spent a good amount of time using, stick with that one. Rails. People are usually surprised when I say this because I don't use Rails, and while I spent some time writing Ruby...

Notes from April
5 May 2024 | original ↗

Welcome to spring, bona fide and humid. Lots of writing this month: I wrote about spending the past two years as an independent technologist. On the media side of things: brief words on Murderville (meh), The Parallax View (incredible), This is Personal (meh), Cribsheet (solid!). Lots of postging: on friction logs, on AI hype, on Stripe Sessions...

Notes from April
5 May 2024 | original ↗

Welcome to spring, bona fide and humid. Lots of writing this month: I wrote about spending the past two years as an independent technologist. On the media side of things: brief words on Murderville (meh), The Parallax View (incredible), This is Personal (meh), Cribsheet (solid!). Lots of microblogging: on friction logs, on AI hype, on Stripe...

Finding null JSON values in Postgres
30 Apr 2024 | original ↗

Postgres' JSONB functionality is fast and useful but when I find myself dropping down from the Django ORM into SQL to do weird things, the syntax strikes me as confusing and arcane. As such, when I need to do esoteric things it takes me longer time than I'd like, and in hopes that this saves you ten minutes of Stack Overflow trawling: SELECT id,...

Finding null JSON values in Postgres
30 Apr 2024 | original ↗

Postgres' JSONB functionality is fast and useful but when I find myself dropping down from the Django ORM into SQL to do weird things, the syntax strikes me as confusing and arcane. As such, when I need to do esoteric things it takes me longer time than I'd like, and in hopes that this saves you ten minutes of Stack Overflow trawling: SELECT id,...

You need to be frictionlog-maxxing
29 Apr 2024 | original ↗

Lots of people have spent the past few days discussing the perceived increase in difficulty in getting an entry-level programming job relative to the halcyon ZIRP days of yesteryear. I am sympathetic to new grads running into this; I am dismayed that when I ask some [1] of them what they've been doing their answer boils down to "sending out my...

You need to be frictionlog-maxxing
29 Apr 2024 | original ↗

Lots of people have spent the past few days discussing the perceived increase in difficulty in getting an entry-level programming job relative to the halcyon ZIRP days of yesteryear. I am sympathetic to new grads running into this; I am dismayed that when I ask some [1] of them what they've been doing their answer boils down to "sending out my...

You gotta be able to taste the kool-aid
25 Apr 2024 | original ↗

Cognition, a six-month-old startup in the AI coding space just raised $175m at a $2b valuation: Despite the skepticism surrounding Devin’s launch, the AI coding assistant has shown promising results. According to the SWE-Bench benchmark, which evaluates AI models on software engineering tasks, Devin achieved a 13.86% accuracy in resolving issues...

You gotta be able to taste the kool-aid
25 Apr 2024 | original ↗

Cognition, a six-month-old startup in the AI coding space just raised $175m at a $2b valuation: Despite the skepticism surrounding Devin’s launch, the AI coding assistant has shown promising results. According to the SWE-Bench benchmark, which evaluates AI models on software engineering tasks, Devin achieved a 13.86% accuracy in resolving issues...

Stripe Sessions 2024
24 Apr 2024 | original ↗

Stripe held the keynote for Sessions, their annual WWDC/re:invent-esque conference, this morning. I wanted to jot down some thoughts while they’re still fresh. (I think the changelog is the best way to poke around both the changes I’m writing about and the ones that I omitted.) Caveat / disclosure I am a Stripe user and shareholder. That being...

Stripe Sessions 2024
24 Apr 2024 | original ↗

Stripe held the keynote for Sessions, their annual WWDC/re:invent-esque conference, this morning. I wanted to jot down some thoughts while they’re still fresh. (I think the changelog is the best way to poke around both the changes I’m writing about and the ones that I omitted.) Caveat / disclosure I am a Stripe user and shareholder. That being...

Your job is to produce value
22 Apr 2024 | original ↗

Two people who I think are smart and good both said things that I bump up against [1]: "The software industry is rapidly converging on just three languages: Go, Rust, and JS. It would be smart to learn one of those really well, and have at least a working acquaintance with the other two." Lately, “Design Engineer” has felt more and more like a...

Weird test: internal link checking
20 Apr 2024 | original ↗

I wrote last month about using weird tests. Here's another example: checking for broken internal links in our upcoming docsite redesign! const extractInternalLinks = (content: string): string[] => { // Check for internal links only, in the form of [text](/path). const internalLinks = content.match(/\[.*?\]\(\/.*?\)/g); return ( ...

Two years as an independent technologist
20 Apr 2024 | original ↗

This week marks two full years since I left Stripe and started what in retrospect is a new (and likely) final phase of my career as an independent technologist. I didn’t quite know what that would entail at the time: it turned out to be a combination of founder (my work at Buttondown) and managing partner (my work at Third South). I wanted to put...

Weird test: internal link checking
20 Apr 2024 | original ↗

I wrote last month about using weird tests. Here's another example: checking for broken internal links in our upcoming docsite redesign! const extractInternalLinks = (content: string): string[] => { // Check for internal links only, in the form of [text](/path). const internalLinks = content.match(/\[.*?\]\(\/.*?\)/g); return ( ...

Seattle Forever
18 Apr 2024 | original ↗

Magnuson Park on a lazy Saturday in July; Golden Gardens on a rare sunny October day; Top Pot (for nostalgia's sake); Gasworks; Taste of India; Unicorn (and living across the street from it for two years); the Vivace sidewalk stand (where I made my first Seattle friend, hi Shep); Zig Zag; coffee-walks around Green Lake; Freeway Park; the bar at...

Why Buttondown isn't OSS
15 Apr 2024 | original ↗

A number of people have asked me in the past week why Buttondown isn't open-source, given: the love and overt financial commitment we have to open source the increasing number of "open source startups" (Cal, Maybe, Lago coming to mind) I preface this answer with the fact that this is coming from my personal blog and not Buttondown's blog, and...

defineModel is dope
11 Apr 2024 | original ↗

I find myself spending very little time enjoying Vue. Which is not to say I hate it, but that I don't have a lot of fun with it — I've reached a sort of intellectual detente with the framework, and most of my "fun frontend time" is spent in pure functional TypeScript. But I was delighted to discover a change in Vue 3.4 that makes life 2% better...

Tailwind black magic: swallowing all pointer events
31 Mar 2024 | original ↗

I wrote two days ago about a real and useful application of Tailwind black magic; here's another. Buttondown has a dropzone component lets folks drag-and-drop items or click on it to get a file-picker. It's used for importing images, archives, CSVs, the works: because it's so flexible, we expose a slot so that components can customize the text...

Tailwind black magic: swallowing all pointer events
31 Mar 2024 | original ↗

I wrote two days ago about a real and useful application of Tailwind black magic; here's another. Buttondown has a dropzone component lets folks drag-and-drop items or click on it to get a file-picker. It's used for importing images, archives, CSVs, the works: because it's so flexible, we expose a slot so that components can customize the text...

Tailwind black magic: styling paragraphs within tables
29 Mar 2024 | original ↗

The new version of the Buttondown docs site is all in on Keystatic, Markdoc, and Tailwind's typography plugin — which makes it really easy to author beautiful docs in plaintext. We ran into one small issue, which is that the Markdoc renderer likes to place paragraph tags in table cells, such that: | Column |...

Tailwind black magic: styling paragraphs within tables
29 Mar 2024 | original ↗

The new version of the Buttondown docs site is all in on Keystatic, Markdoc, and Tailwind's typography plugin — which makes it really easy to author beautiful docs in plaintext. We ran into one small issue, which is that the Markdoc renderer likes to place paragraph tags in table cells, such that: | Column |...

Why should a company?
27 Mar 2024 | original ↗

For a long time, my goal with Buttondown was largely around failure avoidance: "I want to get my first paying customer so I know it's not a fake product"; "I want to hit a thousand dollars in revenue so I know it's not just friends humoring me"; "I want to make $10K/mo or else I won't be able to work on it full-time if I want to"; and so on. It's...

Why should a company?
27 Mar 2024 | original ↗

For a long time, my goal with Buttondown was largely around failure avoidance: "I want to get my first paying customer so I know it's not a fake product"; "I want to hit a thousand dollars in revenue so I know it's not just friends humoring me"; "I want to make $10K/mo or else I won't be able to work on it full-time if I want to"; and so on. It's...

Are monopolies bad, actually?
26 Mar 2024 | original ↗

One of the more interesting theses advanced by Zero to One [1] is that monopolies are good to the extent that they afford companies the agency and comfort to engage in long-term activities: Monopolists can think about things other than making money; non-monopolists can’t. In perfect competition, a business is so focused on today’s margins that it...

Are monopolies bad, actually?
26 Mar 2024 | original ↗

One of the more interesting theses advanced by Zero to One [1] is that monopolies are good to the extent that they afford companies the agency and comfort to engage in long-term activities: Monopolists can think about things other than making money; non-monopolists can’t. In perfect competition, a business is so focused on today’s margins that it...

Is cool enough?
21 Mar 2024 | original ↗

Via HN I ran into not one but two extremely neat and pleasant-looking libraries for URL manipulation. They look like great libraries, and a prior version of me would have taken a brief set of cursory glances at the hodgepodge of janky URL manipulation code that I wrote for Buttondown and said "okay, time to rip out all of this and replace it with...

Is cool enough?
21 Mar 2024 | original ↗

Via HN I ran into not one but two extremely neat and pleasant-looking libraries for URL manipulation. They look like great libraries, and a prior version of me would have taken a brief set of cursory glances at the hodgepodge of janky URL manipulation code that I wrote for Buttondown and said "okay, time to rip out all of this and replace it with...

PSA: mess around with Keystatic
20 Mar 2024 | original ↗

We've been using Keystatic in Buttondown for around six months now: we migrated most of the content on the marketing site (which is backed by Next) from MDX onto Keystatic, and were so happy with the experience that the upcoming rebuild of the docs site will be featuring Keystatic as well. It's hard to accurately describe why Keystatic, because...

PSA: mess around with Keystatic
20 Mar 2024 | original ↗

We've been using Keystatic in Buttondown for around six months now: we migrated most of the content on the marketing site (which is backed by Next) from MDX onto Keystatic, and were so happy with the experience that the upcoming rebuild of the docs site will be featuring Keystatic as well. It's hard to accurately describe why Keystatic, because...

On techno-optimism
19 Mar 2024 | original ↗

I consider myself, in a literal sense: a techno-optimist; while technology in of itself is an amoral force, I think it’s pretty hard to disagree with the notion that technological progress has in aggregate advanced humanity’s capacity for love, health, wonder, and joy. Every now and then a piece will come out whose thesis is something like the...

Globals in Histoire
17 Mar 2024 | original ↗

Histoire, like so many other tools in the Vue ecosystem, is a bit of a neglected younger sibling to Storybook — a little bit uglier, with worse documentation and a couple rough edges, but much more tightly integrated with Vue and Vite. [1] One thing that was not particularly obvious with using Histoire was how to declare a global variable. (There...

Globals in Histoire
17 Mar 2024 | original ↗

Histoire, like so many other tools in the Vue ecosystem, is a bit of a neglected younger sibling to Storybook — a little bit uglier, with worse documentation and a couple rough edges, but much more tightly integrated with Vue and Vite. [1] One thing that was not particularly obvious with using Histoire was how to declare a global variable. (There...

There's no such thing as a zero-marginal-cost free tier
16 Mar 2024 | original ↗

In the latest episode of Mostly Technical, Ian brings up ConvertKit as an example of a company for which having a free tier makes more sense than PlanetScale, since there are no marginal costs — you don't need to spin up a large amount of fixed-cost resources for every free customer, and you get those sweet network effects for nothing. I preface...

Notes on Zed
10 Mar 2024 | original ↗

I was late to the VS Code zeitgeist, and as penitence I try to go out of my way to try new editors whenever I see them — which is why this morning I installed Zed, which makes its bones on performance (yay!) and teams functionality (irrelevant for my use cases, but seems abstractly fertile.) First: it is quite fast, and feels good in many of the...

Use weird tests to capture tacit knowledge
4 Mar 2024 | original ↗

Working on Buttondown — or any mature, complex codebase — effectively and quickly requires a lot of tacit knowledge that I've done a hitherto-poor job of documenting, a fact I am learning more and more quickly as I start to scale up the number of folks working on the codebase. Documentation in the literal sense is a good first step and final...

PSA: mess around with Kolo
3 Mar 2024 | original ↗

I had bookmarked Kolo many months ago to try out and finally got a chance to integrate it with Buttondown — a process that I expected to take a couple hours on a lazy Sunday and in fact took ten minutes and three lines of code. If you have a Django app, I think you should drop everything you're doing and install it right now. It is tremendously,...

PSA: mess around with Kolo
3 Mar 2024 | original ↗

I had bookmarked Kolo many months ago to try out and finally got a chance to integrate it with Buttondown — a process that I expected to take a couple hours on a lazy Sunday and in fact took ten minutes and three lines of code. If you have a Django app, I think you should drop everything you're doing and install it right now. It is tremendously,...

Years are magic wands
27 Feb 2024 | original ↗

A couple folks wrote in responding to Vibes and years asking how I did annual planning. I start with a question: "if I had a magic wand, what things would I want to change about the business?" My answers can be concrete or abstract; they can be lofty or object-level. They just have to be the right answers, and they have to be honest. For...

Vibes and years
24 Feb 2024 | original ↗

XH asks: How do indie developers/small teams keep track of and prioritize long-term roadmaps? I've been basically work off my gut + Feeling of the Day for the past few years, and that's getting a bit unsustainable Buttondown's roadmapping has existed for the past three years in a bimodal fashion: In November—December, I spend a lot of active and...

Vibes and years
24 Feb 2024 | original ↗

XH asks: How do indie developers/small teams keep track of and prioritize long-term roadmaps? I've been basically work off my gut + Feeling of the Day for the past few years, and that's getting a bit unsustainable Buttondown's roadmapping has existed for the past three years in a bimodal fashion: In November—December, I spend a lot of active and...

11ty
18 Feb 2024 | original ↗

.njk as the default templating language is an odd choice, and I find myself stubbing my toe on it a good amount. Maybe that's a me thing! It is extremely fast. This site has around 2300 pages; Eleventy is compiling it in around two seconds. The extensibility ergonomics are terrific. This is all it takes to declare a new filter, for instance:...

You should use Helpscout
18 Feb 2024 | original ↗

Was digging through old issues of the personal site and found this draft snippet: I was evaluating HelpScout as a potential first step in a series of many, many steps to onboard a dedicated support engineer for Buttondown, and it turns out that the process of adding custom content to a given conversation (ie the Stripe information, account...

11ty
18 Feb 2024 | original ↗

.njk as the default templating language is an odd choice, and I find myself stubbing my toe on it a good amount. Maybe that's a me thing! It is extremely fast. This site has around 2300 pages; Eleventy is compiling it in around two seconds. The extensibility ergonomics are terrific. This is all it takes to declare a new filter, for instance:...

You should use Helpscout
18 Feb 2024 | original ↗

Was digging through old issues of the personal site and found this draft snippet: I was evaluating HelpScout as a potential first step in a series of many, many steps to onboard a dedicated support engineer for Buttondown, and it turns out that the process of adding custom content to a given conversation (ie the Stripe information, account...

Buttondown Analytics 3.0
11 Feb 2024 | original ↗

Working on a new analytics engine — a scant eleven months after the previous 'new analytics engine'. Calling this 3.0 is a bit of a misnomer: most of the code, design, and plumbing from the 2023 redesign is sticking around, just in a more modular format. The goal here is to address a couple shortfalls in the previous architecture: Business and...

Buttondown Analytics 3.0
11 Feb 2024 | original ↗

Working on a new analytics engine — a scant eleven months after the previous 'new analytics engine'. Calling this 3.0 is a bit of a misnomer: most of the code, design, and plumbing from the 2023 redesign is sticking around, just in a more modular format. The goal here is to address a couple shortfalls in the previous architecture: Business and...

Gosling’s Old Rum
7 Feb 2024 | original ↗

Virginia has draconian liquor laws, which means I have to get interesting bottles shipped from [REDACTED], a site on which I am very prone to judging a book by its cover; every month I'll end up purchasing a bottle of something purely because it looks interesting and I can vaguely imagine it fitting into a couple cocktails down the line. This...

Gosling’s Old Rum
7 Feb 2024 | original ↗

Virginia has draconian liquor laws, which means I have to get interesting bottles shipped from [REDACTED], a site on which I am very prone to judging a book by its cover; every month I'll end up purchasing a bottle of something purely because it looks interesting and I can vaguely imagine it fitting into a couple cocktails down the line. This...

Scattered thoughts on buying software businesses
17 Jan 2024 | original ↗

My friends and I bought five software businesses last year, on the thesis that: despite the recent uptick of interest in the space, it was still a fairly undervalued class of asset; it would be kind of fun and neat. We purchased these businesses after around eight months of sourcing and searching; we've been operating them for a little less than...

Migrating someone who's on Stripe Connect Express
13 Jan 2024 | original ↗

Most Stripe accounts on Substack are “Standard Connect”, which essentially means that: the author has full agency over their account and is the merchant of record; they can revoke OAuth access from Substack (or whomever) at any time; Substack continues to take that 10% as an application fee, though the author (or another connected account) can...

Migrating someone who's on Stripe Connect Express
13 Jan 2024 | original ↗

Most Stripe accounts on Substack are “Standard Connect”, which essentially means that: the author has full agency over their account and is the merchant of record; they can revoke OAuth access from Substack (or whomever) at any time; Substack continues to take that 10% as an application fee, though the author (or another connected account) can...

2023
30 Dec 2023 | original ↗

(You may be interested in last year's annual review.) Health I wrote last year: I am, as I write this, in the best shape of my life In retrospect, this was: a hilarious way to start an essay true, and no longer so. I committed to hitting the 1/2/3/4 club this year, which I accomplished (yay!), but shortly thereafter I fell into what I would...

Mass renaming files in fish on macOS
17 Dec 2023 | original ↗

One of many two-liners to come as I migrate things from the old site onto Obsidian: brew install rename rename "s/.mdx/.md/" **.md

Mass renaming files in fish on macOS
17 Dec 2023 | original ↗

One of many two-liners to come as I migrate things from the old site onto Obsidian: brew install rename rename "s/.mdx/.md/" **.md

Postgres batch enqueuing in ten lines of Django
15 Dec 2023 | original ↗

It hasn't failed me yet: BATCH_SIZE = 100 def batch_proess(queryset) -> None: count = queryset.count() if count == 0: time.sleep(10) return with transaction.atomic(): batch = list( queryset.select_for_update(of=("self",), skip_locked=True).values_list( "id", flat=True ...

Postgres batch enqueuing in ten lines of Django
15 Dec 2023 | original ↗

It hasn't failed me yet: BATCH_SIZE = 100 def batch_proess(queryset) -> None: count = queryset.count() if count == 0: time.sleep(10) return with transaction.atomic(): batch = list( queryset.select_for_update(of=("self",), skip_locked=True).values_list( "id", flat=True ...

What Elephants Taste Like
31 Oct 2023 | original ↗

When I wrote Befriending the Goon Squad — an essay on the importance of patience and discipline when building a product — I received dozens of variations of the following question: So how do you stay disciplined? How do you avoid getting distracted by new ideas or dismayed by bad weeks, even when you only have a few users? Various people I think...

Befriending the Goon Squad
12 Jul 2023 | original ↗

TL;DR The single biggest asset that side projects and "nights and weekends" businesses have on their side is near-infinite runway. If you have near-infinite runway, your largest risk is yourself: you get bored, you get demotivated, you get distracted, etc. If you're sufficiently patient and disciplined, you can wait out the competition and rely...

Spoonbill (2016—2023)
11 Jun 2023 | original ↗

The start I would be lying to you if I told you I remember exactly what was going on when I came up with the idea for Spoonbill. I know I was still in what I would call my "year in the wilderness" — in a not-so-great relationship, in a not-so-great job, trying to compensate for both by moonlighting on a bunch of projects and drinking too many...

2022
29 Dec 2022 | original ↗

2022 in review Hello! My name's Justin. This is my annual review for 2022. You may also be interested in last year's. Health I am, as I write this, in the best shape of my life. “Best shape” is, admittedly, vague and somewhat subjective; I could rephrase as “I am lifting more weight than I ever have before and am a better boulderer than I’ve ever...

2021
29 Dec 2021 | original ↗

Personal CountsNumber of times I’ve texted “gahhhh sorry for the late response”144Hours spent gaming with partner117Photos of Telly taken whilst he sleeps84Bottles of Veuve Clicquot consumed1 Health I ended 2020 in a period of what could generously be called “fitness stasis”; I was working out and walking but not particularly pushing myself in...

2019
29 Dec 2019 | original ↗

2019 was pretty great. here are the highlights: found someone i loved we moved in together into a house that i bought got promoted at a job that i continue to love worked very hard hit 5k MRR across all my various projects signed my first four-digit software contract and my first five-digit software contract read (and listened to) a lot of books...

2018
29 Dec 2018 | original ↗

Okay, let's skip the whole "gee, it's been a whole year, huh? this time last year I was..." and get into it. What worked So, all the good stuff first: I started writing poetry again. This is, honestly, the best: I forgot how much I needed a creative outlet, and how much sanity and satisfaction it affords me. I started running seriously! I ran my...

2016
29 Dec 2016 | original ↗

Welp. 2016 was a doozy. There were lot of very good things. I started the best job of my life; I started living with my partner, and have never been happier; I'm in the best shape of my life. I listened to a lot of great music, and ate multiple salads. (This sounds boastful, because it is, but I'm trying to be more honest about victories and...

↑ these items are from RSS. Visit the blog itself at https://jmduke.com/ to find other articles and to appreciate the author's digital home.