Jim Nielsen’s Blog

You found my HTML feed — I also have an XML feed and a JSON feed.

I ♥ HTML

Subscribe to my blog by copy-pasting this URL into your RSS reader.

(Learn more about RSS and subscribing to content on the web at aboutfeeds.)

Recent posts

Grateful: Colors in console.log()

View

So there I am, having an issue where my UI state isn’t updating correctly. What do I do? What every developer does: turn to console.log() and troubleshoot by logging values.

I have a named color (e.g. blue) and a corresponding HSL color string for that named color (e.g. 100 50% 0%). I log those in the click handler function where I expect the color to change.

onClick={() => {
  // Some stuff...
  
  console.log(
    `theme change: ${colorName} ${colorHslString}`
  )
}

Then I go click around in the UI and observe the bug. The problem is, when I look at the console to see if what the UI is doing matches what the code is doing, it’s impossible to tell. The values are indiscernible because I can’t read HSL.

Animated gif of a mouse clicking an orange button, then a purple button, then back to the orange button and the console logging HSL color string values each time it gets clicked.

Do you know if 262.1 83.3% 57.8% is “violet” off the top of your head? Well I don't.

Then this vague memory hits me: can’t you log something to the console with a bit of color? Sure enough, I find a reference in my notes!

So I update my console.log() statement to style the log statement the same color value it’s logging, making it super easy to visually diff!

console.log(
  `%c theme change: ${colorName} ${colorHslString}`,
  `color: white; background-color: hsl(${colorHslString})`
);

Now when it says “violet” it should actually paint a color that looks like violet. Here’s what debugging looks like under this scenario:

Animated gif of a mouse clicking an orange button, then a purple button, then back to the orange button and the console logging HSL color string values each time it gets clicked that are styled with a color.

Yes! That’s super helpful. I can see the color name being logged doesn’t match the color value. That gives me a really good sense for where the bug is.

I look at the code, fix the bug, then go back to the UI and test again:

Animated gif of a mouse clicking an orange button, then a purple button, then back to the orange button and the console logging HSL color string values each time it gets clicked that are styled with a color.

Boom! It works.

So I’m expressing my gratitude for being able to style console.log statements!


Reply
Tags

Ryan Dahl Talks Deno on The Changelog

View

Ryan Dahl was on The Changelog to talk about Deno 2 specifically and his work on JavaScript more broadly. What follows are a few things that stood out to me.

His Regrets From Node Are Now in Deno

I think it’s interesting that Ryan’s famous talk 10 Things I Regret About Node.js served as the manifesto and launching point for Deno. And yet, he’s now re-introduced some of those regrets into Deno — out of practicality, a point he openly admits in the interview.

For example, here are some of his stated regrets from Node.js:

Regret: package.json

It's unfortunate that there is centralized (privately controlled even) repository for modules.

And now Deno has spawned a registry: JSR.

If only relative files and URLs were used when importing, the path defines the version. There is no need to list dependencies.

I loved this about the original version of Deno. No need for a package.json because package version info was in the module URL. But they’ve been moving away from this. Which leads me to:

Regret: require("module") without the extension ".js"

Needlessly less explicit.

Adjacent to his point about package.json, if you use relative paths or full URLs, all the info you need is in the string: package name, version, extension, etc.

But alas, it seems like these purist principles weren’t enough to sway folks, though I’m not sure if that’s simply because of the legacy convention and baggage of Node itself. Out of practicality, many of Ryan’s “regrets” about Node.js have made it into Deno and I appreciate his honesty in conceding the point (and his ability to articulate a rationale).

Play to Your Strengths

Jerod asks Ryan a great question: instead of building something new and different with Deno, why not concentrate your efforts in making Node.js better? Ryan’s response:

I’m not willing to sit in committee for 13 years trying to make [what we built into Deno by default] happen

He’s referring to all the base infrastructure around Deno, such as:

  • Rust codebase
  • Secure by default capabilities
  • Typescript built-in
  • Web API compatibilities
  • LSP
  • Code formatting
  • Linting
  • etc.

Ryan believes JavaScript continues to merit modern enhancements because, give its ubiquity, its such a core part of humanity:

JavaScript is not like other programming languages. It is the default programming language because so much human infrastructure is built on the web. And because JavaScript is like HTTP or CSS or HTML, it is one of the protocols of the web. It has a future unlike that of Swift. Lots of people use Swift. A lot of infrastructure is built on Swift. But it’s not like JavaScript. JavaScript will be here in 5 years, if not 10, if not 20, if not forever. It is deeply embedded in humanity at this point. And I think it is worth the effort to strive to make it simple.

It’s an intriguing thought that pokes at the tension between the idea of being a revolutionary vs. trying to change a system from within. We all only have so much time and we have to ask ourselves where that time is best spent based on our own faculties, strengths, and weaknesses.

Maybe you have strong political sensibilities and could make sweeping changes inside an established organization. Or maybe that’s your weakness and you’d be better off in the wilderness developing your ideas, which perhaps never fully develop into their own, self-sustaining platform or organization, but they may spread and infiltrate into the existing systems of your time and find root there.

Everybody has to find their own path. I can appreciate Ryan articulating the rationale for his (and Deno’s) — even though I’m still kinda sad about the module stuff tbh.

Last, But Not Least: Free JavaScript

You can sense Ryan’s passion for JavaScript which overflows when he talks about his initiative “Free JavaScript”.

Did you know Oracle owns the name JavaScript as a trademark? So, for example, nobody can have a conference called “JavaScript Conf”.

It seems kind of ridiculous when you think about it. Can you imagine some corporate entity owning the name of a core web technology? Like if Apple owned "HTTP”, or Google owned “HTML", or Microsoft owned "CSS”? That’d be absurd.

I already signed the petition.


Reply
Tags

“Easier and More Convenient” They Said…

View

Comic of a woman at a ticket train ticket counter where the attendant tells her “OK, one more time: Go home and log on to our website from your computer, create an account and purchase your ticket with your credit or debit card, download the ticket to a smartphone, then come back at the allocated time... Just what part of easier and more convenient' don't you get?”

The other day in our morning rush before school my wife asked for help figuring out how to put lunch money on our kids’ school accounts.

For some time she’s been doing it “the hard way”: talk to the people in the front office of the school every few months and swipe a credit card. Every time she did it, they would remind her there was an “easier and more convenient” way to do it via an app. But that seemed like the hard way of doing it: find an app, download it, create yet another account (and another password to remember), enter a credit card, etc. So she asked for my help.

First I had to find the app in the App Store. This sounds like an easy task, but all I had was the name of a generic, three-letter service. Have you tried searching for an app with a generic name in the App Store? The results are legion, and you have no heuristics for gauging the authenticity of the app. To be honest, this was an app for a county lunch school program, which means it would probably look and feel like a phishing scam.

Once I finally found the app and verified with my wife that it was the one the school uses, I began the rest of the process: download and install the app, create an account and password, enter my credit card info, and tie my children to the account. I assure you, it was not “easy and convenient”. And when I was done, I was told it would take up to three days for the money to show on my account — and my kids needed lunch that day. Would they get it? Who knew!

So an instantaneous digital transaction would take a few days for servers to register it. Meanwhile I thought, “cash seems like a really innovative invention right now…”

And when I was all done with the task, the app had the nerve to ask me how my “experience” was. Experience? That was not an experience. Our family vacation we took this summer to Canada, that was an experience. What I had with this app was an ordeal.

Come to think of it, that’s the terminology product teams should be forced to use when they solicit people via email — “How was your ordeal with us?” Perhaps folks would reframe how many people view their service: as a task to be completed as soon as possible. And once we complete it, we forget about the app and move on with our lives.

Grumpy McGrumpster today with this post, I know.

These thoughts spur from this great article “Nobody wants to use any software” (hat tip to Eric Bailey’s newsletter), which states:

We don’t need to delight people in the software itself. Delight in software is almost always a delay.

The delight most people are looking for is outside of the software we’re building. Best to get them on their way, away from our thing, and on to the delight they’re looking for — their children, a walk through a field, a cookie and some milk, playing a tune on the guitar, whatever.

In my case, it was “just let me put some lunch money on my kids’ account” so I can get in the car and take my kids to school, talking Pokémon along the way and resting assured that they’ll have something to put in their belly when lunch time comes.


Reply

Putting the “Person” in “Personal Website”

View

The other day I saw a meme that went something like this:

Isn’t it crappy how basic human activities like singing, dancing, and making art have been turned into skills instead of being recognized as behaviors? The point of doing these things has become to get good at them. But they should be recognized as things humans do innately, like how birds sing or bees make hives.

I thought about that for a minute, then decided: making websites should be the same!

The original vision for the web, according to Tim Berners-Lee, was to make it a collaborate medium where everyone could read and write.

Social media sort of achieved this, but the incentives are off. And it’s not just about ownership of the content you produce and who can monetize it, but the context in which you produce it. Mandy nails this in her recent piece “Coming home”:

While one of the reasons oft declared for using POSSE is the ability to own your content, I’m less interested in ownership than I am in context. Writing on my own site has very different affordances: I’m not typing into a little box, but writing in a text file. I’m not surrounded by other people’s thinking, but located within my own body of work. As I played with setting this up, I could immediately feel how that would change the kinds of things I would say, and it felt good. Really good. Like putting on a favorite t-shirt, or coming home to my solid, quiet house after a long time away.

Yes! This is why I believe everyone could benefit from a personal website. Its form encourages you to look inward, whereas every social platform on the internet encourages you to look outward.

A personal website has affordances which encourage you to create something that you couldn’t otherwise create anywhere else, like YouTube or Reddit or Facebook or Twitter or even Mastodon. Why? Because the context of those environments is outward looking. It’s not personal, but social. The medium shapes the message.

If I were to put this in terms of a priority of constituencies, it would be something like this:

  • Personal website: personal over social.
  • Social platform: social over personal.

Additionally, a personal website and a social platform are two different environments: one I’ve cultivated, the other I’ve been granted. As Mandy puts it:

[having a personal website] allowed me to cultivate the soil to suit my purposes—rather than having to adapt my garden to the soil I was given

Like dancing or singing, you don’t have to be skilled to do them. Personal websites should be the same. They’re for everyone. Like dancing and singing, their expression can be as varied as every individual human.


Reply

Randomness, Serendipity, and an “I Wouldn’t Recommend This” Algorithm

View

Sean Voisen has a great post about 1) how we as humans think of randomness, 2) how computers simulate randomness, and the difference between the two.

