Jim Nielsen’s Blog

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

I HTML

Recent posts

Relationship Advice for AI

View

You know what’s really helpful in solving my own problems? Writing them down, sending them to someone, and not hearing back.

You ever do that? For me, it’s a bulletproof method to solving problems.

It’s akin to those moments when you go to someone with a problem, you talk it through, you find a solution, you thank them for their help, and they say, “Well I didn’t even say anything, but you’re welcome.”

If I have a friend, co-worker, or collaborator who I know is on the other end of a chat box, typing out my problem and not hearing back from them can be a tremendous help.

Here’s an example of how it often goes:


Jim Nielsen, Friday at 12:53 PM
I’m having an issue where the deployment isn’t working. Failiures are coming from lines 123-125 of the build script...

Jim Nielsen, Friday at 12:59 PM
Oh, it looks like something changed in commit abc123e in the lock file...

Jim Nielsen, Friday at 1:02 PM
This is so weird, I hate troubleshooting this crap. Why is everything in the world garbage?

Jim Nielsen, Friday at 1:03 PM
Ok, I can’t figure this out. I'm going to need your help when you have a second.

Jim Nielsen, Friday at 1:09 PM
Oh hey, actually I think I know what the problem is...

Jim Nielsen, Friday at 1:11 PM
Ok, it’s fixed now. Nevermind, I don’t need your help. Thanks!

Co-worker, Friday at 4:03 PM
You're welcome, glad I could help!


In contrast, AI is too eager to respond back with something when nothing would be much more helpful.

Knowing another human is there to connect with — available, listening, but not speaking — has helped me many times as I express my thinking step-by-step.

So let me give you some relationship advice, AI. Sometimes you don’t need to say or do anything. You just need to listen.

Cool? Thanks.


Reply via: Email :: Mastodon :: Bluesky

Tagged in: #ai

Tools As Ways of Being

View

I took notes from Sean Voisen’s call for more hybrid tools. He speaks for a moment on generative AI and its inclusion into existing tools, but reading between the lines the insight I found was how our tools can trigger empathy for people and disciplines:

One of the greatest goals we can have for [making] tools…is that in expanding all of our respective capabilities, we do not replace our human teammates, but rather we participate more deeply in the creative process together.

A good tool improves your output.

A great tool improves your output and your understanding and empathy for others and their disciplines.

If designing tools is designing ways of being — “we shape our tools and they shape us” — then the tools we use together are shared ways of being. They facilitate us not only getting stuff done together, but being together. And that being can bring a better understanding of each other.

I don’t think that’s too crazy to assert, especially when you look at communities that coalesce around tools, like Clojure. People love their tools, and they identify with the principles they embody and the communities that support them.

Our tools are ways of being. How important, then, that we carefully consider their design as well as proliferate their diversity.


Reply via: Email :: Mastodon :: Bluesky

Using Locally-Installed CLI Tools In Node Projects

View

You have a dependency that provides a CLI tool, how do you use it?

Even though you did npm i from your project root, if you run <tool> <command> it won’t work because that tool is not in your global path.

You could install <tool> globally, but then if you have <tool> in multiple projects and you run <tool> <command> in another project it might not be the same version of the tool.

For example, you might have tool@0.1.0 in one project and tool@0.2.0 in another, and they might have different CLI commands. So you want to run/test whatever version of tool is installed in your local project (e.g. the one in package.json), you need something other than the globally installed version.

Over time, there are three ways I’ve learned to deal with this problem. I’m listing them here for myself.

For the examples, I am going to be using the ori command line tool from Web Origami, but they can be generalized to any CLI tool.

Use npx

You can run a package you have installed locally — or one you don’t have installed at all! — using npx.

Note: npx is part of npm. If you have npm installed, you also have npx.

npx ori version

Pros:

  • Short 3-character command to do what you want.

Cons:

  • ??? just that you have to know it exists, I guess.

Invoke Directly From node_modules

You can reference the locally-installed CLI tool directly in node_modules and run it.

When npm installs stuff, it sticks executables in a special .bin folder, which is where you’ll find any CLI tools you installed.

# From your project root
./node_modules/.bin/ori version

Pros:

  • Let’s you run the CLI tool dependency that’s installed locally to the project.

Cons:

  • Lots of extra typing each time you want to run an executable.

Add a Script to package.json

If the CLI tool is a dependency in the project, you can formulate the command as a script in package.json

"scripts": {
  "ori-version": "ori version"
},
"dependencies": {
  "@weborigami/ori": "^0.2.5"
}

Then run it with:

npm run ori-version

This will use the locally-installed version of the ori command line tool.

Pros:

  • Useful for things like build commands on remote servers (e.g. tell Netlify to run npm run build).

