<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: michael-lynch</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/michael-lynch.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2026-10-07T14:53:51+00:00</updated><author><name>Simon Willison</name></author><entry><title>Anti-Patterns in Software Blogging</title><link href="https://simonwillison.net/2026/Oct/7/anti-patterns-in-software-blogging/" rel="alternate"/><published>2026-10-07T14:53:51+00:00</published><updated>2026-10-07T14:53:51+00:00</updated><id>https://simonwillison.net/2026/Oct/7/anti-patterns-in-software-blogging/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://refactoringenglish.com/blog/anti-patterns-software-blogging/#summary"&gt;Anti-Patterns in Software Blogging&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Some excellent writing advice from Michael Lynch. Michael warns against "meandering intros", misjudging your reader's existing knowledge, assuming they'll read your previous posts, and excessive formality.&lt;/p&gt;
&lt;p&gt;He also warns against &lt;a href="https://refactoringenglish.com/blog/anti-patterns-software-blogging/#overreliance-on-links"&gt;overreliance on links&lt;/a&gt; as an excuse not to explain terminology. This one hurt! I do this all the time, but I have a nagging suspicion that almost nobody ever clicks on them.&lt;/p&gt;
&lt;p&gt;(In &lt;a href="https://lobste.rs/s/rwdufq/anti_patterns_software_blogging#c_qdhhsd"&gt;a Lobste.rs comment&lt;/a&gt; Michael clarifies that "My rule of thumb is that my article should still make sense to the reader even if they don't click any links". That works for me.)&lt;/p&gt;
&lt;p&gt;This point about using your own voice is crucial:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Beginner software bloggers suffer from a mass delusion that you have to write in a stiff, overly formal way for people to take you seriously [...]&lt;/p&gt;
&lt;p&gt;Just write the way you talk.&lt;/p&gt;
&lt;p&gt;With so many developers delegating their writing to AI, software blogging is becoming bland and homogenous. Readers are hungry for writing with personality.&lt;/p&gt;
&lt;/blockquote&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/rwdufq/anti_patterns_software_blogging"&gt;Lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/blogging"&gt;blogging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/writing"&gt;writing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/michael-lynch"&gt;michael-lynch&lt;/a&gt;&lt;/p&gt;