He puts forth an intriguing thought: in a world increasingly driven by computation, how does that affect randomness in our lives? Here’s Sean:

We could all benefit from more randomness in our lives more than we may realize. By veering off the beaten path, by being exposed to new things we would otherwise never expose ourselves to, we increase the possibilities for serendipitous and creative encounters. But our increasingly computationally-dependent world is fundamentally incompatible with allowing this to happen.

Be exposed to things we would otherwise never be exposed to? That sounds like the antithesis of the algorithm.

The algorithm is: “You liked that? I bet you would like this!”

But where is an algorithm that says: “You liked that? I bet you would never choose this — but here it is anyway!”

I have to admit, I have a number of things in my life where I could say, “I would have never chosen ____, but it’s been one of the best things in my life!” Many things I would’ve never chosen, yet they came to me, and they’ve changed my perspective and outlook and my life.

Where’s that algorithm?

I suppose it’s hard to make money off of, “Here’s some stuff you would never choose for yourself.”

So, where possible, I like the suggestion to make room for randomness in your life — and that might just mean stepping away from the pseudo-randomness of the computer more often.


Reply

Blogging & Listening

View

When you read a great blog post, the feeling you often get is: “I already knew this, I just hadn’t been able to express it!”

In this sense, writing a great blog post is about listening.

