MoreRSS

site iconJim NielsenModify

Designer. Engineer. Writer.20+ years at the intersection of design & code on the web.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Jim Nielsen

My Copy of The Internet Phone Book

2025-06-23 03:00:00

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

2025-06-16 03:00:00

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

The Continuum From Static to Dynamic

2025-06-12 03:00:00

Dan Abramov in “Static as a Server”:

Static is a server that runs ahead of time.

“Static” and “dynamic” don’t have to be binaries that describe an entire application architecture. As Dan describes in his post, “static” or “dynamic” it’s all just computers doing stuff.

Computer A requests something (an HTML document, a PDF, some JSON, who knows) from computer B. That request happens via a URL and the response can be computed “ahead of time” or “at request time”. In this paradigm:

  • “Static” is server responding ahead of time to an anticipated requests with identical responses.
  • “Dynamic” is a server responding at request time to anticipated requests with varying responses.

But these definitions aren’t binaries, but rather represent two ends of a spectrum. Ultimately, however you define “static” or “dynamic”, what you’re dealing with is a response generated by a server — i.e. a computer — so the question is really a matter of when you want to respond and with what.

Answering the question of when previously had a really big impact on what kind of architecture you inherited. But I think we’re realizing we need more nimble architectures that can flex and grow in response to changing when a request/response cycle happens and what you respond with.

Perhaps a poor analogy, but imagine you’re preparing holiday cards for your friends and family:

  • “Static” is the same card sent to everyone
  • “Dynamic” is a hand-written card to each individual

But between these two are infinite possibilities, such as:

  • A hand-written card that’s photocopied and sent to everyone
  • A printed template with the same hand-written note to everyone
  • A printed template with a different hand-written note for just some people
  • etc.

Are those examples “static” or “dynamic”? [Cue endless debate].

The beauty is that in proving the space between binaries — between what “static” means and what “dynamic” means — I think we develop a firmer grasp of what we mean by those words as well as what we’re trying to accomplish with our code.

I love tools that help you think of the request/response cycle across your entire application as an endlessly-changing set of computations that happen either “ahead of time”, “just in time”, or somewhere in-between.


Reply via: Email · Mastodon · Bluesky

The Web as URLs, Not Documents

2025-06-11 03:00:00

Dan Abramov on his blog (emphasis mine):

The division between the frontend and the backend is physical. We can’t escape from the fact that we’re writing client/server applications. Some logic is naturally more suited to either side. But one side should not dominate the other. And we shouldn’t have to change the approach whenever we need to move the boundary.

What we need are the tools that let us compose across the stack.

What are these tools that allow us to easily change the computation of an application happening between two computers? I think Dan is arguing that RSC is one of these tools.

I tend to think of Remix (v1) as one of these tools. Let me try and articulate why by looking at the difference between how we thought of websites in a “JAMstack” architecture vs. how tools (like Remix) are changing that perspective.

JAMstack: a website is a collection of static documents which are created by a static site generator and put on a CDN. If you want dynamism, you “opt-out” of a static document for some host-specific solution whose architecture is starkly different from the rest of your site.

Remix: a website is a collection of URLs that follow a request/response cycle handled by a server. Dynamism is “built-in” to the architecture and handled on a URL-by-URL basis. You choose how dynamic you want any particular response to be: from a static document on a CDN for everyone, to a custom response on a request-by-request basis for each user.

As your needs grow beyond the basic “static files on disk”, a JAMstack architecture often ends up looking like a microservices architecture where you have disparate pieces that work together to create the final whole: your static site generator here, your lambda functions there, your redirect engine over yonder, each with its own requirements and lifecycles once deployed.

Remix, in contrast, looks more like a monolith: your origin server handles the request/response lifecycle of all URLs at the time and in the manner of your choosing.

Instead of a build tool that generates static documents along with a number of distinct “escape hatches” to handle varying dynamic needs, your entire stack is “just a server” (that can be hosted anywhere you host a server) and you decide how and when to respond to each request — beforehand (at build), or just in time (upon request). No architectural escape hatches necessary.

You no longer have to choose upfront whether your site as a whole is “static” or “dynamic”, but rather how much dynamism (if any) is present on a URL-by-URL basis. It’s a sliding scale — a continuum of dynamism — from “completely static, the same for everyone” to “no one line of markup is the same from one request to another”, all of it modeled under the same architecture.

And, crucially, that URL-by-URL decision can change as needs change. As Dan Abramov noted in a tweet:

[your] build doesn’t have to be modeled as server. but modeling it as a server (which runs once early) lets you later move stuff around.

Instead of opting into a single architecture up front with escape hatches for every need that breaks the mold, you’re opting in to the request/response cycle of the web’s natural grain, and deciding how to respond on a case-by-case basis.