</summary><category term="blogging"/><category term="writing"/><category term="michael-lynch"/></entry><entry><title>The most popular blogs of Hacker News in 2025</title><link href="https://simonwillison.net/2026/Jan/2/most-popular-blogs-of-hacker-news/" rel="alternate"/><published>2026-01-02T19:10:43+00:00</published><updated>2026-01-02T19:10:43+00:00</updated><id>https://simonwillison.net/2026/Jan/2/most-popular-blogs-of-hacker-news/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://refactoringenglish.com/blog/2025-hn-top-5/"&gt;The most popular blogs of Hacker News in 2025&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Michael Lynch maintains &lt;a href="https://refactoringenglish.com/tools/hn-popularity/"&gt;HN Popularity Contest&lt;/a&gt;, a site that tracks personal blogs on Hacker News and scores them based on how well they perform on that platform.&lt;/p&gt;
&lt;p&gt;The engine behind the project is the &lt;a href="https://github.com/mtlynch/hn-popularity-contest-data/blob/master/data/domains-meta.csv"&gt;domain-meta.csv&lt;/a&gt; CSV on GiHub, a hand-curated list of known personal blogs with author and bio and tag metadata, which Michael uses to separate out personal blog posts from other types of content.&lt;/p&gt;
&lt;p&gt;I came top of the rankings in 2023, 2024 and 2025 but I'm listed &lt;a href="https://refactoringenglish.com/tools/hn-popularity/"&gt;in third place&lt;/a&gt; for all time behind Paul Graham and Brian Krebs.&lt;/p&gt;
&lt;p&gt;I dug around in the browser inspector and was delighted to find that the data powering the site is served with open CORS headers, which means you can easily explore it with external services like Datasette Lite.&lt;/p&gt;
&lt;p&gt;Here's a convoluted window function query Claude Opus 4.5 &lt;a href="https://claude.ai/share/8e1cb294-0ff0-4d5b-b83f-58e4c7fdb0d2"&gt;wrote for me&lt;/a&gt; which, for a given domain, shows where that domain ranked for each year since it first appeared in the dataset:&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-s"&gt;with yearly_scores as (&lt;/span&gt;
&lt;span class="pl-s"&gt;  select &lt;/span&gt;
&lt;span class="pl-s"&gt;    domain,&lt;/span&gt;
&lt;span class="pl-s"&gt;    strftime('%Y', date) as year,&lt;/span&gt;
&lt;span class="pl-s"&gt;    sum(score) as total_score,&lt;/span&gt;
&lt;span class="pl-s"&gt;    count(distinct date) as days_mentioned&lt;/span&gt;
&lt;span class="pl-s"&gt;  from "hn-data"&lt;/span&gt;
&lt;span class="pl-s"&gt;  group by domain, strftime('%Y', date)&lt;/span&gt;
&lt;span class="pl-s"&gt;),&lt;/span&gt;
&lt;span class="pl-s"&gt;ranked as (&lt;/span&gt;
&lt;span class="pl-s"&gt;  select &lt;/span&gt;
&lt;span class="pl-s"&gt;    domain,&lt;/span&gt;
&lt;span class="pl-s"&gt;    year,&lt;/span&gt;
&lt;span class="pl-s"&gt;    total_score,&lt;/span&gt;
&lt;span class="pl-s"&gt;    days_mentioned,&lt;/span&gt;
&lt;span class="pl-s"&gt;    rank() over (partition by year order by total_score desc) as rank&lt;/span&gt;
&lt;span class="pl-s"&gt;  from yearly_scores&lt;/span&gt;
&lt;span class="pl-s"&gt;)&lt;/span&gt;
&lt;span class="pl-s"&gt;select &lt;/span&gt;
&lt;span class="pl-s"&gt;  r.year,&lt;/span&gt;
&lt;span class="pl-s"&gt;  r.total_score,&lt;/span&gt;
&lt;span class="pl-s"&gt;  r.rank,&lt;/span&gt;
&lt;span class="pl-s"&gt;  r.days_mentioned&lt;/span&gt;
&lt;span class="pl-s"&gt;from ranked r&lt;/span&gt;
&lt;span class="pl-s"&gt;where r.domain = :domain&lt;/span&gt;
&lt;span class="pl-s"&gt;  and r.year &amp;gt;= (&lt;/span&gt;
&lt;span class="pl-s"&gt;    select min(strftime('%Y', date)) &lt;/span&gt;
&lt;span class="pl-s"&gt;    from "hn-data"&lt;/span&gt;
&lt;span class="pl-s"&gt;    where domain = :domain&lt;/span&gt;
&lt;span class="pl-s"&gt;  )&lt;/span&gt;
&lt;span class="pl-s"&gt;order by r.year desc&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;(I just noticed that the last &lt;code&gt;and r.year &amp;gt;= (&lt;/code&gt; clause isn't actually needed here.)&lt;/p&gt;
&lt;p&gt;My &lt;a href="https://lite.datasette.io/?csv=https://hn-popularity.cdn.refactoringenglish.com/hn-data.csv#/data?sql=with+yearly_scores+as+%28%0A++select+%0A++++domain%2C%0A++++strftime%28%27%25Y%27%2C+date%29+as+year%2C%0A++++sum%28score%29+as+total_score%2C%0A++++count%28distinct+date%29+as+days_mentioned%0A++from+%22hn-data%22%0A++group+by+domain%2C+strftime%28%27%25Y%27%2C+date%29%0A%29%2C%0Aranked+as+%28%0A++select+%0A++++domain%2C%0A++++year%2C%0A++++total_score%2C%0A++++days_mentioned%2C%0A++++rank%28%29+over+%28partition+by+year+order+by+total_score+desc%29+as+rank%0A++from+yearly_scores%0A%29%0Aselect+%0A++r.year%2C%0A++r.total_score%2C%0A++r.rank%2C%0A++r.days_mentioned%0Afrom+ranked+r%0Awhere+r.domain+%3D+%3Adomain%0A++and+r.year+%3E%3D+%28%0A++++select+min%28strftime%28%27%25Y%27%2C+date%29%29+%0A++++from+%22hn-data%22%0A++++where+domain+%3D+%3Adomain%0A++%29%0Aorder+by+r.year+desc&amp;amp;domain=simonwillison.net"&gt;simonwillison.net results&lt;/a&gt; show me ranked 3rd in 2022, 30th in 2021 and 85th back in 2007 - though I expect there are many personal blogs from that year which haven't yet been manually added to Michael's list.&lt;/p&gt;
&lt;p&gt;Also useful is that every domain gets its own CORS-enabled CSV file with details of the actual Hacker News submitted from that domain, e.g. &lt;code&gt;https://hn-popularity.cdn.refactoringenglish.com/domains/simonwillison.net.csv&lt;/code&gt;. Here's &lt;a href="https://lite.datasette.io/?csv=https://hn-popularity.cdn.refactoringenglish.com/domains/simonwillison.net.csv#/data/simonwillison"&gt;that one in Datasette Lite&lt;/a&gt;.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=46465819"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/hacker-news"&gt;hacker-news&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sql"&gt;sql&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sqlite"&gt;sqlite&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette"&gt;datasette&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette-lite"&gt;datasette-lite&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cors"&gt;cors&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/michael-lynch"&gt;michael-lynch&lt;/a&gt;&lt;/p&gt;



</summary><category term="hacker-news"/><category term="sql"/><category term="sqlite"/><category term="datasette"/><category term="datasette-lite"/><category term="cors"/><category term="michael-lynch"/></entry></feed>