Jim Nielsen’s Blog

You found my experimental HTML feed (there are also other ways to subscribe).

I HTML

Recent posts

Measurement and Numbers

View

Here’s Jony Ive talking to Patrick Collison about measurement and numbers:

People generally want to talk about product attributes that you can measure easily with a number…schedule, costs, speed, weight, anything where you can generally agree that six is a bigger number than two

He says he used to get mad at how often people around him focused on the numbers of the work over other attributes of the work.

But after giving it more thought, he now has a more generous interpretation of why we do this: because we want relate to each other, understand each other, and be inclusive of one another. There are many things we can’t agree on, but it’s likely we can agree that six is bigger than two. And so in this capacity, numbers become a tool for communicating with each other, albeit a kind of least common denominator — e.g. “I don’t agree with you at all, but I can’t argue that 134 is bigger than 87.”

This is conducive to a culture where we spend all our time talking about attributes we can easily measure (because then we can easily communicate and work together) and results in a belief that the only things that matter are those which can be measured.

People will give lip service to that not being the case, e.g. “We know there are things that can’t be measured that are important.” But the reality ends up being: only that which can be assigned a number gets managed, and that which gets managed is imbued with importance because it is allotted our time, attention, and care.

This reminds me of the story of the judgement of King Solomon, an archetypal story found in cultures around the world. Here’s the story as summarized on Wikipedia:

Solomon ruled between two women who both claimed to be the mother of a child. Solomon ordered the baby be cut in half, with each woman to receive one half. The first woman accepted the compromise as fair, but the second begged Solomon to give the baby to her rival, preferring the baby to live, even without her. Solomon ordered the baby given to the second woman, as her love was selfless, as opposed to the first woman's selfish disregard for the baby's actual well-being

In an attempt to resolve the friction between two individuals, an appeal was made to numbers as an arbiter. We can’t agree on who the mother is, so let’s make it a numbers problem. Reduce the baby to a number and we can agree!

But that doesn’t work very well, does it?

I think there is a level of existence where measurement and numbers are a sound guide, where two and two make four and two halves make a whole.

But, as humans, there is another level of existence where mathematical propositions don’t translate. A baby is not a quantity. A baby is an entity. Take a whole baby and divide it up by a sword and you do not half two halves of a baby.

I am not a number. I’m an individual. Indivisible.

What does this all have to do with software? Software is for us as humans, as individuals, and because of that I believe there is an aspect of its nature where metrics can’t take you.cIn fact, not only will numbers not guide you, they may actually misguide you.

I think Robin Rendle articulated this well in his piece “Trust the vibes”:

[numbers] are not representative of human experience or human behavior and can’t tell you anything about beauty or harmony or how to be funny or what to do next and then how to do it.

Wisdom is knowing when to use numbers and when to use something else.


Reply via: Email · Mastodon · Bluesky

Computers Are a Feeling

View

Exploring diagram.website, I came across The Computer is a Feeling by Tim Hwang and Omar Rizwan:

the modern internet exerts a tyranny over our imagination. The internet and its commercial power has sculpted the computer-device. It's become the terrain of flat, uniform, common platforms and protocols, not eccentric, local, idiosyncratic ones.

Before computers were connected together, they were primarily personal. Once connected, they became primarily social. The purpose of the computer shifted to become social over personal.

The triumph of the internet has also impoverished our sense of computers as a tool for private exploration rather than public expression. The pre-network computer has no utility except as a kind of personal notebook, the post-network computer demotes this to a secondary purpose.

Smartphones are indisputably the personal computer. And yet, while being so intimately personal, they’re also the largest distribution of behavior-modification devices the world has ever seen. We all willing carry around in our pockets a device whose content is largely designed to modify our behavior and extract our time and money.

Making “computer” mean computer-feelings and not computer-devices shifts the boundaries of what is captured by the word. It removes a great many things – smartphones, language models, “social” “media” – from the domain of the computational. It also welcomes a great many things – notebooks, papercraft, diary, kitchen – back into the domain of the computational.

