Latest Posts (20 found)
Jim Nielsen 6 days ago

Fewer Computers, Fewer Problems: Going Local With Builds & Deployments

Me, in 2025, on Mastodon : I love tools like Netlify and deploying my small personal sites with But i'm not gonna lie, 2025 might be the year I go back to just doing builds locally and pushing the deploys from my computer. I'm sick of devops'ing stupid stuff because builds work on my machine and I have to spend that extra bit of time to ensure they also work on remote linux computers. Not sure I need the infrastructure of giant teams working together for making a small personal website. It’s 2026 now, but I finally took my first steps towards this. One of the ideas I really love around the “local-first” movement is this notion that everything canonical is done locally, then remote “sync” is an enhancement. For my personal website, I want builds and deployments to work that way. All data, build tooling, deployment, etc., happens first and foremost on my machine. From there, having another server somewhere else do it is purely a “progressive enhancement”. If it were to fail, fine. I can resort back to doing it locally very easily because all the tooling is optimized for local build and deployment first (rather than being dependent on fixing some remote server to get builds and deployments working). It’s amazing how many of my problems come from the struggle to get one thing to work identically across multiple computers . I want to explore a solution that removes the cause of my problem, rather than trying to stabilize it with more time and code. “The first rule of distributed computing is don’t distribute your computing unless you absolutely have to” — especially if you’re just building personal websites. So I un-did stuff I previously did (that’r right, my current predicament is self-inflicted — imagine that). My notes site used to work like this : It worked, but sporadically. Sometimes it would fail, then start working again, all without me changing anything. And when it did work, it often would take a long time — like five, six minutes to run a build/deployment. I never could figure out the issue. Some combination of Netlify’s servers (which I don’t control and don’t have full visibility into) talking to Dropbox’s servers (which I also don’t control and don’t have full visibility into). I got sick of trying to make a simple (but distributed) build process work across multiple computers when 99% of the time, I really only need it to work on one computer. So I turned off builds in Netlify, and made it so my primary, local computer does all the work. Here are the trade-offs: The change was pretty simple. First, I turned off builds in Netlify. Now when I Netlify does nothing. Next, I changed my build process to stop pulling markdown notes from the Dropbox API and instead pull them from a local folder on my computer. Simple, fast. And lastly, as a measure to protect myself from myself, I cloned the codebase for my notes to a second location on my computer. This way I have a “working copy” version of my site where I do local development, and I have a clean “production copy” of my site which is where I build/deploy from. This helps ensure I don’t accidentally build and deploy my “working copy” which I often leave in a weird, half-finished state. In my I have a command that looks like this: That’s what I run from my “clean” copy. It pulls down any new changes, makes sure I have the latest deps, builds the site, then lets Netlify’s CLI deploy it. As extra credit, I created a macOS shortcut So I can do , type “Deploy notes.jim-nielsen.com” to trigger a build, then watch the little shortcut run to completion in my Mac’s menubar. I’ve been living with this setup for a few weeks now and it has worked beautifully. Best part is: I’ve never had to open up Netlify’s website to check the status of a build or troubleshoot a deployment. That’s an enhancement I can have later — if I want to. Reply via: Email · Mastodon · Bluesky Content lives in Dropbox Code is on GitHub Netlify’s servers pull both, then run a build and deploy the site What I lose : I can no longer make edits to notes, then build/deploy the site from my phone or tablet. What I gain : I don’t have to troubleshoot build issues on machines I don’t own or control. Now, if it “works on my machine”, it works period.

0 views
Jim Nielsen 1 weeks ago

Prototyping with LLMs

Did you know that Jesus gave advice about prototyping with an LLM? Here’s Luke 14:28-30: Suppose one of you wants to build a tower. Won’t you first sit down and estimate the cost to see if you have enough money to complete it? For if you lay the foundation and are not able to finish it, everyone who sees it will ridicule you, saying, ‘This person began to build and wasn’t able to finish.’ That pretty much sums me up when I try to vibe a prototype . Don’t get me wrong, I’m a big advocate of prototyping . And LLMs make prototyping really easy and interesting. And because it’s so easy, there’s a huge temptation to jump straight to prototyping. But what I’ve been finding in my own behavior is that I’ll be mid-prototyping with the LLM and asking myself, “What am I even trying to do here?” And the thought I have is: “I’d be in a much more productive place right now if I’d put a tiny bit more thought upfront into what I am actually trying to build.” Instead, I just jumped right in, chasing a fuzzy feeling or idea only to end up in a place where I’m more confused about what I set out to do than when I started. Don’t get me wrong, that’s fine. That’s part of prototyping. It’s inherent to the design process to get more confused before you find clarity. But there’s an alternative to LLM prototyping that’s often faster and cheaper: sketching. I’ve found many times that if I start an idea by sketching it out, do you know where I end up? At a place where I say, “Actually, I don’t want to build this.” And in that case, all I have to do is take my sketch and throw it away. It didn’t cost me any tokens or compute to figure that out. Talk about efficiency! I suppose what I’m saying here is: it’s good to think further ahead than the tracks you’re laying out immediately in front of you. Sketching is a great way to do that. (Thanks to Facundo for prompting these thoughts out of me.) Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 1 weeks ago

