← Back to homeHow I Taught workspace:* to Stay in Its Lane (And Other Adventures in Package Publishing)

How I Taught workspace:* to Stay in Its Lane (And Other Adventures in Package Publishing)

Sunday, 26th of January 2025

Ah, the joys of modern software development. You start with a monorepo, feeling like a wizard who’s just discovered a spell book—TypeScript flows effortlessly between packages, and workspace:* whispers, “Don’t worry, I’ve got this.”

But then you try to share your magical packages with the world, and everything falls apart.

You’re greeted by an error message that might as well say,

📣 “What even is workspace:*? Go home, you’re drunk.”

The consuming app refuses to cooperate. Your carefully crafted dependencies are now just awkward strangers, and you’re left sitting there like, “Why is this happening to me?”

The Problem

In my monorepo, I had a UI library and a utilities library, best friends forever—or so I thought. The UI package relied on the utilities package using workspace:* in package.json, which worked beautifully… until I tried publishing.
The consuming app, blissfully ignorant of monorepo etiquette, decided that workspace:* was some kind of alien language and refused to install the dependencies. Cue me questioning every life decision that brought me to this point 😵‍💫.

The Hack—Er, I Mean, Solution

I dusted myself off and did what any developer does when faced with an impossible problem:

📣 I wrote a script.

In my CI pipeline, I added a prepublish script that ran just before publishing. Its mission? Replace every instance of workspace:* with real version numbers. And because I like a little drama, I didn’t hardcode those versions. Instead, I used GitVersion to dynamically generate them based on the state of the Git repository.

GitVersion, for the uninitiated, is like a fortune teller for your Git history. It looks at your branches, tags, and commits to divine the correct semantic version. So, my script took the version GitVersion produced and swapped it in where workspace:* had been causing chaos.

Now, could I have just used latest as a fallback? Sure. But that’s like putting duct tape on a leaky pipe—you’ll probably regret it later.

The Moral of the Story

Was this the most elegant solution? Probably not. Did it work? Absolutely. And while I can’t say I enjoyed spending hours debugging a problem caused by a single string, I did enjoy the smug satisfaction of watching everything finally work.

So, if you ever find yourself wrestling with workspace:*, just remember: there’s always a script, a tool, or a questionable hack waiting to save the day. And if all else fails, go grab a coffee and pretend it’s someone else’s problem for a while.