If you’re listening — to others, your coworkers, the people you follow, your own experiences, your users, etc. — there are undertones of something being said collectively. If you can hear it, write it down.

People convey important things without stating them explicitly. When those unstated things resonate with you, write them down and publish them.

Other people may love what you write because it resonates with what they’ve been feeling and hearing. It’s both validating and clarifying!

So if you don’t know what to blog about, listen. Listen to what you hear and write it down. I doubt you’re the only one hearing it, but you can be one of the few writing it down.


Reply

Estimated Reading Time Widgets

View

Beware ye who enter, here be personal opinions.

I’ve never understood reading time estimation widgets. Why did these get so popular? Is it because they’re easy? I mean, you can grab one off npm no problem.

Screenshot of a large number of search results from npm for the keyword “reading-time”.

Baldur suggests a theory in his piece about estimated reading times:

At some point a programmer read in a study that the average person read 233 words per minute and decided that this would be a great way to estimate reading time for everybody on the fucking planet.

The “reading time” for an article always felt so personal to me. As Baldur also points out, it can be affected by so many variables, such as:

  • Word count or length
  • Writing style
  • Design (formatting, typeface, etc.)
  • Individual physical factors
  • Vocabulary
  • Medium

Because I’ve always seen reading time as such an incredibly personal thing, I’ve never once paid any heed to these widgets. In fact, I’ve been slightly perturbed a service would presume to know how quickly I could read an article.