I Tried Vibing an RSS Reader and My Dreams Did Not Come True

Simon Willison wrote about how he vibe coded his dream presentation app for macOS . I also took a stab at vibe coding my dream app: an RSS reader. To clarify: Reeder is my dream RSS app and it already exists, so I guess you could say my dreams have already come true? But I’ve kind of always wanted to try an app where my RSS feed is just a list of unread articles and clicking any one opens it in the format in which it was published (e.g. the original website). So I took a stab at it. (Note: the backend portion of this was already solved, as I simply connected to my Feedbin account via the API .) First I tried a macOS app because I never would’ve tried a macOS app before. Xcode, Swift, a Developer Account? All completely outside my wheelhouse. But AI helped be get past that hurdle of going from nothing to something . It was fun to browse articles and see them in situ . A lot of folks have really great personal websites so it’s fun to see their published articles in that format. This was pretty much pure vibes. I didn’t really look at the code at all because I knew I wouldn’t understand any of it. I got it working the first night I sat down and tried it. It was pretty crappy but it worked. From there I iterated. I’d use it for a day, fix things that were off, keep using it, etc. Eventually I got to the point where I thought: I’m picky about software, so the bar for my dreams is high. But I’m also lazy, so my patience is quite low. The intersection of: the LLM failing over and over + my inability to troubleshoot any of it + not wanting to learn = a bad combination for persevering through debugging. Which made me say: “Screw it, I’ll build it as a website!” But websites don’t really work for this kind of app because of CORS. I can’t just stick an article’s URL in an and preview it because certain sites have cross site headers that don’t allow it to display under another domain. But that didn’t stop me. I tried building the idea anyway as just a list view. I could install this as a web app on my Mac and I'd get a simple list view: Anytime I clicked on a link, it would open in my default browser. Actually not a bad experience. It worked pretty decent on my phone too. Once I visited my preview deploy, I could "isntall" it to my home screen and then when I opened it, I'd have my latest unread articles. Clicking on any of them would open a webview that I could easily dismiss and get back to my list. Not too bad. But not what I wanted, especially on desktop. It seemed like the only option to 1) get exactly what I wanted, and 2) distribute it — all in a way that I could understand in case something went wrong or I had to overcome an obstacle — was to make a native app. At this point, I was thinking: “I’m too tired to learn Apple development right now, and I’ve worked for a long time on the web, so I may as well leverage the skills that I got.” So I vibed an Electron app because Electron will let me get around the cross site request issues of a website. This was my very first Electron app and, again, the LLM helped me go from nothing to something quite quickly (but this time I could understand my something way better). The idea was the same: unread articles on the left, a preview of any selected articles on the right. Here’s a screenshot: It’s fine. Not really what I want. But it’s a starting point. Is it better than Reeder? Hell no. Is it my wildest dreams realized? Also no. But it’s a prototype of an idea I’ve wanted to explore. I”m not sure I’ll go any further on it. It’s hacky enough that I can grasp a vision for what it could be. The question is: do I actually want this? Is this experience something I want in the long run? I think it could be. But I have to figure out exactly how I want to build it as a complementary experience to my preferred way of going through my RSS feed. Which won't be your preference. Which is why I'm not sharing it. So what’s my takeaway from all this? I don’t know. That’s why I’m typing this all out in a blog post. Vibe coding is kinda cool. It lets you go from “blank slate” to “something” way faster and easier than before. But you have to be mindful of what you make easy . You know what else is easy? Fast food. But I don’t want that all the time. In fact, vibe coding kinda left me with that feeling I get after indulging in social media, like “What just happened? Two hours have passed and what did I even spend my time doing? Just mindlessly chasing novelty?” It’s fun and easy to mindlessly chasing your whims. But part of me thinks the next best step for this is to sit and think about what I actually want, rather than just yeeting the next prompt out. I’ve quipped before that our new timelines are something like: The making from nothing isn't as hard anymore. But everything after that still is. Understanding it. Making it good. Distributing it. Supporting it. Maintaining it. All that stuff. When you know absolutely nothing about those — like I did with macOS development — things are still hard. After all this time vibing, instead of feeling closer to my dream, I actually kinda feel further from it. Like the LLM helped close the gap in understanding what it would actually take for me to realize my dreams. Which made me really appreciate the folks who have poured a lot of time and thought and effort into building RSS readers I use on a day-to-day basis. Thank you makers of Feedbin & Reeder & others through the years. I’ll gladly pay you $$$ for your thought and care. In the meantime, I may or may not be over here slowly iterating on my own supplemental RSS experience. In fact, I might’ve just found the name: RxSSuplement. Reply via: Email · Mastodon · Bluesky Ok, I could use this on my personal computer. I don’t know that I’ll be able to iterate on this much more because its getting more complicated and failing more and more with each ask ( I was just trying to move some stupid buttons around in the UI and the AI was like, “Nah bro, I can’t.”) I have no idea how I’d share this with someone. I don’t think I’d be comfortable sharing this with someone (even though I think I did things like security right by putting credentials in the built-in keychain, etc.) I guess this is where the road stops. Nothing -> Something? 1hr. Something -> Something Good ? 1 year.