Cons:

  • When you’re iterating with a CLI tool locally, the feedback cycle for this method is incredibly cumbersome: type the command in package.json, save the file, run npm run <command>, see if it worked, repeat.

Reply via: Email :: Mastodon :: Bluesky

Tagged in: #node

Gotchas in Naming CSS View Transitions

View

I’m playing with making cross-document view transitions work on this blog.

Nothing fancy. Mostly copying how Dave Rupert does it on his site where you get a cross-fade animation on the whole page generally, and a little position animation on the page title specifically.

Animated gif of a mouse clicking on a blog post title and it animating to the top on the next HTML page.

To animate the page title, I need a unique ID to target the element I want to transition between pages, e.g.

<!-- 1st page HTML -->
<a
  href="/2024/i-love-kitkats"
  style="view-transition-name: kitkats">
  I Love KitKats
</a>

<!-- 2nd page HTML -->
<h1 style="view-transition-name: kitkats">
  I Love KitKats
</h1>

The problem with the above is that, if I have page that lists all my blog posts and I have another one about KitKats, what will the ID be?

Well I already have a globally-unique ID for each post: the post’s URL path!

So, in my static site generator, I think “I’ll just use my post’s path as the transition name!”

<a
  href="/2024/i-love-kitkats"
  style="view-transition-name: /2024/i-love-kitkats">
  I Love KitKats
</a>  

I’m not actually sure if this will work because of the forward slashes, but I try it.

No dice.

“Maybe I need to wrap it in quotes, like a the name of a value in font-family?”

So I try that:

<a
  href="/2024/i-love-kitkats"
  style="view-transition-name: '/2024/i-love-kitkats'">
  I Love KitKats
</a>  

Nope, that doesn't work either.

Ok, fine. I’ll just strip out the slashes in the path. I don’t need the slashes for it to be a unique identifier, e.g.

postPath.replace(/\//g, '')

Which gives me HTML like this:

<a
  href="/2024/i-love-kitkats"
  style="view-transition-name: 2024i-love-kitkats">
  I Love KitKats
</a> 

Still no dice.

After trying to get it working without looking at the manual, I concede to looking up view-transition-name on MDN. The docs say I have to use “a distinct identifying name (a <custom-ident>)”.

“What is a <custom-ident>?” I follow that link and read about it.

The docs throw some shade at me:

A <custom-ident> must not be placed between single or double quotes as this would be identical to a <string>.

Whoops.

Ok, so it’s an identifier that has some special rules, like that you can’t use an already-reserved global CSS name like “inherit”, “unset”, or “auto”.

Also you can’t use a forward slash (my bad).

And you can’t start the string with a number (my bad).

So I stick a prefix on each, e.g.

'title-${postPath}'.replace(/\//g, '')

Giving me:

<a
  href="/2024/i-love-kitkats"
  style="view-transition-name: title-2024i-love-kitkats">
  I Love KitKats
</a> 

Boom! It works!

So there you go. Way more than you ever wanted to know about the gotchas of a creating a unique view-transition-name.

And if you didn’t know about <custom-ident> in CSS, now you do!

Update 2024-01-13

Bramus reached out to let me know the cutting edge will let put id attributes on elements and then use auto (Safari-only at the time of this writing) or attr() which can parse a value into an custom-ident (Chrome 133+ at the time of this writing).

Here’s some example code from his Codepen:

<div class="cards">
  <div class="card" id="card-1">1</div>
  <div class="card" id="card-2">2</div>
  <div class="card" id="card-3">3</div>
</div>
<style>
.card[id] {
    view-transition-name: attr(id type(<custom-ident>), none);
    view-transition-class: card;
}
</style>

Pretty cool!


Reply via: Email :: Mastodon :: Bluesky

Tagged in: #css

Don’t Miss the Product for the Artifacts

View

Ever hear that idiom, “Don’t miss the forest for the trees”? The idea being, you miss the bigger picture because you’re focused on the minutia?

Feels like the tech equivalent is: Don’t miss the product for the artifacts.

Here’s Robin Rendle in a recent piece on design artifacts:

There’s a factory-like production of the modern design process which believes that the assets are more important than the product itself.

Nailed it 🎯

Too often we confuse 1) the artifact created in support of the deliverable, with 2) the deliverable itself.

For example, some designers are awesome at Figma. True wizards at the things they can make. But we’re not Figma designers. We’re app designers, web designers, product designers. Figma is just the tool that facilitates creating the thing we actually want to make. Yet we can spend so much time thinking “being good at Figma” is our purpose, when in fact it’s to use Figma to build something great for people!

Even “website” or “app” can be misleading. A web developer makes what they were hired for: a web site. An app developer makes an app.

But we’re not making websites or apps. We’re making tools and experiences that help people solve their problems.

