<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://laughingmeme.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://laughingmeme.org/" rel="alternate" type="text/html" /><updated>2026-06-09T03:46:16+00:00</updated><id>https://laughingmeme.org/feed.xml</id><title type="html">Kellan Elliott-McCrea: Blog</title><subtitle>A personal blog of Kellan Elliott-McCrea. I don&apos;t really know what a &quot;laughing meme&quot; is. It sounded cool in 1999.</subtitle><author><name>Kellan Elliott-McCrea</name></author><entry><title type="html">The Importance of Tools and the Hedonic Treadmill of “Feels like Magic”</title><link href="https://laughingmeme.org/2026/05/22/the-importance-of-tools-and-the-hedonic-treadmill-of-feels-like-magic.html" rel="alternate" type="text/html" title="The Importance of Tools and the Hedonic Treadmill of “Feels like Magic”" /><published>2026-05-22T12:08:10+00:00</published><updated>2026-05-22T12:08:10+00:00</updated><id>https://laughingmeme.org/2026/05/22/the-importance-of-tools-and-the-hedonic-treadmill-of-feels-like-magic</id><content type="html" xml:base="https://laughingmeme.org/2026/05/22/the-importance-of-tools-and-the-hedonic-treadmill-of-feels-like-magic.html"><![CDATA[<p>Claude Code felt like magic when I used it for the first time (14 months ago?). And then it felt like magic again when the models got good at code at the end of the year.</p>

<p>But then I wanted to be able to <a href="https://laughingmeme.org/2026/03/24/coding-and-blogging-on-vacation.html">vibe code entirely from my phone, one handed on vacation, while sipping a fruity drink and playing beach soccer with the kiddos</a>, which brought me to exe.dev and Shelley. Shelley is great because its batteries included, all the tools you need out of the box to do web development.</p>

<p>Of course after that it started to feel clunky. The UI is a power tool of options, compaction is disruptive at a time when most agents are smoothing that experience out, exe.dev is still primarily focusing on it’s magic SSH setup experience, but I’m on my phone, and the phone based ssh/terminal clients feel like the increasingly baroque products of an evolutionary dead end.</p>

<p>So now I’m using “Claude Code for Web for iOS” (I think that really is the product name), and it’s simple and elegant, that nice soothing color palette of Anthropics, fewer things shoved in than the web experience, and it’s just “chat with your repo”, no vestigial or distracting UI elements.</p>

<p>Kiddo and I took some photos of sketches she made and <a href="https://kellanem.com/skybound/">started building a game together</a> on the subway ride to school. She’s the artist and art director, I’m holding the phone with Claude on it in one hand, and the pole in the other.</p>

<p>But the tools are surprisingly weak.</p>

<ul>
  <li>
    <p>There’s no built in hosting option, surprising given Claude for Web has had artifacts forever, I’m reduced to using githack to get live previews of the work (and with some fiddly caching issues).</p>
  </li>
  <li>
    <p>It can’t see your work, no VLM, no screenshot tools, no Playwright/Chrome Dev Tools skills. Certainly nothing as sophisticated as the Shelley tools around mobile web emulation, profiling, accessibility, etc. (also when is Claude get video support a la Gemini?)</p>
  </li>
</ul>

<p>Off the train, with two hands and a spare minute exe.dev/Shelley looks a lot more compelling (and the price differential between Anthropic’s subsidized accounts is getting smaller as the subsidies get smaller). But rising expectations mean none of it is feeling magical anymore, just all tools and compromises, and TODO: FIXME. Which is, in and of itself, wild.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[Claude Code felt like magic when I used it for the first time (14 months ago?). And then it felt like magic again when the models got good at code at the end of the year.]]></summary></entry><entry><title type="html">Coding on Vacation</title><link href="https://laughingmeme.org/2026/03/24/coding-and-blogging-on-vacation.html" rel="alternate" type="text/html" title="Coding on Vacation" /><published>2026-03-24T14:37:37+00:00</published><updated>2026-03-24T14:37:37+00:00</updated><id>https://laughingmeme.org/2026/03/24/coding-and-blogging-on-vacation</id><content type="html" xml:base="https://laughingmeme.org/2026/03/24/coding-and-blogging-on-vacation.html"><![CDATA[<p>The question I asked myself (and the private Slack channel): is ensuring that I have a phone based approach to agentic coding while I’m on vacation healthy because I’m ensuring that I’m not on the computer, a phone is less instrusive, or extremely unhealthy, because you know (gestures broadly) the whole being on vacation thing.</p>