0 views
Jim Nielsen 1 weeks ago

The Blandness of Systematic Rules vs. The Delight of Localized Sensitivity

Marcin Wichary brings attention to this lovely dialog in ClarisWorks from 1997: this breaks the rule of button copy being fully comprehensible without having to read the surrounding strings first, perhaps most well-known as the “avoid «click here»” rule. Never Register/​Register Later/​Register Now would solve that problem, but wouldn’t look so neat. This got me thinking about how you judge when an interface should bend to fit systematic rules vs. exert itself and its peculiarities and context? The trade-off Marcin points out is real: "Never Register / Register Later / Register Now" is fully self-describing and avoids the «click here» rule. However, it kills the elegant terseness that makes that dialog so delightful. “Now / Later / Never” is three words with no filler and a perfect parallel structure. It feels like one of those cases where the rule is sound as a guideline but a thoughtful design supersedes the baseline value provided by the rule. Rules, in a way, are useful structures when you don’t want to think more. But more thinking can result in delightful exceptions that prove better than the outcome any rule can provide. I suppose it really is trade-offs everywhere : As software moves towards “scale”, I can’t help but think that systematic rules swallow all decision making because localized exceptions become points of friction — “We can’t require an experienced human give thought and care to the design of every single dialog box.” What scale wants is automated decision making that doesn’t require skill or expertise because those things, by definition, don’t scale. Then again, when you manufacture upon inhuman lines how can you expect humane outcomes? Reply via: Email · Mastodon · Bluesky When you choose to make decisions on a case-by-case basis, the result can be highly-tailored to the specific context of the problem at hand. However, within a larger system, you can start to lose consistency and coherence across similar UX decision points. When you choose to make system rules override the sensitivities of individual cases, you can lose the magic and delight of finding waypoints tailored exclusively to their peculiarities.

0 views
Jim Nielsen 2 weeks ago

Continuous, Continuous, Continuous

Jason Gorman writes about the word “continuous” and its place in making software. We think of making software in stages (and we often assign roles to ourselves and other people based on these stages): the design phase, the coding phase, the testing phase, the integration phase, the release phase, and so on. However this approach to building and distributing software isn’t necessarily well-suited to an age where everything moves at breakneck speed and changes constantly. The moment we start writing code, we see how the design needs to change. The moment we start testing, we see how the code needs to change. The moment we integrate our changes, we see how ours or other people’s code needs to change. The moment we release working software into the world, we learn how the software needs to change. Making software is a continuous cycle of these interconnected stages: designing, coding, testing, integrating, releasing. But the lines between these stages are very blurry, and therefore the responsibilities of people on our teams will be too. The question is: are our cycles for these stages — and the collaborative work of the people involved in them — measured in hours or weeks? Do we complete each of these stages multiple times a day, or once every few weeks? if we work backwards from the goal of having working software that can be shipped at any time, we inevitably arrive at the need for continuous integration, and that doesn’t work without continuous testing, and that doesn’t work if we try to design and write all the code before we do any testing. Instead, we work in micro feedback loops, progressing one small step at a time, gathering feedback throughout so we can iterate towards a good result. Feedback on the process through the process must be evolutionary. You can’t save it all up for a post-mortem or a 1-on-1. It has to happen at the moment, evolving our understanding one piece of feedback at a time (see: Gall’s law , a complex system evolves from a simpler one). if code craft could be crystallised in one word, that word would be “continuous”. Your advantage in software will be your ability to evolve and change as your customers expectations evolve and change (because the world evolves and changes), which means you must be prepared to respond to, address, and deliver on changes in expectations at any given moment in time. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 3 weeks ago

Code as a Tool of Process