The web is not a collection of static documents. It’s a collection of URLs — of requests and responses — and tools that align themselves to this grain make composing sites with granular levels of dynamism so much easier.


Reply via: Email · Mastodon · Bluesky

Related posts linking here: (2025) The Continuum From Static to Dynamic

Some Miscellaneous Thoughts on Visual Design Prodded By The Sameness of AI Company Logos

2025-06-07 03:00:00

Radek Sienkiewicz in a funny-because-its-true piece titled “Why do AI company logos look like buttholes?“:

We made a circular shape [logo] with some angles because it looked nice, then wrote flowery language to justify why our…design is actually profound.

As someone who has grown up through the tumult of the design profession in technology, that really resonates. I’ve worked on lots of projects where I got tired of continually justifying design decisions with language dressed in corporate rationality.

This is part of the allure of code. To most people, code either works or it doesn’t. However bad it might be, you can always justify it with “Yeah, but it’s working.”

But visual design is subjective forever. And that’s a difficult space to work in, where you need to forever justify your choices.

In that kind of environment, decisions are often made by whoever can come up with the best language to justify their choices, or whoever has the most senior job title.

Personally, I found it very exhausting.

As Radek points out, this homogenization justified through seemingly-profound language reveals something deeper about tech as an industry: folks are afraid to stand out too much.

Despite claims of innovation and disruption, there's tremendous pressure to look legitimate by conforming to established visual language.

In contrast to this stands the work of individual creators whose work I have always loved — whether its individual blogs, videos, websites, you name it. The individual (and I’ll throw small teams in there too) have a sense of taste that doesn’t dilute through the structure and processes of a larger organization.

No single person suggests making a logo that resembles an anus, but when everyone's feedback gets incorporated, that's what often emerges.

In other words, no individual would ever recommend what you get through corporate hierarchies.

That’s why I love the work of small teams and individuals. There’s still soul. You can still sense the individuals — their personalities, their values — oozing through the work. Reminds me of Jony Ive’s description of when he first encountered a Mac:

I was shocked that I had a sense for the people who made it. They could’ve been in the room. You really had a sense of what was on their minds, and their values, and their joy and exuberance in making something that they knew was helpful.

This is precisely why I love the websites of individuals because their visual language is as varied as the humans behind them — I mean, just look at the websites of these individuals and small teams. You immediately get a sense for the people behind them. I love it!


Reply via: Email · Mastodon · Bluesky

Notes from Andreas Fredriksson’s “Context is Everything”

2025-06-05 03:00:00

I quite enjoyed this talk. Some of the technical details went over my head (I don’t know what “split 16-bit mask into two 8-bit LTUs” means) but I could still follow the underlying point.

First off, Andreas has a great story at the beginning about how he has a friend with a browser bookmarklet that replaces every occurrence of the word “dependency” with the word “liability”. Can you imagine npm working that way? Inside package.json:

{
  "liabilities": {
    "react": "^19.0.0",
    "typescript": "^5.0.0"
  },
  "devLiabilities": {...}
}

But I digress, back to Andreas.

He points out that the context of your problems and the context of someone else’s problems do not overlap as often as we might think.

It’s so unlikely that someone else tried to solve exactly our same problem with exactly our same constraints that [their solution or abstraction] will be the most economical or the best choice for us. It might be ok, but it won’t be the best thing.

So while we immediately jump to tools built by others, the reality is that their tools were built for their problems and therefore won’t overlap with our problems as much or as often as we’re led to believe.

Venn diagram with three circles. The first says 'My problems', the second 'Your problems' and the third 'Facebook’s problems' and they barely have any overlap and where they do it’s labeled “React”.

In Andreas’ example, rather than using a third-party library to parse JSON and turn it into something, he writes his own bespoke parser for the problem at hand. His parser ignores a whole swath of abstractions a more generalized parser solves for, and guess what? His is an order of magnitude faster!

Solving problems in the wrong domain and then glueing things together is always much, much worse [in terms of performance] than solving for what you actually need to solve.

It’s fun watching him step through the performance gains as he goes from a generalized solution to one more tailored to his own specific context.

What really resonates in his step-by-step process is how, as problems present themselves, you see how much easier it is to deal with performance issues for stuff you wrote vs. stuff others wrote. Not only that, but you can debug way faster!

(Just think of the last time you tried to debug a file 1) you wrote, vs. 2) one you vendored vs. 3) one you installed deep down in node_modules somewhere.)

Andreas goes from 41MB/s throughput to 1.25GB/s throughput without changing the behavior of the program. He merely removed a bunch of generalized abstractions he wasn’t using and didn’t need.

Surprise, surprise: not doing unnecessary things is faster!

You should always consider the unique context of your situation and weigh trade-offs. A “generic” solution means a solution “not tuned for your use case”.


Reply via: Email · Mastodon · Bluesky