I love the feeling of a personal computer, one whose purpose primarily resides in the domain of the individual and secondarily supports the social. It’s part of what I love about the some of the ideas embedded in local-first, which start from the principle of owning and prioritizing what you do on your computer first and foremost, and then secondarily syncing that to other computers for the use of others.


Reply via: Email · Mastodon · Bluesky

Follow Up: An Analysis of YouTube Links From The White House’s “Wire” Website

View

After publishing my Analysis of Links From The White House’s “Wire” Website, Tina Nguyen, political correspondent at The Verge, reached out with some questions.

Her questions made me realize that the numbers in my analysis weren’t quite correct (I wasn’t de-depulicating links across days, so I fixed that problem).

More pointedly, she asked about the most popular domain the White House was linking to: YouTube. Specifically, were the links to YouTube 1) independent content creators, 2) the White House itself, or 3) a mix.

A great question. I didn’t know the answer but wanted to find out. A little JavaScript code in my spreadsheet and boom, I had all the YouTube links in one place.

Screenshot of a table of data in a spreadsheet showing all the links to YouTube from wh[dot]gov/wire

I couldn’t really discern from the links themselves what I was looking at. A number of them were to the /live/ subpath, meaning I was looking at links to live streaming events. But most of the others were YouTube’s standard /watch?v=:id which leaves the content and channel behind the URL opaque. The only real way to know was to click through to each one.

I did a random sampling and found most of the ones I clicked on all went to The White House’s own YouTube channel. I told Tina as much, sent here the data I had, and she reported on it in an article at The Verge.

Tina’s question did get me wondering: precisely how many of those links are to the White House’s own YouTube channel vs. other content creators?

Once again, writing scripts that process data, talk to APIs, and put it all into 2-dimensional tables in a spreadsheet was super handy.

I looked at all the YouTube links, extracted the video ID, then queried the YouTube API for information about the video (like what channel it belongs to). Once I had the script working as expected for a single cell, it was easy to do the spreadsheet thing where you just “drag down” to autocomplete all the other cells with video IDs.

Animated gif of a mouse cursor dragging down the cell cursor in a spreadsheet and data being fetched (from an API) and populated in spreadsheet cells

The result?

From May 8th to July 6th there were 78 links to YouTube from wh.gov/wire, which breaks down as follows:

  • 73 links to videos on the White House’s own YouTube channel
  • 2 links to videos on the channel “Department of Defense”
  • 1 link to a video on the channel “Pod Force One with Miranda Devine”
  • 1 link to a video on the channel “Breitbart News”
  • 1 link to a video that has since been taken down “due to a copyright claim by Sony Music Publishing” (so I’m not sure whose channel that was)

Pie chart showing the percentage distribution of data points among four sources: The White House (94.7%, shown in blue), Department of Defense (2.63%, red), Pod Force One with Miranda Devine (1.32%, green), and Breitbart News (1.32%, purple).


Reply via: Email · Mastodon · Bluesky

Do You Even Personalize, Bro?

View

There’s a video on YouTube from “Technology Connections” — who I’ve never heard of or watched until now — called Algorithms are breaking how we think. I learned of this video from Gedeon Maheux of The Iconfactory fame. Speaking in the context of why they made Tapestry, he said the ideas in this video would be their manifesto.

So I gave it a watch.

Generally speaking, the video asks: Does anyone care to have a self-directed experience online, or with a computer more generally?

I'm not sure how infrequently we’re actually deciding for ourselves these days [how we decide what we want to see, watch, and do on the internet]

Ironically we spend more time than ever on computing devices, but less time than ever curating our own experiences with them.

Which — again ironically — is the inverse of many things in our lives.

Generally speaking, the more time we spend with something, the more we invest in making it our own — customizing it to our own idiosyncrasies.

But how much time do you spend curating, customizing, and personalizing your digital experience? (If you’re reading this in an RSS reader, high five!)

I’m not talking about “I liked that post, or saved that video, so the algorithm is personalizing things for me”.

Do you know what to get yourself more of?

Do you know where to find it?

Do you even ask yourself these questions?

“That sounds like too much work” you might say.

And you’re right, it is work. As the guy in the video says:

I'm one of those weirdos who think the most rewarding things in life take effort

Me too.


Reply via: Email · Mastodon · Bluesky

Setting Element Ordering With HTML Rewriter Using CSS

View

After shipping my work transforming HTML with Netlify’s edge functions I realized I have a little bug: the order of the icons specified in the URL doesn’t match the order in which they are displayed on screen.

Why’s this happening?

I have a bunch of links in my HTML document, like this:

<icon-list>
  <a href="/1/"></a>
  <a href="/2/"></a>
  <a href="/3/"></a>
  <!-- 2000+ more -->
</icon-list>

I use html-rewriter in my edge function to strip out the HTML for icons not specified in the URL. So for a request to:

/lookup?id=1&id=2

My HTML will be transformed like so:

<icon-list>
  <!-- Parser keeps these two -->
  <a href="/1/"></a>
  <a href="/2/"></a>
  
  <!-- But removes this one -->
  <a href="/3/"></a>
</icon-list>

Resulting in less HTML over the wire to the client.

But what about the order of the IDs in the URL? What if the request is to:

/lookup?id=2&id=1

Instead of:

/lookup?id=1&id=2

In the source HTML document containing all the icons, they’re marked up in reverse chronological order. But the request for this page may specify a different order for icons in the URL. So how do I rewrite the HTML to match the URL’s ordering?

The problem is that html-rewriter doesn’t give me a fully-parsed DOM to work with. I can’t do things like “move this node to the top” or “move this node to position x”.

With html-rewriter, you only “see” each element as it streams past. Once it passes by, your chance at modifying it is gone. (It seems that’s just the way these edge function tools are designed to work, keeps them lean and performant and I can’t shoot myself in the foot).

So how do I change the icon’s display order to match what’s in the URL if I can’t modify the order of the elements in the HTML?

CSS to the rescue!

Because my markup is just a bunch of <a> tags inside a custom element and I’m using CSS grid for layout, I can use the order property in CSS!

All the IDs are in the URL, and their position as parameters has meaning, so I assign their ordering to each element as it passes by html-rewriter. Here’s some pseudo code:

// Get all the IDs in the URL
const ids = url.searchParams.getAll("id");

// Select all the icons in the HTML
rewriter.on("icon-list a", {
  element: (element) => {
    // Get the ID
    const id = element.getAttribute('id');
    
    // If it's in our list, set it's order
    // position from the URL
    if (ids.includes(id)) {
      const order = ids.indexOf(id);
      element.setAttribute(
        "style",
        `order: ${order}`
      );
    // Otherwise, remove it
    } else {
      element.remove();
    }
  },
});

Boom! I didn’t have to change the order in the source HTML document, but I can still get the displaying ordering to match what’s in the URL.

I love shifty little workarounds like this!


Reply via: Email · Mastodon · Bluesky

An Analysis of Links From The White House’s “Wire” Website

View

A little while back I heard about the White House launching their version of a Drudge Report style website called White House Wire. According to Axios, a White House official said the site’s purpose was to serve as “a place for supporters of the president’s agenda to get the real news all in one place”.

So a link blog, if you will.

As a self-professed connoisseur of websites and link blogs, this got me thinking: “I wonder what kind of links they’re considering as ‘real news’ and what they’re linking to?”

So I decided to do quick analysis using Quadratic, a programmable spreadsheet where you can write code and return values to a 2d interface of rows and columns.

I wrote some JavaScript to:

  • Fetch the HTML page at whitehouse.gov/wire
  • Parse it with cheerio
  • Select all the external links on the page
  • Return a list of links and their headline text

In a few minutes I had a quick analysis of what kind of links were on the page:

Screenshot of the Quadratic spreadsheet, with rows and columns of data on the left, and on the right a code editor containing the code which retrieved and parsed the data on the left.

This immediately sparked my curiosity to know more about the meta information around the links, like:

  • If you grouped all the links together, which sites get linked to the most?
  • What kind of interesting data could you pull from the headlines they’re writing, like the most frequently used words?
  • What if you did this analysis, but with snapshots of the website over time (rather than just the current moment)?

So I got to building.