<p>First attempt was VPS + Tailscale + tmux + Moshi + Claude Code Remote Control.</p>

<p>Clunky. SSH on the phone is never going to be fun. Claude Code /rc is very much a 1.0 product (sorry Andy!), I didn’t have a good pipeline to serving the things I was building, and when I put CC on yolo’ing some network configurations I lost access to the VPS, and breaking back in is a post vacation activity.</p>

<p>Second was using exe.dev, and in particular their agent Shelley. (Frankenstein reference?)</p>

<p>It’s been a ton of fun, works great on mobile web. Comes with a sophisticated set of tools around coding, researching, brainstorming, testing in browsers (including mobile emulation, accessibility and performance), visual QA, etc. As someone who has been playing with souping up harnesses recently this feels like a nice one. It uses sub-agents by default, and async web UI so it’s all background work by default. Has a built in code to publish pipeline. I’m having a lot of fun with it. My only caveat is I’m not sure how much it’s going to cost, I can’t really reason about that bit yet.</p>

<p>Started building a fun toy while we waited on the tarmac at JFK: a <a href="https://garden.exe.xyz/">garden of generative coding techniques</a> (in an older sense of the word).</p>

<p>And then I had it check out my blog repo, new my new post script, and I transcribed this blog post while getting a break from the sun. Fun.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[The question I asked myself (and the private Slack channel): is ensuring that I have a phone based approach to agentic coding while I’m on vacation healthy because I’m ensuring that I’m not on the computer, a phone is less instrusive, or extremely unhealthy, because you know (gestures broadly) the whole being on vacation thing.]]></summary></entry><entry><title type="html">Hack: claude -p</title><link href="https://laughingmeme.org/2026/03/20/hack-claude-p.html" rel="alternate" type="text/html" title="Hack: claude -p" /><published>2026-03-20T11:49:53+00:00</published><updated>2026-03-20T11:49:53+00:00</updated><id>https://laughingmeme.org/2026/03/20/hack-claude-p</id><content type="html" xml:base="https://laughingmeme.org/2026/03/20/hack-claude-p.html"><![CDATA[<p><code class="language-plaintext highlighter-rouge">claude -p</code> is a quick hack that I find myself using more.</p>

<p>Calling one of the various LLM APIs is easy. But requires key management. For me on a personal project that’s no big deal. In a work context it’s less trivial. But I’m working in <code class="language-plaintext highlighter-rouge">claude</code>, which means I have a tool talking to a LLM API running already all the time, that already has not only an API key, but also an allocated budget that is being managed around making me more productive. Much easier if all my LLM based productivity is spend hits a single line item.</p>