In that sense, delivering a website is still just delivering an artifact.

And we’re not making artifacts.

We’re trying to help people make progress: solve their problems, find information, complete tasks.

Artifacts are always in service of progress, not progress itself.


Reply via: Email :: Mastodon :: Bluesky

Social Inflation

View

Imagine you’re on a social network and you start getting tons of followers.

You love it! Your follower count is going up!

Instead of a nobody with a couple hundred followers, you’ve bypassed the 1k+ mark and it keeps going!

You’re ecstatic! This is the “next step” you were aspiring to.

But then you start looking around.

The people you’re following with 1k+ followers are now at 10k+.

It hits you: everyone else’s follower count is going up too.

The network owners announce: “We’re having a bot problem at the moment. We’re aware of it and working on it.”

1k followers isn’t what it used to be. Now you need 10k. Or 100k.

Everyone’s follower count is being inflated.

Now when my kids ask, “Why can’t we just print more money?” I think I can analogize currency inflation to their social network following. Your follower count going up makes you feel good, but it’s merely the illusion of growth. What seems like increase is actually dilution, as relative value remains consistent and genuine value hasn’t changed.

Economic disclaimer: this content is for fun only and should not be considered professional economic theory. Please do not send me emails or messages beginning with: “Well, actually…”


Reply via: Email :: Mastodon :: Bluesky

Push Notifications Are Organizational Marshmallows

View

It’s a notifications’ world, we’re just living in it.

Companies can’t help but try and get your attention via email, text, or push notifications and drive you to their app.

Push notifications in particular are a powerful tool — and where there’s power, there’s abuse.

I’m sure you, dear reader, have had your notifications abused by overly-eager companies (here’s a screenshot example of what I’m talking about, courtesy of a Medium article).

Screenshot of two iPhone screens side by side, both chok full of promotional notifications.

Ben Thompson and John Gruber were talking about this on a recent episode of Dithering[1] and I loved Ben’s framing of push notification use as the marshmallow test for companies.

(What’s a marshmallow test? A famous experiment where they offered children a choice between one small but immediate reward, or two small but delayed rewards. A researcher would leave a child in a room with a single marshmallow for about 15 minutes then return. If they didn’t eat the marshmallow, the reward was two marshmallows. There are lots of videos re-enacting this test on YouTube for those interested.)

In this case, companies are the children and push notifications are the marshmallows. The engagement catnip push notifications produce is intoxicating. People know they can increase metrics any time they amp up notifications. It takes a lot of restraint — and often someone with organizational clout — to put a foot down and say, “We’re not going to abuse this because the long-term costs are too significant.”

Thus notification usage is a test of self-control, one too many companies fail. In fact if a company can exercise the restraint to not abuse push notifications, that’s a signal of how well-run they are! Here’s Ben:

Notification abuse is an example of why big company management is hard. What’s happening is someone [in the org] their KPI is “monthly active users” and they’re like, “I can turn this dial and get more monthly active users.” But they’re not the VP of “Good Taste” or “Don’t Piss Off Your Users” and so [exercising restraint] falls through the cracks. There’s probably some sort of metric you could do on company management dysfunction based on the number of abuse of notifications you get.

John chimed in with his own observation on how even Apple isn’t a role model in their own platform:

Apple is prone to abuse the little red badges you get in Settings because they’re the only ones who can do them. “What’s this red badge? Oh they’re offering me Apple Music, which I already have, for $5/month.” Because somebody was like “Oh my god, do you understand how many Apple Music subscriptions we sell when get that red badge in there?”

It’s a test of restraint and wisdom: can you forgo the short-term bump in metrics from (obtrusive) notifications in exchange for the long-term health, trust, and engagement of users?

Going forward, anytime I see my own notifications abused — besides getting angry and 1) turning off the app’s notifications, or 2) deleting the app — I’ll picture that notification as a yummy little marshmallow that somebody just couldn’t resist!


  1. Dithering is a subscription-based podcast, so I can’t link directly to an episode or transcript. For those interested, the episode was “Assisted Computing and Wearables” from December 10, 2024.

Reply via: Email :: Mastodon :: Bluesky

You Can Now Subscribe To My Blog via Email

View

I don’t think you should. I think you should use RSS.

But if you want posts delivered directly to your email, you can do that now.

However, disclaimer: I don’t know if I’ll keep this feature.

It costs me money.

And I don’t monetize my blog.

So sending you an email costs me monies every month.

And if that ever gets to feeling too expensive, it’ll be one of the first things I cut in my budget.

And fair warning: I’m cheap, lol.

How I Did It

Pretty simple: I setup an account with Buttondown which has an rss-to-email feature.

This is nice because I’m lazy. I want to put as little effort as possible into this.