Quadratic today doesn’t yet have the ability for your spreadsheet to run in the background on a schedule and append data. So I had to look elsewhere for a little extra functionality.

My mind went to val.town which lets you write little scripts that can 1) run on a schedule (cron), 2) store information (blobs), and 3) retrieve stored information via their API.

After a quick read of their docs, I figured out how to write a little script that’ll run once a day, scrape the site, and save the resulting HTML page in their key/value storage.

Screenshot of 9 lines of code from val.town that fetches whitehouse.gov/wire, extracts the text, and stores it in blob storage.

From there, I was back to Quadratic writing code to talk to val.town’s API and retrieve my HTML, parse it, and turn it into good, structured data. There were some things I had to do, like:

  • Fine-tune how I select all the editorial links on the page from the source HTML (I didn’t want, for example, to include external links to the White House’s social pages which appear on every page). This required a little finessing, but I eventually got a collection of links that corresponded to what I was seeing on the page.
  • Parse the links and pull out the top-level domains so I could group links by domain occurrence.
  • Create charts and graphs to visualize the structured data I had created.

Selfish plug: Quadratic made this all super easy, as I could program in JavaScript and use third-party tools like tldts to do the analysis, all while visualizing my output on a 2d grid in real-time which made for a super fast feedback loop!

Once I got all that done, I just had to sit back and wait for the HTML snapshots to begin accumulating!

It’s been about a month and a half since I started this and I have about fifty days worth of data.

The results?

Here’s the top 10 domains that the White House Wire links to (by occurrence), from May 8 to June 24, 2025:

  1. youtube.com (133)
  2. foxnews.com (72)
  3. thepostmillennial.com (67)
  4. foxbusiness.com (66)
  5. breitbart.com (64)
  6. x.com (63)
  7. reuters.com (51)
  8. truthsocial.com (48)
  9. nypost.com (47)
  10. dailywire.com (36)

A pie chart visualizing the top ten links (by domain) from the White House Wire

From the links, here’s a word cloud of the most commonly recurring words in the link headlines:

  1. “trump” (343)
  2. “president” (145)
  3. “us” (134)
  4. “big” (131)
  5. “bill” (127)
  6. “beautiful” (113)
  7. “trumps” (92)
  8. “one” (72)
  9. “million” (57)
  10. “house” (56)

Screenshot of a word cloud with “trump” being the largest word, followed by words like “bill”, “beautiful” and “president”.

The data and these graphs are all in my spreadsheet, so I can open it up whenever I want to see the latest data and re-run my script to pull the latest from val.town. In response to the new data that comes in, the spreadsheet automatically parses it, turn it into links, and updates the graphs. Cool!

Screenshot of a spreadsheet with three different charts and tables of data.

If you want to check out the spreadsheet — sorry! My API key for val.town is in it (“secrets management” is on the roadmap). But I created a duplicate where I inlined the data from the API (rather than the code which dynamically pulls it) which you can check out here at your convenience.

Update: 2025-07-03

After publishing, I realized that I wasn’t de-duplicating links. Because this works by taking snapshots once a day of the website’s HTML, if the same link stayed up for multiple days, it was getting counted twice.

So I tweaked my analysis to de-duplicate links because I want a picture of all the links shared over time. It didn’t really change the proportions of which sites were shared most frequently, just lowered their occurrence because links now weren’t counted twice.

Given that, here’s an update of the “top 10 links by domain” from May 8th to July 3rd.

  1. youtube.com (73)
  2. foxnews.com (36)
  3. x.com (31)
  4. breitbart.com (29)
  5. nypost.com (28)
  6. thepostmillennial.com (26)
  7. foxbusiness.com (22)
  8. truthsocial.com (20)
  9. washingtontimes.com (16)
  10. dailywire.com (15)

A pie chart visualizing the top ten links (by domain) from the White House Wire


Reply via: Email · Mastodon · Bluesky

Related posts linking here: (2025) Follow Up: An Analysis of YouTube Links From The White House’s “Wire” Website

Transforming HTML With Netlify Edge Functions

View

I’ve long wanted the ability to create custom collections of icons from my icon gallery.