<p>E.g. a quick script to classify Github PRs has a section like:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">return</span> <span class="sa">f</span><span class="s">"""You are classifying GitHub pull requests for an engineering team.

  PRODUCT AREAS (choose exactly one per PR):
  </span><span class="si">{</span><span class="n">area_lines</span><span class="si">}</span><span class="s">

  WORK TYPES (choose exactly one per PR):
  </span><span class="si">{</span><span class="n">work_type_lines</span><span class="si">}</span><span class="s">

  For each PR, return a JSON array with these fields:
  - pr_id, product_area, work_type, confidence, keywords

  Return ONLY the JSON array. No prose, no markdown fences.

  PULL REQUESTS:
  </span><span class="si">{</span><span class="n">prs_text</span><span class="si">}</span><span class="s">"""</span>
</code></pre></div></div>

<p>And the call itself:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">def</span> <span class="nf">_call_claude</span><span class="p">(</span><span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="bp">None</span><span class="p">:</span>
      <span class="k">try</span><span class="p">:</span>
          <span class="n">result</span> <span class="o">=</span> <span class="n">subprocess</span><span class="p">.</span><span class="n">run</span><span class="p">(</span>
              <span class="p">[</span><span class="s">'claude'</span><span class="p">,</span> <span class="s">'-p'</span><span class="p">,</span> <span class="s">'--output-format'</span><span class="p">,</span> <span class="s">'text'</span><span class="p">],</span>
              <span class="nb">input</span><span class="o">=</span><span class="n">prompt</span><span class="p">,</span>
              <span class="n">capture_output</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
              <span class="n">text</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
              <span class="n">timeout</span><span class="o">=</span><span class="mi">300</span><span class="p">,</span>
          <span class="p">)</span>
          <span class="k">return</span> <span class="n">result</span><span class="p">.</span><span class="n">stdout</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">if</span> <span class="n">result</span><span class="p">.</span><span class="n">returncode</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="bp">None</span>
      <span class="k">except</span> <span class="p">(</span><span class="n">subprocess</span><span class="p">.</span><span class="n">TimeoutExpired</span><span class="p">,</span> <span class="nb">FileNotFoundError</span><span class="p">):</span>
          <span class="k">return</span> <span class="bp">None</span>

</code></pre></div></div>
<p>Probably this is what the agent sdk is for? This worked.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[claude -p is a quick hack that I find myself using more.]]></summary></entry><entry><title type="html">Timberborn 1.0, HTTP Lever, and Claude Code</title><link href="https://laughingmeme.org/2026/03/15/timberborn-1-0-http-lever-and-claude-code.html" rel="alternate" type="text/html" title="Timberborn 1.0, HTTP Lever, and Claude Code" /><published>2026-03-15T18:27:49+00:00</published><updated>2026-03-15T18:27:49+00:00</updated><id>https://laughingmeme.org/2026/03/15/timberborn-1-0-http-lever-and-claude-code</id><content type="html" xml:base="https://laughingmeme.org/2026/03/15/timberborn-1-0-http-lever-and-claude-code.html"><![CDATA[<p>Timberborn is very much my kind of game. Complex, cozy, climate change, water system design, beavers. (My friend <a href="https://schuyler.info/">Schuyler</a> pointed out at one point that my preferred genre of game is “management sims”, and that perhaps I was little over rotated on my day job.)</p>

<p>I played it a <em>ton</em> during Early Access, and it’s great to see it finally reach 1.0. I highly recommend it.</p>

<p>One of the things they added in 1.0 is a full automation system. <em>Finally</em>. (Though I’ll be honest I was mostly okay with Sluice Gate there by the end at least for basic reservoir management). But now you can get serious! Automations can work on water depth, flow, contamination, the weather, resource counts, population counts, etc. There is memory, and a full complement of logic gates for wiring up your very own beaver powered Turing machine.</p>

<p>But one of the things they <em>also</em> added to 1.0 is the ability to have the game call arbitrary HTTP endpoints, and vice versa.</p>

<p>If you build an “HTTP Lever”, Timberborn will expose HTTP endpoints for turning it off and on on localhost.  Connect it to a fireworks launcher and now you can have fireworks launch across the sky every time that endpoint is called.</p>

<p>Have Claude Code add a Notification hook that calls that endpoint like so, and now every time Claude needs your attention: fireworks launch in Timberborn.</p>

<p><img src="/img/timberborn-fireworks.png" alt="Fireworks in Timberborn" /></p>

<p>(Or you can add it to the Stop hook if you want to know every time Claude stops)</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"Notification"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"curl -s 'http://localhost:8080/api/switch-on/HTTP%20Lever%201'"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"Stop"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"curl -s 'http://localhost:8080/api/switch-on/HTTP%20Lever%201'"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[Timberborn is very much my kind of game. Complex, cozy, climate change, water system design, beavers. (My friend Schuyler pointed out at one point that my preferred genre of game is “management sims”, and that perhaps I was little over rotated on my day job.)]]></summary></entry><entry><title type="html">Socialize the Plan</title><link href="https://laughingmeme.org/2026/03/05/socialize-the-plan.html" rel="alternate" type="text/html" title="Socialize the Plan" /><published>2026-03-05T11:45:16+00:00</published><updated>2026-03-05T11:45:16+00:00</updated><id>https://laughingmeme.org/2026/03/05/socialize-the-plan</id><content type="html" xml:base="https://laughingmeme.org/2026/03/05/socialize-the-plan.html"><![CDATA[<p>On AI and code review.</p>

<p>Anyone who tells you they have this current moment in coding figured out is lying to someone (you or themselves). I’m going to keep sharing half-formed thoughts, and bits of things I’ve learned.</p>

<p>As the cost of writing code goes to zero new strains and bottlenecks appear. This is what we expect when we think about building software as a system. For most teams the first place that strain appears is in code review.</p>

<p><em>No one</em> wants their job to become spending all day carefully reviewing code that someone else had a machine generate in minutes.</p>

<p>Simon wrote yesterday about the anti-patterns of <a href="https://simonwillison.net/guides/agentic-engineering-patterns/anti-patterns/#inflicting-unreviewed-code-on-collaborators">Inflicting unreviewed code on collaborators</a>. Also nice to read the recent <a href="https://www.latent.space/p/reviews-dead">How to Kill the Code Review</a>, and see an old friend like the <a href="https://en.wikipedia.org/wiki/Swiss_cheese_model">Swiss cheese model</a>.</p>

<p>Code review is a funny topic.</p>

<p>Most senior engineers and engineering leaders I know have always been quietly skeptical of its value. It’s expensive, and the data on defect detection doesn’t justify the cost. Meanwhile teams tend to put too much trust in code review while underinvesting in other tools to gain confidence: monitoring, automation, better coding tools and practices, training, etc. (Swiss cheese!)</p>

<p>Code review ubiquity is tied to GitHub’s (really quite recent I promise you!) rise to ubiquity, a tool designed for open source development, that quickly sublimated into being “conventional wisdom and best practice”. So much to say about how in software, we keep believing we’ve found “normal” and “best practice,” forgetting we’re 50 years into an experiment where we tear up and reinvent best practices every 5–10 years.</p>

<p>As a senior leader you sort of shrug and sigh, and be glad that code review has some nice side benefits like ensuring that information is dispersing through the organization, that people are talking to each other, learning and teaching is happening, all of which are valuable.</p>

<p>But that is all about code review for human written code and so I digress.</p>

<p>On my team we’re not ready (yet?) to ditch code review, but I got this insightful feedback on the first large AI generated PR I tried to land that has shaped my thinking. </p>

<blockquote>
  <p>In a manually coded PR, if a reviewer comes in and pushes back on the design, then that’s often a smell that the design wasn’t sufficiently socialized prior to spending time on the implementation. So we have meetings to review designs, we write RFCs, etc, to get consensus about how to do a thing before we commit effort to it. In this case, you went through the planning phase with the agent to determine the approach to take, and then had it churn out the diff.</p>
</blockquote>

<blockquote>
  <p>getting design push-back in a manually written PR is annoying because the effort expended to write it was wasted if the design has to shift. But if the agent is able to quickly produce a new diff once a plan is updated to reflect design feedback, then push-back on the plan isn’t a big deal because we can just update the plan and re-run the agent.</p>
</blockquote>

<p>Anyone working with coding agents regularly knows the planning phase is where the bulk of the time is spent not to mention where the human cognition and creativity is happening (that and designing the verification steps). Plan → save the plan → implement → describe diff → review → verify → fix → possibly update the plan.</p>

<p>Implementation, the generating of code, is really a rather minor and cheap part of the process. Why obsess on getting feedback on that part?</p>

<p>That’s our latest learning as a team: <strong>Socialize and get feedback on the plan.</strong> (Also on the verification steps. And maybe on how you configure your reviewers.)</p>

<p>This is the most human to human high bandwidth work.</p>

<p>I liked a lot of the framing of the problem in Simon’s and Ankit’s posts (and seeing an old friend like Swiss cheese model). But I think their solutions missed out on a plan for ensuring the continuation of the real value that code review provides: socialization, information dispersal, learning and teaching.</p>

<p>Ankit is right, the human work moves upstream (as it always has).</p>

<p>You can look at the code. But honestly, it’s the human driving the agent’s job to worry about the code, ensure it works, and that they meet the standards of the org. We can do something more valuable with our teammates time when we ask them to review our work.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[On AI and code review.]]></summary></entry><entry><title type="html">Ed’s Software, in a Time of Fear</title><link href="https://laughingmeme.org/2026/03/01/software-in-a-time-of-fear.html" rel="alternate" type="text/html" title="Ed’s Software, in a Time of Fear" /><published>2026-03-01T13:58:18+00:00</published><updated>2026-03-01T13:58:18+00:00</updated><id>https://laughingmeme.org/2026/03/01/software-in-a-time-of-fear</id><content type="html" xml:base="https://laughingmeme.org/2026/03/01/software-in-a-time-of-fear.html"><![CDATA[<p>I enjoyed this essay from my friend Ed Lyons, which I think speaks well to <em>my</em> particular state of mind as someone who has been in this industry for 30+ years, a parent, a people leader, a builder.</p>

<p><a href="https://mysteriousrook.medium.com/software-in-a-time-of-fear-4e5a08ac7c63">Software, in a Time of Fear</a></p>

<blockquote>
  <p>Up front, here are the lessons:</p>

  <ol>
    <li>Stop listening to people who are afraid</li>
    <li>Seek first-hand testimony, not opinions</li>
    <li>Go with someone much more enthusiastic than you</li>
    <li>Do not look down</li>
    <li>You must get different equipment</li>
    <li>Put the summit out of your mind</li>
  </ol>

  <p>Yet I hope you stay for the hike up.</p>
</blockquote>

<p>Personally I’m working on 1, 2, 3, and 5. I’m struggling with 4 and 6.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[I enjoyed this essay from my friend Ed Lyons, which I think speaks well to my particular state of mind as someone who has been in this industry for 30+ years, a parent, a people leader, a builder.]]></summary></entry><entry><title type="html">Software Practices from the Scrap Heap?</title><link href="https://laughingmeme.org/2026/02/15/software-practices-from-the-scrap-heap.html" rel="alternate" type="text/html" title="Software Practices from the Scrap Heap?" /><published>2026-02-15T14:53:50+00:00</published><updated>2026-02-15T14:53:50+00:00</updated><id>https://laughingmeme.org/2026/02/15/software-practices-from-the-scrap-heap</id><content type="html" xml:base="https://laughingmeme.org/2026/02/15/software-practices-from-the-scrap-heap.html"><![CDATA[<p>I’m going to keep writing half baked things about AI, because it’s what I’m spending a noticeable number of hours thinking about these days, and because I don’t think it’s possible to be fully baked on the topic. Apologies in advance for those who find it irritating.</p>

<p>Had a call with <a href="https://blog.fsck.com/">Jesse</a> the other week and we discussed how we’re <a href="https://blog.fsck.com/2026/02/03/managing-agents/">speed running the last few decades of engineering management</a>. The swarm craze of the last few weeks bringing us solidly up to Fred Brooks.</p>

<p>Writing about software development over the years has always suffered from at least two key challenges:</p>

<ul>
  <li>
    <p>the vast majority of the writing suffers from survivor bias and serves as a record of something that worked for <em>this particular set of humans</em> in <em>this particular set of circumstances</em>.</p>
  </li>
  <li>
    <p>most of the writing has implicitly assumed a highly rational, implacable, rule following software engineer completely at odds with all the software engineers I’ve known (and wildly at odds with the best of them)</p>
  </li>
</ul>

<p>But if our software theories often assumed emotionally and morally stunted automatons with limitless patience, might they be useful in today’s context?</p>

<ul>
  <li>TDD, always hit and miss for humans, clearly works well for agents.</li>
  <li>The folks I’ve spoken with who are experimenting with maximalist approaches to agentic coding talk a lot about components and isolation in ways that remind me of microservices (terrible for humans), and CORBA before it.</li>
  <li>Bake-offs (the agent might get attached to their implementation, but only for the space of that shell)</li>
  <li>Sub-agents have <em>some</em> of the insights of pair programming encoded in the practice, enough that it makes me wonder about the rest of the XP toolkit.</li>
  <li>UML and Rational Rose coming back?</li>
</ul>

<p>I wonder what else from the scrap heap is worth poking at?</p>

<p><strong>update:</strong> Big Up Front planning was pointed out to me as a classic technique that worked poorly with humans and is coming back as planning becomes more key</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[I’m going to keep writing half baked things about AI, because it’s what I’m spending a noticeable number of hours thinking about these days, and because I don’t think it’s possible to be fully baked on the topic. Apologies in advance for those who find it irritating.]]></summary></entry><entry><title type="html">Code has _always_ been the easy part</title><link href="https://laughingmeme.org/2026/02/09/code-has-always-been-the-easy-part.html" rel="alternate" type="text/html" title="Code has _always_ been the easy part" /><published>2026-02-09T17:05:30+00:00</published><updated>2026-02-09T17:05:30+00:00</updated><id>https://laughingmeme.org/2026/02/09/code-has-always-been-the-easy-part</id><content type="html" xml:base="https://laughingmeme.org/2026/02/09/code-has-always-been-the-easy-part.html"><![CDATA[<p>When I joined Etsy the team was two years into a rewrite chasing a more elegant architecture (actually two distinct incompatible elegant architectures), and hadn’t shipped a customer facing feature in that time. I like to say (and it may even be true) that stopping and pivoting the team to standardizing on PHP was critical to unlocking everything that came later at Etsy. After all, no one ever has to argue about what elegant PHP looks like.</p>

<p>We’ve <em>always</em> had this tension. We’ve always fetishized the act of writing code, the quality of the code, the code as the primary artifact and IP. And on the other hand successful teams have <em>always</em> known that the value is the system, the value is human-technology hybrid that allows a product to be delivered, meet customer needs, evolve to provide more value over time, meet the spoken and unspoken needs of the problem domain, etc. This confusion in our thinking has laid at the heart of why, for example, technical hiring was such a disaster for so long. (Hiring continues to be terrible but it’s actually <em>much</em> better than it used to be. We now make fun of teams that ask you to reverse a linked list on a whiteboard while evaluating if they’d like to have a beer with you. That used to be the norm)</p>

<p>Said another way, we’ve known for a <em>long</em> time that code is the easy part. Has arguably <em>always</em> been the easy part, but certainly has been the easiest part of building software for the last several decades.</p>

<p>Yes: this is a genuinely new moment.</p>

<p>Yes: the last 3-4 months of frontier models, and Claude Code and its ilk are genuinely something new in the world.</p>

<p>Yes: the cost of producing code is plunging towards something near to zero faster than almost any of us can imagine, and that’s going to require a ton of change.</p>

<p>Yes: it’s already breaking social contracts and requiring rethinking about how teams work together. (<a href="https://siddhantkhare.com/writing/ai-fatigue-is-real">Review is <em>fatiguing</em> in a way that creating is not</a>, something else we’ve known for a while.)</p>

<p>Also yes: I’m feeling the <a href="https://simonwillison.net/2026/Feb/6/tom-dale/">dissociative awe at the temporal compression of change</a>.</p>

<p>But code being the easy and cheap part is not new.</p>

<p>Technology changes requiring us to rethink our social contracts and how our teams work is not new.</p>

<p>The web, CI/CD, large scale sites, mobile, SPAs, machine learning and data, all of these broke how teams worked and required us to invent new ways of working.</p>

<p>I think it’s fascinating to <a href="https://simonwillison.net/2026/Feb/7/software-factory/">read about running a dark software factory with a team of 3 people</a>. I think as a leader with a much larger (though comparatively small) team of humans I’m going to need to be equally creative on the right way to incorporate humans rather than exclude them from the process. And honestly those conversations are fun. It’s been a <em>while</em> since we’ve gotten to throw all the pieces up in the air and see what works.</p>

<p>It’s reasonable to be skeptical of AI because so much of the hype around it, and so many of the people hyping it (and profiting from it) are also at the nexus of the most amoral and sometimes out right evil aspect of how capital has transformed tech. (Does anyone else miss when tech was funded by nice, morally uncomplicated actors, like the US Department of Defense, back when it was still called the Department of Defense)</p>

<p>It’s also reasonable for people who entered technology in the last couple of decades because it was good job, or because they enjoyed coding to look at this moment with a real feeling of loss. That feeling of loss though can be hard to understand emotionally for people my age who entered tech because we were addicted to feeling of agency it gave us. The web was objectively awful as a technology, and genuinely amazing, and nobody got into it because programming in Perl was somehow aesthetically delightful. (The language is referred to as write only line noise for a reason)</p>

<p>The cost of code is going to zero. That’s genuinely neat, and mind blowing, and going to require reinventing so many things. It was still never the hard part.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[When I joined Etsy the team was two years into a rewrite chasing a more elegant architecture (actually two distinct incompatible elegant architectures), and hadn’t shipped a customer facing feature in that time. I like to say (and it may even be true) that stopping and pivoting the team to standardizing on PHP was critical to unlocking everything that came later at Etsy. After all, no one ever has to argue about what elegant PHP looks like.]]></summary></entry><entry><title type="html">Web app for looking up NYC street trees</title><link href="https://laughingmeme.org/2025/06/01/nyc-street-trees.html" rel="alternate" type="text/html" title="Web app for looking up NYC street trees" /><published>2025-06-01T17:05:30+00:00</published><updated>2025-06-01T17:05:30+00:00</updated><id>https://laughingmeme.org/2025/06/01/nyc-street-trees</id><content type="html" xml:base="https://laughingmeme.org/2025/06/01/nyc-street-trees.html"><![CDATA[<p>I spent Thursday at King’s County Court House finding out whether I was going to be called for jury duty. I used the opportunity to reach <em>way back</em> in the spark file for a silly side project, a web app for browsing NYC’s street trees.</p>

<p><img src="/img/spark-trees-near-you.jpg" /></p>

<p>This project has been on my todo list for a long time (probably even before the 2016 date I have written down here). I was inspired by <a href="https://www.treesnearyou.com/">Trees Near You</a>, an awesome hack from <a href="https://www.brettcamper.com/">Brett Camper</a> at a hackathon the city threw to promote its new open data initiatives (back when NYC did that kind of thing). At some point Apple changed some APIs and Brett’s awesome app stopped working and I conceived the notion to rebuild it for the web.</p>

<p>Now this project is largely pointless, because in the intervening decade <a href="https://tree-map.nycgovparks.org/">NYC Parks has launched an excellent website to serve just this purpose</a>. But it’s a fun, self contained little project, and I’ve picked up a couple of different times to try out new technology. (The React and React Native versions never really worked. A version I tried to build with Claude’s help in 2023 on Svelte mostly worked locally in Chrome, but never on Safari or in production). With Claude Code this time I got further.</p>

<p>So here is a <a href="https://treesnyc.onrender.com/">simple Trees NYC web app</a>. Relatively vanilla Javascript, SQLite backend. Please enjoy New Yorks 650k+ trees.</p>

<p>(and I was dismissed from jury duty, I don’t think the vibe coding was the reason.)</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[I spent Thursday at King’s County Court House finding out whether I was going to be called for jury duty. I used the opportunity to reach way back in the spark file for a silly side project, a web app for browsing NYC’s street trees.]]></summary></entry><entry><title type="html">Vibe coding for teams, thoughts to date</title><link href="https://laughingmeme.org/2025/05/25/vibe-coding-for-teams.html" rel="alternate" type="text/html" title="Vibe coding for teams, thoughts to date" /><published>2025-05-25T17:05:30+00:00</published><updated>2025-05-25T17:05:30+00:00</updated><id>https://laughingmeme.org/2025/05/25/vibe-coding-for-teams</id><content type="html" xml:base="https://laughingmeme.org/2025/05/25/vibe-coding-for-teams.html"><![CDATA[<p>(note: this is still a <em>topic</em> I’m interested in and thinking about a lot, but this blog post from 8 months ago is so out of date as to be useless - 2026/02/07)</p>

<p>I’ve got <a href="https://www.anthropic.com/claude-code">Claude Code</a> running in the background while I tab between writing this, sipping a Powers, and fielding phone calls from a team slightly panicked about the end of quarter QBR. This blog post is being written on May 27th, 2025, things may have changed by the time you read it. It was a toss up whether to post this on <a href="https://kellanem.com/notes/">Notes on engineering leadership</a>, or here, but eventually decided this was too loose for even Notes low standards. You’ve been warned (or at least given a context window with which to understand the remaining blog post).</p>

<p>LLMs are without a doubt the most disruptive change to how code gets written I’ve seen in my career since the introduction of the World Wide Web. As someone who largely <em>started</em> on the web at a time when most people weren’t, I remember reading <a href="https://en.wikipedia.org/wiki/Dr._Dobb%27s_Journal">Dr. Dobb’s</a> 30 years ago and seeing all these ads for weird C++ binaries I could pay to include in binaries I shipped on CDs. (Jokes on me as I now work at a <a href="https://www.adobe.com/">company</a> that has C++ in production that dates to that era). That said, as of today, LLMs don’t change some key fundamental physics of writing code as a team. Importantly, as of today, they haven’t changed the fundamental calculation that writing code is always easier than understanding code.</p>

<p>The insight that reading code is harder than writing leads naturally to the insight that <a href="https://kellanem.com/notes/towards-an-understanding-of-technical-debt">every line of code is tech debt</a>. Every line of code encodes your best current understanding of the problem you’re trying to solve (for increasingly weird definitions of “you”). Nothing has changed the fact that your current understanding is probably limited, and wrong in several ways.</p>

<h3 id="updating-your-mental-model-even-harder-for-llms-than-for-engineers">Updating your mental model even harder for LLMs than for engineers</h3>

<p>If you’ve ever had the questionable joy of participating in a “technological transformation” (whether or not it was called that) than you’ve had the specific experience of how challenging it is to convince an engineering team to give up on its current test suite (for extremely variable values of “test suite”). It doesn’t matter how much you argue that the test suite is a product of the practices and understanding of the problem you’re trying to over turn. And you’ll have this same conversation iterated for each historical technical decision (but especially tests). I’ve gone through the process of convincing a toddler to give up their pacifier, and convincing engineers to give up their tests, and I’d choose reasoning with the 2 year old any day of the week.</p>

<p>LLMs are more challenging. As soon as you instruct them to start building context from an existing codebase, you’re in a battle to change their mind about what’s important. From tests, to schemas, to dependencies. Given the lack of explicit tools for operating on their internal model, it’s a shockingly similar process to convincing an engineer (I should note the approaches that work with a toddler <em>do not work</em> with LLMs, in particular bribery is largely a failure).</p>

<p>The saving grace for engineers is the handful of folks who through inclination or trauma either believe in a better world or just want to see the current world burn and are therefore inclined to radical departures. My experimental data suggests telling LLMs they “just want to watch the world burn” does not make them more comfortable deleting obsolete test cases.</p>

<h3 id="nih-wasnt-invented-here-but-we-did-perfect-it">NIH wasn’t invented here, but we did perfect it.</h3>

<p>Current generations of LLM are very happy to write you a new function for functionality you already have in your codebase. Your tips on incantations to add to CLAUDE.md to change this behavior welcome. Just telling it “DRY” ain’t getting the job done. (and honestly, <a href="https://wiki.c2.com/?DontRepeatYourself">DRY</a> was always problematic advice that lead to premature abstraction, and that was before the nightmare that was dependency injection). Code bases with significant AI contribution are … bushy. Arguably as long as no humans are required to reason about the codebase we’re fine. It does preclude, practically from first principles, those exceptional individuals many of us have encountered in our career who seemed to be able to hold the entire code base in their brains. Arguably that’s a net positive. Those individuals were always problematic similar to those folks who are willing to <a href="https://www.google.com/search?q=heroes+considered+harmful">work 80 hours a week and jump on every incident</a>. At a minimum they make the rest of us look bad. But it’s still an arms race between the LLM and itself. I may be skeptical of TDD as a human practice, but as a LLM practices it’s the gold standard. But if every member of your team has their own bespoke approach to common functionality is your test suite doing its job? At a minimum you’re burning a lot of Github Actions CPU. And that’s before you ponder what does the response to <a href="https://nvd.nist.gov/vuln/detail/cve-2021-44228">Log4Shell</a> look like in a world where everyone on your team has their own NIH bespoke logging code?</p>

<h3 id="a-small-number-of-well-known-tools--if-it-was-opposite-day">A Small Number of Well Known Tools … if it was opposite day.</h3>

<p>Highly productive engineering teams (historically) reach that productivity by building a deep expertise in their tool chain. This is why it is so critical to closely examine <a href="https://kellanem.com/notes/new-tech">introducing new technologies</a> to your stack. An under examined cost of complicated technologies is that the cost of defining the preferred subset of capabilities falls on each development team instead of the industry as a whole. For example think about how every team that uses a “big language” (like Typescript or Scala) defines their own local subset, or paucity of Postgres best practices vs MySQL. <a href="https://wiki.c2.com/?ThereIsMoreThanOneWayToDoIt">TIMTOWTDI</a> isn’t actually a good thing. (<a href="https://docs.python.org/3/tutorial/stdlib.html#batteries-included">“batteries included”</a> definitely won that argument) LLMs radically lower the cost of writing code (already the cheapest part of software development). With LLMs it is often easier to code an approach than research one. The exploding ecological diversity in our software environments is breathtaking.</p>

<h3 id="where-were-at-today">Where we’re at today</h3>

<p>Local, bespoke, unique, noisy, bushy, <em>big</em> codebases seem like the inevitable byproduct of our current tools and models. It’s possible that LLMs can be shaped into tools that making code reading and code reasoning more powerful; that help us refactor, refine, and reduce the complexity of our codebases. I’m certainly encouraging my team to experiment with what is possible. Lowering the cost of <em>writing</em> code was the thing that no engineering leader asked for, but it’s the thing we got.</p>

<p>How are you changing your leadership practices in the face of LLMs?</p>

<p>You’ve spent $0 on LLM APIs reading this blog post.</p>]]></content><author><name>Kellan Elliott-McCrea</name></author><summary type="html"><![CDATA[(note: this is still a topic I’m interested in and thinking about a lot, but this blog post from 8 months ago is so out of date as to be useless - 2026/02/07)]]></summary></entry></feed>