2025-04-17 03:00:00
Carson Gross has a post about vendoring which brought back memories of how I used to build websites in ye olden days, back in the dark times before npm.
“Vendoring” is where you copy dependency source files directly into your project (usually in a folder called /vendor
) and then link to them — all of this being a manual process. For example:
jquery.js
or reset.css
somewhere on the web (usually from the project’s respective website, in my case I always pulled jQuery from the big download button on jQuery.com and my CSS reset from Eric Meyer’s website)./vendor
, e.g. /vendor/[email protected]
<script src="/vendor/[email protected]">
And don’t get me started on copying your transitive dependencies (the dependencies of your dependencies). That gets complicated when you’re vendoring by hand!
Now-a-days package managers and bundlers automate all of this away: npm i
what you want, import x from 'pkg'
, and you’re on your way! It’s so easy (easy to get all that complexity).
But, as the HTMX article points out, a strength can also be a weakness. It’s not all net gain (emphasis mine):
Because dealing with large numbers of dependencies is difficult, vendoring encourages a culture of independence.
You get more of what you make easy, and if you make dependencies easy, you get more of them.
I like that — you get more of what you make easy. Therefore: be mindful of what you make easy!
As Carson points out, dependency management tools foster a culture of dependence — imagine that!
I know I keep lamenting Deno’s move away from HTTP imports by default, but I think this puts a finger on why I’m sad: it perpetuates the status quo, whereas a stance on aligning imports with how the browser works would not perpetuate this dependence on dependency resolution tooling. There’s no package manager or dependency resolution algorithm for the browser.
I was thinking about all of this the other day when I then came across this thread of thoughts from Dave Rupert on Mastodon. Dave says:
I prefer to use and make simpler, less complex solutions that intentionally do less. But everyone just wants the thing they have now but faster and crammed with more features (which are juxtaposed)
He continues with this lesson from his startup Luro:
One of my biggest takeaways from Luro is that it’s hard-to-impossible to sell a process change. People will bolt stuff onto their existing workflow (ecosystem) all day long, but it takes a religious conversion to change process.
Which really helped me put words to my feelings regarding HTTP imports in Deno:
i'm less sad about the technical nature of the feature, and more about what it represented as a potential “religious revival” in the area of dependency management in JS. package.json & dep management has become such an ecosystem unto itself that it seems only a Great Reawakening™️ will change it.
I don’t have a punchy point to end this article. It’s just me working through my feelings.
2025-04-15 03:00:00
I like to try different apps.
What makes trying different apps incredible is a layer of interoperability — standardized protocols, data formats, etc.
When I can bring my data from one app to another, that’s cool. Cool apps are interoperable. They work with my data, rather than own it.
For example, the other day I was itching to try a new RSS reader. I’ve used Reeder (Classic) for ages. But every once in a while I like to try something different.
This is super easy because lots of clients support syncing to Feedbin. It’s worth pointing out: Feedbin has their own app. But they don’t force you to use it. You’re free to use any RSS client you want that supports their service.
So all I have to do is download a new RSS client, login to Feedbin, and boom! An experience of my data in a totally different app from a totally different developer.
That’s amazing!
And you know how long it took? Seconds. No data export. No account migration.
Doing stuff with my blog is similar. If I want to try a different authoring experience, all my posts are just plain-text markdown files on disk. Any app that can operate on plain-text files is a potential new app to try.
No shade on them, but this why I personally don’t use apps like Bear. Don’t get me wrong, I love so much about Bear. But it wants to keep your data in its own own proprietary, note-keeping safe. You can’t just open your notes in Bear in another app. Importing is required. But there’s a big difference between apps that import (i.e. copy) your existing data and ones that interoperably work with it.
Email can also be this way. I use Gmail, which supports IMAP, so I can open my mail in lots of different clients — and believe me, I've tried a lot of email clients over the years.
This is why I don’t use un-standardized email features because I know I can’t take them with me.
It’s also why I haven’t tried email providers like HEY! Because they don't support open protocols so I can’t swap clients when I want.
My email is a dataset, and I want to be able to access it with any existing or future client. I don't want to be stuck with the same application for interfacing with my data forever (and have it tied to a company).
I love this way of digital life, where you can easily explore different experiences of your data. I wish it was relevant to other areas of my digital life. I wish I could:
In a world like this, applications would compete on an experience of my data, rather than on owning it.
The world’s a big place. The entire world doesn’t need one singular photo experience to Rule Them All.
Let’s have experiences that are as unique and varied as us.
2025-04-11 03:00:00
I learned a new word: ductile. Do you know it?
I’m particularly interested in its usage in a physics/engineering setting when talking about materials.
Here’s an answer on Quora to: “What is ductile?”
Ductility is the ability of a material to be permanently deformed without cracking.
In engineering we talk about elastic deformation as deformation which is reversed once the load is removed for example a spring, conversely plastic deformation isn’t reversed.
Ductility is the amount (usually expressed as a ratio) of plastic deformation that a material can undergo before it cracks or tears.
I read that and started thinking about the “ductility” of languages like HTML, CSS, and JS. Specifically: how much deformation can they undergo before breaking?
HTML, for example, is famously forgiving. It can be stretched, drawn out, or deformed in a variety of ways without breaking.
Take this short snippet of HTML:
<!doctype html>
<title>My site</title>
<p>Hello world!
<p>Nice to meet you
That is valid HTML. But it can also be “drawn out” for readability without losing any of its meaning. It’ll still render the same in the browser:
<!doctype html>
<html>
<head>
<title>My site</title>
</head>
<body>
<p>Hello world!</p>
<p>Nice to meet you.</p>
</body>
</html>
This capacity for the language to undergo a change in form without breaking is its “ductility”.
HTML has some pull before it breaks.
JS, on the other hand, doesn’t have the same kind of ductility. Forget a quotation mark and boom! Stretch it a little and it breaks.
console.log('works!');
// -> works!
console.log('works!);
// Uncaught SyntaxError: Invalid or unexpected token
I suppose some would say “this isn’t ductility, this is merely forgiving error-parsing”. Ok, sure.
Nevertheless, I’m writing here because I learned this new word that has very practical meaning in another discipline to talk about the ability of materials to be stretched and deformed without breaking.
I think we need more of that in software. More resiliency. More malleability. More ductility — prioritized in our materials (tools, languages, paradigms) so we can talk more about avoiding sudden failure.
2025-04-09 03:00:00
The other day I was working on something where I needed to use CSS to apply multiple background images to an element, e.g.
<div>
My content with background images.
</div>
<style>
div {
background-image:
url(image-one.jpg),
url(image-two.jpg);
background-position:
top right,
bottom left;
/* etc. */
}
</style>
As I was tweaking the appearance of these images, I found myself wanting to control the opacity of each one.
A voice in my head from circa 2012 chimed in, “Um, remember Jim, there is no background-opacity
rule. Can’t be done.” Then that voice started rattling off the alternatives:
opacity
but that will apply to the entire element, which you have text in, so that won’t work.opacity
. Or::before
& :after
), apply the background images to those, then use opacity
.Then modern me interrupted this old guy. “I haven’t reached for background-opacity
in a long time. Surely there’s a way to do this with more modern CSS?”
So I started searching and found this StackOverflow answer which says you can use background-color
in combination with background-blend-mode
to achieve a similar effect, e.g.
div {
/* Use some images */
background-image:
url(image-one.jpg),
url(image-two.jpg);
/* Turn down their 'opacity' by blending them into
the background color */
background-color: rgba(255,255,255,0.6);
background-blend-mode: lighten;
}
Worked like a charm! It probably won’t work in every scenario like a dedicated background-image-opacity
might, but for my particular use case at that moment in time it was perfect!
I love little moments like this where I reach to do something in CSS that was impossible back when I really cut my teeth on the language, and now there’s a one- or two-line modern solution!
[Sits back and gets existential for a moment.]
We all face moments like this where we have to balance leveraging hard-won expertise with seeking new knowledge and greater understanding, which requires giving up the lessons of previous experience in order to make room for incorporating new lessons of experiences.
It’s hard to give up the old, but it’s the only way to make room for the new — death of the old is birth of the new.
ShopTalk Show kindly pointed me at “Maybe there kinda is background-opacity?”. Looks like there’s a spec for a cross-fade()
function in CSS, though it’s only been implemented by Safari and the time of this writing.
Building off Chris’ CSS-Tricks article linked above, you could do something like this (I put the gif as a custom property, for readability’s sake, not sure you could actually do this):
div {
/* 1px transparent gif, base64 encoded */
--transparentImg: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7;
/* 1px transparent gif, base64 encoded */
background-image:
/* 1st image */
cross-fade(
/* my image */
url(image.jpg),
/* transparent image */
url(var(--transparentImg)),
/* desired 'background opacity' */
50%
),
/* 2nd image */
cross-fade(
url(image.jpg),
url(var(--transparentImg)),
20%
),
/* 3rd image, etc. */
;
}
Maybe once that ships 4real, we really will have a proxy for background-opacity
!
2025-04-06 03:00:00
I saw these going around, but didn’t think I’d ever see myself get tagged — then Eric assuaged my FOMO.
As I’ve done elsewhere talking about how I blog, I’m gonna try and impose a character limit to my answers (~240). I’m not sure if that makes my job as the writer easier or harder, but it should make your job as the reader easier.
I think I started because everything I learned about building on the web came from reading other people’s blogs online, so I wanted to be a “web person” like them.
At the time of this writing (April 2025):
I’ve arrived at this setup less from a combination of choice and evolution. As me and my writing evolve, my process and tools evolve too.
Blogspot, way back in the day. It’s no longer up, which is probably for the best. I was posting stuff I made from following “make this in Photoshop” tutorials.
Or I’d practice trying to visually express silly puns.
Or I’d make visual mashups of culture at the time.
For a detailed history of changes on how I blog, I blog about blogging under #myBlog and I blog about microblogging under #myNotes. Read any of those posts for insights into my ever-changing process.
When I read other people’s thoughts.
I’m a simmerer. Rarely does a post go from thought to published in one sitting. For example, here’s a screenshot of my current simmering drafts (note my sophisticated editorial process of assigning each draft a letter prefix for sorting based on my appetite for finishing it).
Stuff I make.
Or stuff others make.
Or thoughts I think while reading thoughts others think.
I have a tags page that tries to capture what I write categorically — for example, I blog notes from books I read, and podcasts I listen to — but TBH it’s not the greatest taxonomy of my writing.
Reductively: I blog about web design and development.
Whoa, that question got me more introspective than I expected. Gonna move on before this becomes an existential crisis.
I used to highlight some of my favs on my home page, but I stopped. Choosing favorites is hard.
My blog posts are like my kids: I love them all equally, lol.
I suppose my favorite blog post is the one I’ll publish next.
Will I redesign? Lol, the question is: when will you redesign?
Sorry if I mention someone who’s already been tagged:
Sorry, I’m not gonna ping any of these folks. If they read my blog, they’ll see their names. Otherwise, dear reader, consider it a suggestion to go subscribe to their stuff.
2025-04-03 03:00:00
Jack Johnson is on Rick Rubin’s podcast Tetragrammaton talking about music, film making, creativity, and surfing.
At one point (~24:30) Johnson talks about his love for surfing and the beautiful flow state it puts him in:
Sometimes I’ll see a friend riding a wave while I’m paddling out, and the thing I’ll see them do just seems like magic...I’ll think, “How in the world did they just do that?” And then on your next ride you’re doing the exact same thing without thinking but it’s all muscle memory and it’s all in this flow that you get into. That’s a really beautiful state to get into, to do something that feels like a magic trick, like something you shouldn’t be able to do, but all of the sudden you’re doing it.
I’m not a surfer, and I can’t do effortlessly cool. But I know what a flow state feels like.
Johnson’s description reminds me of that feeling when you get a little time on a personal project — riding the wave of working on your personal website.
You open your laptop. You start paddling out. Maybe you see an internet friend who was doing something cool and you want to try it but you have no idea if you’ll be able to do it as well as they did.
And before you know it, you’re in that flow state where muscle memory takes over and you’re doing stuff without even consciously thinking about it — stuff that others might look at and perceive as magic (cough anything on the command line cough) but it’s not magic to you. Intuition and experience just take over while you ride the wave.
Ok, I’m a nerd. But I don’t care. It’s a great feeling, regardless of whether it’s playing an instrument, or surfing, or programming. That feeling of sinking into a craft you’ve worked at your whole life that you don’t have to think about anymore.