That’s to say nothing of the fact that if I come to a text to understand it (or merely enjoy it for that matter), speed is the very last thing on my mind.

I’ve always viewed any service that sticks a “reading time” widget on its articles as the literary equivalent of fast-food: you’re not here for quality, but for expediency.

Personally, I think they devalue a text more than they add to it.

But hey, I’ll grant that’s just like, my opinion, man.


Reply

The Ruthless Edit

View

Rick Rubin gives this advice about working in the studio with artists when making an album:

[Let’s say] We’ve recorded twenty-five songs. We think the album is going to have ten. Instead of picking our favorite ten, we limit it to: “What are the five or six we can’t live without?” [So you] go past the goal to get to the real heart of it, and then you say: “Ok here are the five or six we can't live without, now what would we add to that which makes it better and not worse?” It puts you in a different frame when you start with building and not removing.

I love this! So often in design, engineering, or product, you’re faced with this decision: how do we pare down what we have to something that feels like a cohesive whole?

The impulse is to ask, “Well what do we have to cut it down to?” Then, knowing the limit, you pick your favorites until you hit it.

But that impulse overlooks the fact that things don’t exist in isolation. They exist in relation to each other. So if you’re merely picking your favorites up to an arbitrary limit, you’ll be left with a whole whose individual pieces are great but don’t sum to anything greater.

This particular course of action creates a mindset where there is no more “creation” only “deletion”. You go from a mode of “creating” to a mode of “editing” but you never look back to creating.

Instead, Rick recommends this idea of a “ruthless edit” where you go beyond your initial limit, then shift back to “creating” mode.

If the limit is ten, you choose five. Then you switch from editing back to creating begin asking: how can we add back in a way that elevates the whole? This encourages you to not merely selecting things based on their individual merits. Rather, you select a core set of things that carry the thrust of what you’re trying to do and then you add complementary things around that core to bolster the very things you loved so much in the first place!

An Illustration

This can all sound a little theoretical with words alone. Let me try to illustrate with an example.

Let’s say you have roughly twenty five things.

Twenty five seeminly random black circles scattered on a white background.

And you’re told the limit is ten, so you single out your ten favorites.

Twenty five seeminly random black circles scattered on a white background, with ten random circles highlighted in red.

Then you cut away everything else, so you’re merely left with your favs. How well do they stand together as a whole?

Ten seeminly random red circles scattered on a white background

Contrast this with a scenario where you follow Rick’s advice.

You’re told the limit is ten, so you start with five of your absolute favorites — the ones you know you can’t live without.

Twenty five seeminly random black circles scattered on a white background, with five random circles highlighted in red.

Now you can ask important questions about building back up to ten. How do these five relate to each other? How do they relate to the remaining options? How can I choose five more that build on these core five favorites and produce something whose sum is greater than the individual parts?

As you look at these relationships, a new, underlying pattern reveals itself which you hadn’t seen before. So you choose five more which support your initial core selection, making the overarching whole better and more cohesive.

Twenty five seeminly random black circles scattered on a white background, with ten circles highlighted in red revealing an undelying structure and pattern to their arrangement.

What you’re now left with, once you remove everything else, is something that reveals a unified, pleasing whole.

Ten circles on a white background in a structured grid.