Steve Krouse wrote a piece that has me nodding along: Programming, like writing, is an activity, where one iteratively sharpens what they're doing as they do it. (You wouldn't believe how many drafts I've written of this essay.) There’s an incredible amount of learning and improvement, i.e. sharpening , to be had through the process of iteratively building something. As you bring each aspect of a feature into reality, it consistently confronts you with questions like, “But how will this here work?” And “Did you think of that there ?” If you jump over the process of iteratively building each part and just ask AI to generate a solution, you miss the opportunity of understanding the intricacies of each part which amounts to the summation of the whole. I think there are a lot of details that never bubble to the surface when you generate code from English as it’s simply not precise enough for computers . Writing code is a process that confronts you with questions about the details. If you gloss over the details, things are going to work unexpectedly and users will discover the ambiguity in your thinking rather than you (see also: “bugs”). Writing code is a tool of process. As you go, it sharpens your thinking and helps you discover and then formulate the correctness of your program. If you stop writing code and start generating it, you lose a process which helped sharpen and refine your thinking. That’s why code generation can seem so fast: it allows you to skip over the slow, painful process of sharpening without making it obvious what you’re losing along the way. You can’t understand the trade-offs you’re making, if you’re not explicitly confronted with making them. To help me try to explain my thinking (and understand it myself), allow me a metaphor. Imagine mining for gold. There are gold nuggets in the hills. And we used to discover them by using pick axes and shovels. Then dynamite came along. Now we just blow the hillside away. Nuggets are fragmented into smaller pieces. Quite frankly, we didn’t even know if there were big nuggets or small flecks in the hillside because we just blasted everything before we found anything. After blasting, we take the dirt and process it until all we have left is a bunch of gold — most likely in the form of dust. So we turn to people, our users, and say “Here’s your gold dust!” But what if they don’t want dust? What if they want nuggets? Our tools and their processes don’t allow us to find and discover that anymore. Dynamite is the wrong tool for that kind of work. It’s great in other contexts. If you just want a bunch of dust and you’re gonna melt it all down, maybe that works fine. But for finding intact, golden nuggets? Probably not. It’s not just the tool that helps you, it’s the process the tool requires. Picks and shovels facilitate a certain kind of process. Dynamite another. Code generation is an incredible tool, but it comes with a process too. Does that process help or hurt you achieve your goals? It’s important to be cognizant of the trade-offs we make as we choose tools and their corresponding processes for working because it’s trade-offs all the way down. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 3 weeks ago

Re: People Are Not Friction

Dave Rupert puts words to the feeling in the air: the unspoken promise of AI is that you can automate away all the tasks and people who stand in your way. Sometimes I feel like there’s a palpable tension in the air as if we’re waiting to see whether AI will replace designers or engineers first. Designers empowered by AI might feel those pesky nay-saying, opinionated engineers aren’t needed anymore. Engineers empowered with AI might feel like AI creates designs that are good enough for most situations. Backend engineers feel like frontend engineering is a solved problem. Frontend engineers know scaffolding a CRUD app or an entire backend API is simple fodder for the agent. Meanwhile, management cackles in their leather chairs saying “Let them fight…” It reminds me of something Paul Ford said : The most brutal fact of life is that the discipline you love and care for is utterly irrelevant without the other disciplines that you tend to despise. Ah yes, that age-old mindset where you believe your discipline is the only one that really matters. Paradoxically, the promise of AI to every discipline is that it will help bypass the tedious-but-barely-necessary tasks (and people) of the other pesky disciplines. AI whispers in our ears: “everyone else’s job is easy except yours” . But people matter. They always have. Interacting with each other is the whole point! I look forward to a future where, hopefully, decision makers realize: “Shit! The best products come from teams of people across various disciplines who know how to work with each other, instead of trying to obviate each other.” Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 4 weeks ago

You Might Debate It — If You Could See It

Imagine I’m the design leader at your org and I present the following guidelines I want us to adopt as a team for doing design work: How do you think that conversation would go? I can easily imagine a spirited debate where some folks disagree with any or all of my points, arguing that they should be struck as guidelines from our collective ethos of craft. Perhaps some are boring, or too opinionated, or too reliant on trends. There are lots of valid, defensible reasons. I can easily see this discussion being an exercise in frustration, where we debate for hours and get nowhere — “I suppose we can all agree to disagree”. And yet — thanks to a link to Codex’s front-end tool guidelines in Simon Willison’s article about how coding agents work — I see that these are exactly the kind of guidelines that are tucked away inside an LLM that’s generating output for many teams. It’s like a Trojan Horse of craft: guidelines you might never agree to explicitly are guiding LLM outputs, which means you are agreeing to them implicitly. It’s a good reminder about the opacity of the instructions baked in to generative tools. We would debate an open set of guidelines for hours, but if there’re opaquely baked in to a tool without our knowledge does anybody even care? When you offload your thinking, you might be on-loading someone else’s you’d never agree to — personally or collectively. Reply via: Email · Mastodon · Bluesky Typography: Use expressive, purposeful fonts and avoid default stacks (Inter, Roboto, Arial, system). Motion: Use a few meaningful animations (page-load, staggered reveals) instead of generic micro-motions. Background: Don't rely on flat, single-color backgrounds; use gradients, shapes, or subtle patterns to build atmosphere. Overall: Avoid boilerplate layouts and interchangeable UI patterns. Vary themes, type families, and visual languages.

1 views
Jim Nielsen 1 months ago

Food, Software, and Trade-offs

