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...
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),...
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...
(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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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,...
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,...
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...
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...
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,...
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,...
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...
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...
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...
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...
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...
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...
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,...
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, 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...
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....
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...
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...
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...
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...
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!
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....
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!
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....
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...
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...
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...
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...
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...
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",...
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",...
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...
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...
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...
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...
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...
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. 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. 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...
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...
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...
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...
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...
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,...
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,...
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...
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...
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...
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 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 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...
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...
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 ( ...
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...
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 ( ...
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...
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...
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...
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...
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...
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 |...
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 |...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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...
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,...
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,...
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...
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...
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...
.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:...
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...
.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:...
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...
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...
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...
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...
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...
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...
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...
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...
(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...
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
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
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 ...
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 ...
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...
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...
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 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...
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 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...
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...
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...