This all comes about by changing the process through which you make edits. Editing becomes a process where you ruthlessly select a core then switch back to “creating” mode and build something around that core to create something amazing!


Reply
Tags

Seeing Others in Data, But Not Ourselves

View

Stanford psychologist Emily Pronin and her colleagues came up with an interesting study in human behavior.

Subjects were given incomplete words and asked to complete them with the first word that came to mind.

For example, you’re given the fragments B__T and CHE__ and you write BOOT and CHESS.

Afterwards, subjects were asked to explain what they thought their responses revealed about themselves: their interests, motivations, and character.

Then they were shown responses by other participants and asked the same question: what do these answers reveal about this person?

What happened is fascinating and simultaneously not surprising. Here’s author Kathryn Schulz’s summary:[1]

the same person who characterized her own choice of words as "happenstance" and felt that they revealed nothing about her inferred the following from another person's choices: ”I think this girl is on her period ... I also think that she either feels she or someone else is in a dishonest sexual relationship.”

People saw their own word choices as mere happenstance, while the word choices of others served as a kind of mirror reflecting the inner-most self of others.

Looking at their own word choices, one participant said:

I don't agree with these word-stem completions as a measure of my personality.

But looking at someone else’s, they surmised[2]:

I get the feeling that whoever did this is pretty vain, but basically a nice guy.

I think this is a fascinating study of a trait that, to be quite honest, I know operates in my own mind.

We believe other people can be known from the outside based on their words and deeds. However, we believe we can only be known from the inside — that’s how we know ourselves — and our words and deeds are not a fully accurate representation of who we are.

I wonder how much this phenomenon operates in the software industry as we pour over troves of user data looking for patterns that can lead us to generalized statements about behavior — statements we would make about others based on their outward behavior (as measured by data), but knowing inwardly we would never conclude the same thing about ourselves.

In other words: we believe data is a reflection of others, but not ourselves.

For example:

  • Seeing others: “They clicked on that banner ad, they must be interested in buying the product!”
  • Seeing ourselves: “lol, look at this thing! Who would ever buy this? I gotta click to see how ridiculous it is…”

Or:

  • Seeing others: “When prompted to leave a review, they clicked 1 star, so they must not like our product!”
  • Seeing ourselves: “I was too busy to leave a review when that thing popped up, so I just clicked 1 star because I couldn’t give a real assessment in good conscience and needed to get on with what I was doing.”

Or:

  • Seeing others: “They dismissed the banner offering them 50% off. They don’t like our sale!”
  • Seeing ourselves: “This random banner popped up while I was simultaneously clicking somewhere else and it immediately disappeared, so I never actually read what it said.”

I’m probably wandering too deep into the intersection of human psychology and science, so I’ll stop here.

But the general idea, as pointed out in Being Wrong, still stands: each of us live with our own intricate, internal reality. Our moods, emotions, and thoughts fluctuate in a complex way we ourselves don’t even understand. It’s easy to feel no one can draw conclusions about our true nature without access to this inner world. But do we extend the same courtesy to others?

Neither you nor I can be truly known by the data we leave behind.


Footnotes
  1. This story comes from Kathryn Schulz’s book Being Wrong which I’ve been reading (shout out to Mandy for the recommendation). ⏎
  2. Want to read how funny some of these contrasting characterizations are? Check out my photo from the page in the book. ⏎
Reply

Personal Websites Are As Vulnerable As Us

View

I look at some people’s personal websites and think, “Stupendous! If I ever reach that zenith of personal web design, I will call it quits.”

Then I read a post by them later and they say something like, “Gah! I just really don’t like where I’m at with my personal website.”

And in my mind I say, “WHAAAAAATTTT??!?!?”

To me, they’re living the personal website dream! But they don’t feel that way. They seem to feel…well the same way I feel about my personal website.

It’s like our personal websites are a mirror to ourselves — a place where the mind’s eye must reconcile with the optical eye’s perception of reality.

It’s a torturous affair, to be sure.

And yet, people still publish those personal sites, those redesigns, those half-baked ideas.

There’s something vulnerable about publishing a personal website for the whole world to see, like standing up before a big crowd.

And there’s no bigger crowd than the whole internet.


Reply