I’m already publishing a feed on my blog, so I just point Buttondown at that feed, do a little configuration, and voila! Every time I publish a new post, Buttondown will pick it up and fire off emails.

Getting a little widget on to my site where folks can put in their email to sign up was a breeze. I was able to copy/paste some <form> code, style it a tiny bit, and be on my way. No <script> required!

(Honestly, the folks at Buttondown were super helpful and generous through this whole process. If you’re looking for an email platform, check them out. Also: this is not a sponsored post. I just genuinely had a good experience.)

Why I Did It

Out of curiosity.

Maybe around the beginning of 2026 I’ll write another post and let you know if anybody signed up.

I can’t keep track of how many people are signed up via RSS. And that’s fine.

However, I will know how many people are signed up via email, which is both cool and terrifying: cool because who doesn’t want to know they have readers? But terrifying because each person costs me money and my blog makes me $0/year.

That’s why I say, go ahead and subscribe via email but do it at your peril! One day, the emails may stop coming.

But they’ll always be there on the web and in your feed reader.


Reply via: Email :: Mastodon :: Bluesky

Tagged in: #myBlog

Podcast Notes: Vlad Prelovac on “The Talk Show”

View

Vlad Prelovac is the CEO of Kagi: a search engine you have to pay for.

He’s on episode 416 of John Gruber’s The Talk Show to discuss why he thinks we should be paying for search.

Hearing his point of view is compelling. I quite enjoyed the entire podcast. So much, in fact, that I took notes.

If any of the bullet points below catch your attention, you should go listen too.

  • We as a society haven’t been respectful of how the information we consume influences us.
    • They talk at length about the parallel between how much we’ve learned about how important it is to be mindful of what food you put into your body. In the 70’s nobody cared as much. Maybe people will look back at us and say, “Can you believe the information they used to put into their minds? Lol!”
  • The whole point of advertising is to influence your behavior — and we’ve wedged advertising between us and information.
  • People ask, “Why would you pay for search?” The right question is, “Why would you tolerate advertising in your search for information?” Can you imagine, for example, going to a library and having to watch an ad to find the call number for a book?
  • Google’s customer is not the user, it is the advertiser. And if the customer wants something, you give it to them. Why? Because you’re a public company, and public companies are optimized to generate a profit. And who gives you profit? Your customer!
  • If you put all of the smartest designers, engineers, product people, etc. in a room and asked them to design the best search experience for users, if you recommended what Google looks like today they would kick you out of the room.
  • Kagi downranks websites with lots of ads/trackers/etc. Why? They’ve found quantity of ad technology correlates to lower quality content (spam, affiliate crap, etc.)
    • In other words, the more ads and trackers there are, the more you can assume the purpose of that site is not to educate you (the user) but to monetize clicks to low quality, high quantity content.
  • Vlad Prelovac on AI: “I want AI to be a hammer in my hand, not a replacement for my mind.”
  • Why did Kagi make the Orion browser? It’s about creating an ecosystem of tools that are aligned from a philosophical perspective. At the end of the day, Safari is still an ad-driven browser (although indirectly) because it is monetized by Google’s default search engine deal (and other “traffic acquisition” deals, which is why you can’t change your default search engine to anything in Safari).
    • Even Safari and Firefox are not aligned philosophically with the idea of advertising-free information search.
  • Orion is built on Webkit, but differs from Safari because it ships with Webkit whereas Safari only supports whatever version ships with macOS. Therefore Orion can, for example, support the latest features and security patches of Webkit on older versions of macOS like Mojave.

Reply via: Email :: Mastodon :: Bluesky

Tagged in: #podcastNotes

Christmas Day

View

It’s Christmas circa 2004.

My teenage brothers, sisters, and I have all finished opening presents and we’re more than content to have absolutely nothing to do — it’s Christmas day after all!

But not Dad. He’s in the bathroom laying tile.

Again, this is Christmas day and Dad is on his hands and knees, in the bathroom, laying tile.

We all laugh at him. “Look at this guy, he can’t not do work on Christmas Day. He has a problem.”

Fast-forward two decades and, when our family gets together, we still get a good laugh poking fun at Dad — “Remember when he was laying tile in the bathroom on Christmas? Lol!”

And yet.

Here it is, Christmas day 2024. The kids are all asleep after a hectic day, and where do I find myself?

Working on my personal website.

I ask myself, “What am I doing? It’s the end of Christmas day and I’m working on my website? I have a problem!”

But then I think of Dad on Christmas.

Maybe we’re more similar than I thought.

What I saw as “work” I now see as finding solace in doing something he knew how to do well, even if others might laugh at him.

I used to laugh.

Now I think I just understand him better.


Reply via: Email :: Mastodon :: Bluesky