Two fields in package.json both claim to pin your package manager. They can't both be satisfied, the tools that read them are moving in opposite directions, and picking wrong can lock you out of your own repo.
Two fields in package.json both claim to pin your package manager. They can't both be satisfied, the tools that read them are moving in opposite directions, and picking wrong can lock you out of your own repo.
Every post on this blog needs two images that do completely different jobs: a social card that has to earn a click in a feed, and an inline hero that opens the article. This post is about how the blog makes both — a typographic default that costs nothing, an opt-in artificial-intelligence (AI) cover that costs about four cents, and the little Model Context Protocol (MCP) server that wires an image model straight into Claude Code. The cover above was made by that exact pipeline.
Bundlers are the most invisible critical infrastructure in frontend development. Every npm run dev and every continuous-integration (CI) pipeline runs through one, yet most of us only think about them when something breaks or when a migration guide lands in our feed. This post is an attempt to fix that: what a bundler actually does under the hood, how we got from script tags to Rust toolchains, which tool owns which niche today, and where the whole thing is heading.
The real goal is simpler: make the terminal fast, readable, predictable and comfortable enough that it gets out of your way.
I've started using chezmoi to manage my dotfiles: shell config, Git config, editor settings, aliases, and all those small files that make a machine feel like mine.
The basic idea is simple:
chezmoi source repo ↔ my real $HOME files
But the direction matters.
Testing Open Graph locally is a bit deceptive: your browser can see localhost, but Facebook, LinkedIn, Slack, Discord, X/Twitter, etc. cannot.
The best workflow is:
1. Check the HTML locally
2. Expose localhost with ngrok
3. Test the public URL in real social preview/debugger tools
Chrome plugins are useful for fast feedback, but the final validation should happen through a public HTTPS URL.
I wanted a tiny CLI tool for a very specific workflow: take an image and expand its canvas to 1200x630, centered, without resizing the image itself. Useful for Open Graph images.
But the interesting part was not the image logic. The interesting part was this constraint:
I do not want global Node, npm, pnpm, TypeScript, or tsx.
That changes the setup.
Your .zshrc started as ten tidy lines and has quietly become a 400-line dumping ground of half-remembered aliases, dead exports, and copy-pasted snippets you're afraid to delete. Here's how to clean it up and keep it that way.