Today I can browse collections of icons that share pre-defined metadata (e.g. “Show me all icons tagged as blue”) but I can’t create your own arbitrary collections of icons.

That is, until now!

I created a page at /lookup that allows you to specify however many id search params you want and it will pull all the matching icons into a single page.

Here’s an example of macOS icons that follow the squircle shape but break out of it ever-so-slightly (something we’ll lose with macOS Tahoe).

It requires a little know how to construct the URL, something I’ll address later, but it works for my own personal purposes at the moment.

So how did I build it?

Implementation

So the sites are built with a static site generator, but this feature requires an ability to dynamically construct a page based on the icons specified in the URL, e.g.

/lookup?id=foo&id=bar&id=baz

How do I get that to work? I can’t statically pre-generate every possible combination[1] so what are my options?

  1. Create a “shell” page that uses JavaScript to read the search params, query a JSON API, and render whichever icons are specified in the URL.
  2. Send an HTML page with all icons over the wire, then use JavaScript to reach into the DOM and remove all icons whose IDs aren’t specified in the page URL.
  3. Render the page on the server with just the icons specified in the request URL.

No. 1: this is fine, but I don’t have a JSON API for clients to query and I don’t want to create one. Plus I have to duplicate template logic, etc. I’m already rendering lists of icons in my static site generator, so can’t I just do that? Which leads me to:

No. 2: this works, but I do have 2000+ icons so the resulting HTML page (I tried it) is almost 2MB if I render everything (whereas that same request for ~4 icons but filtered by the server would be like 11kb). There’s gotta be a way to make that smaller, which leads me to:

No. 3: this is great, but it does require I have a “server” to construct pages at request time.

Enter Netlify’s Edge Functions which allow you to easily transform an existing HTML page before it gets to the client.

To get this working in my case, I:

  1. Create /lookup/index.html that has all 2000+ icons on it (trivial with my current static site generator).
  2. Create a lookup.ts edge function that intercepts the request to /lookup/index.html
  3. Read the search params for the request and get all specified icon IDs, e.g. /lookup?id=a&id=b&id=c turns into ['a','b','c']
  4. Following Netlify’s example of transforming an HTML response, use HTMLRewriter to parse my HTML with all 2000+ icons in it then remove all icons that aren’t in my list of IDs, e.g. <a id='a'>…</a><a id='z'>…</a> might get pruned down to <a id='a'>…</a>
  5. Transform the parsed HTML back into a Response and return it to the client from the function.

It took me a second to get all the Netlify-specific configurations right (put the function in ./netlify/edge-functions not ./netlify/functions, duh) but once I strictly followed all of Netlify’s rules it was working! (You gotta use their CLI tool to get things working on localhost and test it yourself.)

Con-clusions

I don’t particularly love that this ties me to a bespoke feature of Netlify’s platform — even though it works really well!

But that said, if I ever switched hosts this wouldn’t be too difficult to change. If my new host provided control over the server, nothing changes about the URL for this page (/lookup?id=…). And if I had to move it all to the client, I could do that too.

In that sense, I’m tying myself to Netlify from a developer point of view but not from an end-user point of view (everything still works at the URL-level) and I’m good with that trade-off.


  1. Just out of curiosity, I asked ChatGPT: if you have approximately 2,000 unique items, how many possible combinations of those IDs can be passed in a URL like /lookup?id=1&id=2? It said the number is 2^2000 which is “astronomically large” and “far more than atoms in the universe”. So statically pre-generating them is out of the question.

Reply via: Email · Mastodon · Bluesky

Related posts linking here: (2025) Setting Element Ordering With HTML Rewriter Using CSS

Little Swarming Gnats of Data

View

Here’s a screenshot of my inbox from when I was on the last leg of my flight home from family summer vacation:

Screenshot of the Mail app on iOS where the screen is completely full of messages from United Airlines.

That’s pretty representative of the flurry of emails I get when I fly, e.g.:

  • Check in now
  • Track your bags
  • Your flight will soon depart
  • Your flight will soon board
  • Your flight is boarding
  • Information on your connecting flight
  • Tell us how we did