Greg Knauss has my attention with a food analogy in his article “Lose Myself” : A Ding Dong from a factory is not the same thing as a gâteau au chocolat et crème chantilly from a baker which is not the same thing as cramming chunks of chocolate and scoops of whipped cream directly into your mouth [...] The level of care, of personalization, of intimacy — both given and taken — changes its nature. I love food and analogies, so let’s continue down that path. Take these three items for example: Which one of these is the best? I’m sure an immediate reaction comes to mind. But wait, what do we mean by “best”? Best in terms of convenience? Best in terms of flavor? Best in terms of healthiness? Best in terms of how ingredients were sourced and processed? Best in terms of price? Best in terms of… It’s all trade-offs. I don’t think we talk about trade-offs enough, but they’re there. Always there. We might not know what they are yet if we’re on the frontier, but we’re always trading one thing for another. “McDonald’s cherry pie is the best cherry pie ever.” That’s a hot take for social media. We wouldn’t accept that as a rational statement applicable to everyone everywhere all the time. People have preferences, products have strengths and weaknesses, that’s the name of the game. “All software in a year will be written by robots.” Also a hot take, not a serious statement. It’s impossible to apply such a generic prediction to everything everywhere all of the time. But also: “software” hand-written by humans is not the same as “software” generated by a machine. To presume the two are equivalent is a mistake. There are trade-offs. Everything has trade-offs, a set of attributes optimized and balanced towards a particular outcome. You get X, but you lose Y. Life is full of trade-offs. Anyone who says otherwise is trying to sell you something. Reply via: Email · Mastodon · Bluesky A McDonald’s cherry pie A Marie Calendar’s cherry pie A homemade Jim Nielsen cherry pie

0 views
Jim Nielsen 1 months ago

w0rdz aRe 1mpoRtAnt

The other day I was looking at the team billing section of an AI product. They had a widget labeled “Usage leaderboard”. For whatever reason, that phrase at that moment made me pause and reflect — and led me here to this post. It’s an interesting label. You could argue the widget doesn’t even need a label. You can look at it and understood at a glance: “This is a list of people sorted by their AI usage, greatest to least.” But it has that label. It could have a different label. Imagine, for a moment, different names for this widget — each one conjuring different meanings for its purpose and use: Usage leaderboard implies more usage is better. Who doesn’t want to be at or near the top of a leaderboard at work? If you’re not on the leaderboard, what’s that mean for your standing in the company? You better get to work! Calling it a leaderboard imbues the idea of usage with meaning — more is better! All of that accomplished solely via a name. Usage dashboard seems more neutral. It’s not implying that usage is good or bad. It just is , and this is where you can track it. Usage wall of shame sounds terrible! Who wants to be on the wall of shame? That would incentivize people to not have lots of usage. Again, all through the name of the thing! It’s worth noting that individuals and companies are incentivized to choose words designed to shape our thinking and behavior in their interest. The company who makes the widget from my example is incentivized to call this a “Usage leaderboard” because more usage by us means more $$$ for them. I’m not saying that is why they chose that name. There may not be any malicious or greedy intent behind the naming. Jim’s law is a variation on Hanlon’s razor : Don’t attribute to intent that which can be explained by thoughtlessness. I do find it fascinating how little thought we often give to the words we use when they can have a such a profound impact on shaping our own psychology, perception, and behavior. I mean, how many “word experts” are on your internal teams? Personally, I know I could do better at choosing my words more thoughtfully. Reply via: Email · Mastodon · Bluesky “Usage leaderboard” “Usage dashboard” “Usage wall of shame”

0 views
Jim Nielsen 1 months ago

Book Notes: “Blood In The Machine” by Brian Merchant

For my future self, these are a few of my notes from this book . A take from one historian on the Luddite movement: If workmen disliked certain machines, it was because of the use that they were being put, not because they were machines or because they were new Can’t help but think of AI. I don’t worry about AI becoming AGI and subjugating humanity. I worry that it’s put to use consolidating power and wealth into the hands of a few at the expense of many. The Luddites smashed things: to destroy, specifically, ‘machinery hurtful to commonality’ — machinery that tore at the social fabric, unduly benefitting a singly party at the expense of the rest of the community. Those who deploy automation can use it to erode the leverage and earning power of others, to capture for themselves the former earnings of a worker. It’s no wonder CEOs are all about their employees using AI: it gives them the leverage. Respect for the natural rights of humans has been displaced in favor of the unnatural rights of property. Richard Arkwright was an entrepreneur in England. His “innovation” wasn’t the technology for spinning yarn he invented (“pieced together from the inventions of others” would be a better wording), but rather the system of modern factory work he created for putting his machines to work. Arkwright’s “main difficulty”, according to early business theorist Andrew Ure, did not “lie so much in the invention of a proper mechanism for drawing out and twisting cotton into a continuous thread, as in […] training human beings to renounce their desultory habits of work and to identify themselves with the unvarying regularity of the complex automaton.” This was his legacy […] for all his innovation, the secret sauce in his groundbreaking success was labor exploitation. Not much has changed (which is kind of the point of the book). The model for success is: As the author says: [Impose discipline and rigidity on workers, and adapt] them to the rhythms of the machine and the dictates of capital — not the other way around. Reply via: Email · Mastodon · Bluesky Look at the technologies of the day Recognize what works and could turn a profit Steal the ideas and put them into action with unmatched aggression and shamelessness

0 views
Jim Nielsen 1 months ago

Computers and the Internet: A Two-Edged Sword

Dave Rupert articulated something in “Priority of idle hands” that’s been growing in my subconscious for years: I had a small, intrusive realization the other day that computers and the internet are probably bad for me […] This is hard to accept because a lot of my work, hobbies, education, entertainment, news, communities, and curiosities are all on the internet. I love the internet, it’s a big part of who I am today Hard same. I love computers and the internet. Always have. I feel lucky to have grown up in the late 90’s / early 00’s where I was exposed to the fascination, excitement, and imagination of PCs, the internet, and then “mobile”. What a time to make websites! Simultaneously, I’ve seen how computers and the internet are a two-edged sword for me: I’ve cut out many great opportunities with them, but I’ve also cut myself a lot (and continue to). Per Dave’s comments, I have this feeling somewhere inside of me that the internet and computers don’t necessarily align in support my own, personal perspective of what a life well lived is for me . My excitement and draw to them also often leave me with a feeling of “I took that too far.” I still haven’t figured out a completely healthy balance (but I’m also doing ok). Dave comes up with a priority of constituencies to deal with his own realization. I like his. Might steal it. But I also think I need to adapt it, make it my own — but I don’t know what that looks like yet. To be honest, I don't think I was ready to confront any of this but reading Dave’s blog forced it out of my subconscious and into the open, so now I gotta deal. Thanks Dave. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 1 months ago

Making Icon Sets Easy With Web Origami

Over the years, I’ve used different icon sets on my blog. Right now I use Heroicons . The recommended way to use them is to copy/paste the source from the website directly into your HTML. It’s a pretty straightforward process: If you’re using React or Vue, there are also npm packages you can install so you can import the icons as components. But I’m not using either of those frameworks, so I need the raw SVGs and there’s no for those so I have to manually grab the ones I want. In the past, my approach has been to copy the SVGs into individual files in my project, like: Then I have a “component” for reading those icons from disk which I use in my template files to inline the SVGs in my HTML. For example: It’s fine. It works. It’s a lot of node boilerplate to read files from disk. But changing icons is a bit of a pain. I have to find new SVGs, overwrite my existing ones, re-commit them to source control, etc. I suppose it would be nice if I could just and get the raw SVGs installed into my folder and then I could read those. But that has its own set of trade-offs. For example: So the project’s npm packages don’t provide the raw SVGs. The website does, but I want a more programatic way to easily grab the icons I want. How can I do this? I’m using Web Origami for my blog which makes it easy to map icons I use in my templates to Heroicons hosted on Github. It doesn’t require an or a . Here’s an snippet of my file: As you can see, I name my icon (e.g. ) and then I point it to the SVG as hosted on Github via the Heroicons repo. Origami takes care of fetching the icons over the network and caching them in-memory. Beautiful, isn’t it? It kind of reminds me of import maps where you can map a bare module specifier to a URL (and Deno’s semi-abandoned HTTP imports which were beautiful in their own right). Origami makes file paths first-class citizens of the language — even “remote” file paths — so it’s very simple to create a single file that maps your icon names in a codebase to someone else’s icon names from a set, whether those are being installed on disk via npm or fetched over the internet. To simplify my example earlier, I can have a file like : Then I can reference those icons in my templates like this: Easy-peasy! And when I want to change icons, I simply update the entries in to point somewhere else — at a remote or local path. And if you really want to go the extra mile, you can use Origami’s caching feature: Rather than just caching the files in memory, this will cache them to a local folder like this: Which is really cool because now when I run my site locally I have a folder of SVG files cached locally that I can look at and explore (useful for debugging, etc.) This makes vendoring really easy if I want to put these in my project under source control. Just run the file once and boom, they’re on disk! There’s something really appealing to me about this. I think it’s because it feels very “webby” — akin to the same reasons I liked HTTP imports in Deno. You declare your dependencies with URLs, then they’re fetched over the network and become available to the rest of your code. No package manager middleman introducing extra complexity like versioning, transitive dependencies, install bloat, etc. What’s cool about Origami is that handling icons like this isn’t a “feature” of the language. It’s an outcome of the expressiveness of the language. In some frameworks, this kind of problem would require a special feature (that’s why you have special npm packages for implementations of Heroicons in frameworks like react and vue). But because of the way Origami is crafted as a tool, it sort of pushes you towards crafting solutions in the same manner as you would with web-based technologies (HTML/CSS/JS). It helps you speak “web platform” rather than some other abstraction on top of it. I like that. Reply via: Email · Mastodon · Bluesky Go to the website Search for the icon you want Click to “Copy SVG” Go back to your IDE and paste it Names are different between icon packs, so when you switch, names don’t match. For example, an icon might be named in one pack and in another. So changing sets requires going through all your templates and updating references. Icon packs are often quite large and you only need a subset. might install hundreds or even thousands of icons I don’t need.

0 views
Jim Nielsen 1 months ago

How AI Labs Proliferate

SITUATION: there are 14 competing AI labs. “We can’t trust any of these people with super-intelligence. We need to build it ourselves to ensure it’s done right!" SOON: there are 15 competing AI labs. (See: xkcd on standards .) The irony: “we’re the responsible ones” is each lab’s founding mythology as they spin out of each other. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 1 months ago

A Few Rambling Observations on Care