In addition to email, the airline has my mobile number and I have its app, so a large portion of my email notifications are also sent as 1) push notifications to my devices, as well as 2) messages to my mobile phone number.

So when the plane begins boarding, for example, I’m told about it with an email, a text, and a push notification.

I put up with it because I’ve tried pruning my stream of notifications from the airlines in the past, only to lose out on a vital notification about a change or delay. It feels like my two options are:

  1. Get all notifications multiple times via email, text, and in-app push.
  2. Get most notifications via one channel, but somehow miss the most vital one.

All of this serendipitously coincided with me reading a recent piece from Nicholas Carr where he described these kinds of notifications as “little data”:

all those fleeting, discrete bits of information that swarm around us like gnats on a humid summer evening.

That feels apt, as I find myself swiping at lots of little data gnats swarming in my email, message, and notification inboxes.

No wondering they call it “fly”ing 🥁


Reply via: Email · Mastodon · Bluesky

My Copy of The Internet Phone Book

View

I recently got my copy of the Internet Phone Book. Look who’s hiding on the bottom inside spread of page 32:

Photograph of page 32 of the Internet Phone Book listing Jim Nielsen.

The book is divided into a number of categories — such as “Small”, “Text”, and “Ecology” — and I am beyond flattered to be listed under the category “HTML”! You can dial my site at number 223.

As the authors note, the sites of the internet represented in this book are not described by adjectives like “attention”, “competition”, and “promotion”. Instead they’re better suited by adjectives like “home”, “love”, and “glow”.

These sites don’t look to impose their will on you, soliciting that you share, like, and subscribe. They look to spark curiosity, mystery, and wonder, letting you decide for yourself how to respond to the feelings of this experience.

But why make a printed book listing sites on the internet? That’s crazy, right? Here’s the book’s co-author Kristoffer Tjalve in the introduction:

With the Internet Phone Book, we bring the web, the medium we love dearly, and call it into a thousand-year old tradition [of print]

I love that! I think the juxtaposition of websites in a printed phone book is exactly the kind of thing that makes you pause and reconsider the medium of the web in a new light. Isn’t that exactly what art is for?

Kristoffer continues:

Elliot and I began working on diagram.website, a map with hundreds of links to the internet beyond platform walls. We envisioned this map like a night sky in a nature reserve—removed from the light pollution of cities—inviting a sense of awe for the vastness of the universe, or in our case, the internet. We wanted people to know that the poetic internet already existed, waiting for them…The result of that conversation is what you now hold in your hands.

The web is a web because of its seemingly infinite number of interconnected sites, not because of it’s half-dozen social platforms. It’s called the web, not the mall.

There’s an entire night sky out there to discover!


Reply via: Email · Mastodon · Bluesky

Becoming an Asshole

View

This post is a secret to everyone! Read more about RSS Club.

I’ve been reading Apple in China by Patrick McGee.

There’s this part in there where he’s talking about a guy who worked for Apple and was known for being ruthless, stopping at nothing to negotiate the best deal for Apple. He was so aggressive yet convincing that suppliers often found themselves faced with regret, wondering how they got talked into a deal that in hindsight was not in their best interest.[1]

One particular Apple executive sourced in the book noted how there are companies who don’t employ questionable tactics to gain an edge, but most of them don’t exist anymore. To paraphrase: “I worked with two kinds of suppliers at Apple: 1) complete assholes, and 2) those who are no longer in business.”

Taking advantage of people is normalized in business on account of it being existential, i.e. “If we don’t act like assholes — or have someone on our team who will on our behalf[1] — we will not survive!” In other words: All’s fair in self-defense.

But what’s the point of survival if you become an asshole in the process?

What else is there in life if not what you become in the process?

It’s almost comedically twisted how easy it is for us to become the very thing we abhor if it means our survival.

(Note to self: before you start anything, ask “What will this help me become, and is that who I want to be?”)


  1. It’s interesting how we can smile at stories like that and think, “Gosh they’re tenacious, glad they’re on my side!” Not stopping to think for a moment what it would feel like to be on the other side of that equation.

Reply via: Email · Mastodon · Bluesky