In this new AI world, “taste” is the thing everyone claims is the new supreme skill. But I think “care” is the one I want to see in the products I buy. Can you measure care? Does scale drive out care? If a product conversation is reduced to being arbitrated exclusively by numbers, is care lost? The more I think about it, care seems antithetical to the reductive nature of quantification — “one death is a tragedy, one million is a statistic”. Care considers useful, constructive systematic forces — rules, processes, etc. — but does not take them as law. Individual context and sensitivity are the primary considerations. That’s why the professional answer to so many questions is: “it depends”. “This is the law for everyone, everywhere, always” is not a system I want to live in. Businesses exist to make money, so one would assume a business will always act in a way that maximizes the amount of money that can be made. That’s where numbers take you. They let you measure who is gaining or losing the most quantifiable amount in any given transaction. But there’s an unmeasurable, unquantifiable principle lurking behind all those numbers: it can be good for business to leave money on the table. Why? Because you care. You are willing to provision room for something beyond just a quantity, a number, a dollar amount. I don’t think numbers alone can bring you to care . I mean, how silly is it to say: “How much care did you put into the product this week?” “Put me down for a 8 out of 10 this week.” Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 2 months ago

Unresponsive Buttons on My Fastest Hardware Ever

This is one of those small things that drives me nuts. Why? I don’t know. I think it has something to do with the fact that I have a computer that is faster than any computer I’ve ever used in my entire life — and yet, clicking on buttons results in slight but perceptible delays. Let me explain. Imagine a button that looks like this: For SPA apps, when the user clicks that button it takes a split second (even on a fast connection) for anything to happen because: When clicking on that button, even on a fast connection, my brain glitches for a second, my thought process going something like: Granted those thoughts occur in my brain in under a second, but I hate that pause of indetermination. I clicked, I want (perceptibly) instant feedback. If something is happening, tell me! For SPA apps, you could put some state in there, like: This would provide more immediate feedback. But it also raises a whole set of other questions: Oh boy, this is getting complicated isn’t it? This is why, I assume, lots of apps just don’t deal with it. They accept there will be a slight delay in the responsiveness of the UI (and that it might error, but the user can just click again) and justify that it’s really not that big of a deal if there’s a slight, almost imperceptible delay between clicking a button and seeing the UI respond. “We’ve got bigger fish to fry.” And it makes sense. I mean, a slight delay in UI responsiveness, is that why people will or won’t buy your thing? Seems like a small detail. Who’s got the time to spend on details like this?Who cares? I care. That’s why I’m writing this post. To my original point, every piece of hardware I currently own is the fastest version of that device I’ve ever had in my life. And yet, everywhere I go I encounter lag. Lag everywhere. And I’m grumpy about it, hence this post. Reply via: Email · Mastodon · Bluesky The browser makes a request to the server The server talks to Stripe to get a session The server responds with the session data to the client The client redirects [nothing happens] I think “Did that work?” Just as I’m about to click again, I see the URL bar change I think, “Oh, ok, it’s doing something .” I stop myself from clicking again while I wait for the UI to redraw Is that actually the interaction you want, where the text changes? That’s probably gonna shift layout. Maybe you want something different, like a spinner in place of the text. How do you handle that? What if you have multiple places to upgrade? Do you have to implement state in all those places too? What if the trigger in each place is slightly different? A button here, some text there, and icon over yonder? How do you handle all of those different interactions in a standard, immediate way? Errors. What if it fails? Well, we already weren’t handling that in the first code example were we? But maybe we should…

0 views
Jim Nielsen 2 months ago

A Brief History of App Icons From Apple’s Creator Studio

I recently updated my collection of macOS icons to include Apple’s new “Creator Studio” family of icons. Doing this — in tandem with seeing funny things like this post on Mastodon — got me thinking about the history of these icons. I built a feature on my icon gallery sites that’s useful for comparing icons over time. For example, here’s Keynote : (Unfortunately, the newest Keynote isn’t part of that collection because I have them linked in my data by their App Store ID and it’s not the same ID anymore for the Creator Studio app — I’m going to have to look at addressing that somehow so they all show up together in my collection.) That’s one useful way of looking at these icons. But I wanted to see them side-by-side, so I dug them all up. Now, my collection of macOS icons isn’t complete. It doesn’t show every variant since the beginning of time, but it’s still interesting to see what’s changed within my own collection. So, without further ado, I present the variants in my collection. The years labeled in the screenshots represent the year in which I added the to my collection (not necessarily the year that Apple changed them). For convenience, I’ve included a link to the screenshot of icons as they exist in my collection ( how I made that page , if you’re interested). Final Cut Pro: Compressor: Pixelmator Pro: (Granted, Pixelmator wasn’t one of Apple’s own apps until recently but its changes follow the same pattern showing how Apple sets the tone for itself as well as the ecosystem.) One last non-visual thing I noticed while looking through these icons in my archive. Apple used to call their own apps in the App Store by their name, e.g. “Keynote”. But now Apple seems to have latched on to what the ecosystem does by attaching a description to the name of the app, e.g. “Keynote: Design Presentations”. Reply via: Email · Mastodon · Bluesky Keynote -> Keynote: Design Presentations Pages -> Pages: Create Documents Numbers -> Numbers: Make Spreadsheets Final Cut Pro -> Final Cut Pro: Create Video Compressor -> Compressor: Encode Media Logic Pro -> Logic Pro: Make Music MainStage -> MainStage: Perform Live Pixelmator Pro -> Pixelmator Pro: Edit Images

3 views
Jim Nielsen 2 months ago

Study Finds Obvious Truth Everybody Knows

Researchers at Anthropic published their findings around how AI assistance impacts the formation of coding skills : We found that using AI assistance led to a statistically significant decrease in mastery […] Using AI sped up the task slightly, but this didn’t reach the threshold of statistical significance. Wait, what? Let me read that again: using AI assistance led to a statistically significant decrease in mastery Honestly, the entire articles reads like those pieces you find on the internet with titles such as “Study Finds Exercise Is Good for Your Health” or “Being Kind to Others Makes People Happier”. Here’s another headline for you: Study Finds Doing Hard Things Leads to Mastery. Cognitive effort—and even getting painfully stuck—is likely important for fostering mastery. We already know this. Do we really need a study for this? So what are their recommendations? Here’s one: Managers should think intentionally about how to deploy AI tools at scale Lol, yeah that’s gonna happen. You know what’s gonna happen instead? What always happens when organizational pressures and incentives are aligned to deskill workers. Oh wait, they already came to that conclusion in the article: Given time constraints and organizational pressures, junior developers or other professionals may rely on AI to complete tasks as fast as possible at the cost of skill development AI is like a creditor: they give you a bunch of money and don’t talk about the trade-offs, just the fact that you’ll be more “rich” after they get involved. Or maybe a better analogy is Rumpelstilskin : the promise is gold, but beware the hidden cost might be your first-born child. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 2 months ago

The Browser’s Little White Lies

So I’m making a thing and I want it to be styled different if the link’s been visited. Rather than build something myself in JavaScript, I figure I’ll just hook into the browser’s mechanism for tracking if a link’s been visited (a sensible approach, if I do say so myself ). Why write JavaScript when a little CSS will do? So I craft this: But it doesn’t work. is relatively new, and I’ve been known to muff it, so it’s probably just a syntax issue. I start researching. Wouldn’t you know it? We can’t have nice things. doesn’t always work like you’d expect because we (not me, mind you) exploited it. Here’s MDN : You can style visited links, but there are limits to which styles you can use. While is not mentioned specifically, other tricks like sibling selectors are: When using a sibling selector, such as , the adjacent element ( in this example) is styled as though the link were unvisited. Why? You guessed it. Security and privacy reasons. If it were not so, somebody could come along with a little JavaScript and uncover a user’s browsing history (imagine, for example, setting styles for visited and unvisited links, then using and checking style computations). MDN says browsers tell little white lies: To preserve users' privacy, browsers lie to web applications under certain circumstances So, from what I can tell, when I write the browser is telling the engine that handles styling that all items have never been (even if they have been). So where does that leave me? Now I will abandon CSS and go use JavaScript for something only JavaScript can do. That’s a good reason for JS. Reply via: Email · Mastodon · Bluesky

0 views
Jim Nielsen 2 months ago

The Don’t “Contact Us” Page

Nic Chan comes out as the whistleblower on how many “Contact Us” pages are made (spoiler: they’re designed to keep us from contacting anyone). A “fuck off contact page” is what a company throws together when they actually don’t want anyone to contact them at all. They […] are trying to reduce the amount of money they spend on support by carefully hiding the real support channels […] If you solve your own problem by reading the knowledge base, then this is a win for the company. They don’t want to hear from you, they want you to fuck off. It’s true. This is how the proverbial sausage is made. I’ve been there. I’ve seen these decisions handed down. Which means, like Chan, I know how to read between the lines of most “Contact Us” pages on the internet. I’m not sure about you, but as a user, when I see [these kinds of pages], knowing that whatever my original query was, [I know] I’m going to have to solve it unassisted. My process follows this arc: A direct line to a human is the ultimate luxury in today’s world. The project finished on time, everyone got paid, and the client was happy with the end result, but I still felt very disappointed in the whole thing. So it goes. There’s a scene from The Matrix that kept echoing in my head while reading Chan’s post. There are contact pages, my friends. Endless “Contact Us” pages. Where human beings no longer exist. For a long time I probably wouldn’t have believed it, and then I saw the pages made with my own eyes. Watched them remove the ability for human beings to contact one another. And standing there, facing the pure, automated precision of it all, I came to realize the obviousness of the truth. What is the “Contact Us” page? Cost savings. The “Contact Us” page is a computer-generated dream world, built to keep us from contacting another human in order to save cost and turn a human being into this: a source of revenue. Reply via: Email · Mastodon · Bluesky I have a question. Go to the company’s “Contact Us” page. Immediately intuit from the design of the page whether I’m actually going to be able to contact someone and get help, or if I’m on my own.

0 views