When Walking Away From Your Own Project Is the Right Call

Maintaining an open source package can be deeply rewarding. Every download, star, and thank-you message validates the hours you've poured into solving a problem. But validation can easily curdle into pride — and pride, left unchecked, leads maintainers to cling to projects long after they've been outclassed.

I've published many open source packages. Most never found much of an audience. One, however, took off quickly and then declined just as fast — not because it broke, but because I deliberately deprecated it in favor of something better.

download graph for glamorous

That project was glamorous, a CSS-in-JS library I created during that pattern's surge in popularity. I believed I could improve on the leading solution at the time, styled-components, and the community seemed to agree. Glamorous gained traction quickly, even surpassing styled-components in downloads at its peak. It became my most visible project by a wide margin.

Then emotion came along. Its creators had actually been active contributors to glamorous, and they'd built something that was, by any reasonable measure, superior. When I asked the community what they thought, my reasoning was straightforward:

  1. Emotion can do everything glamorous can do
  2. Emotion can do more than glamorous can do
  3. Emotion is faster than glamorous
  4. Emotion is smaller than glamorous
  5. It's good for the community to consolidate and rally around using and improving a single solution

With a reasonable migration path in place — an automated tool, courtesy of my friend Tejas Kumar, could port existing codebases — I deprecated glamorous without hesitation. This wasn't an isolated incident. I've deprecated or handed off several projects over the years. The pattern is always the same: I solved a problem, and then I handed the torch to someone else.

The Cost of Duplicate Solutions

When a maintainer sees someone else solve "their" problem better, the instinct is often to compete. That instinct is almost always wrong. Consider a common scenario:

  1. Brad identifies a problem
  2. Brad solves the problem and is willing to maintain it long-term
  3. Mary identifies the same problem
  4. Mary solves the problem better than Brad with a reasonable migration path and is also willing to maintain it long-term

Brad has two sensible options. He can collaborate with Mary, folding her solution into his package under a major version with a migration guide, making them co-maintainers. Or he can deprecate his solution and point users to Mary's.

The unreasonable option is to get upset, double down, and grind until his package is on par with Mary's. That might feel heroic, but it leaves the community with two nearly identical solutions to evaluate, maintain, and choose between. Users face yet another decision in an ecosystem already drowning in them. Contributors split their efforts across two codebases solving the same problem.

Different trade-offs can justify parallel solutions. If two packages make meaningfully different design decisions, the split might be worth the cost. But far too many packages simply aren't differentiated enough to justify the fragmenting effect. And if migration from one to the other is genuinely easy, that's a strong signal the two solutions don't diverge enough to coexist.

Deprecation Isn't an Admission of Failure

There's a natural reluctance to abandon a project after investing significant effort. That reluctance is the sunk cost fallacy wearing a maintainer's hat. Continuing to pour work into an inferior solution — and inviting others to do the same — when a genuinely better option exists is selfish and prideful.

Deprecation causes far less disruption than it might seem. An existing package doesn't stop working when it's deprecated. Migration only becomes necessary if users need bug fixes, features, or a fix for a relevant security vulnerability — in other words, exactly the people who'd want to move to the better solution anyway.

When emotion launched, I felt a twinge of disappointment that glamorous couldn't simply be improved to match it. But that passed quickly, replaced by relief. Someone else was going to carry the problem forward, and I was free to move on to something new. The problem was in good hands.

Reasonable Exceptions

This guidance isn't absolute. Several legitimate reasons might justify keeping a project alive:

When Superiority Is Debatable

If you genuinely believe your solution holds its own, document your reasoning. Put a list of your package's advantages in your docs where people deciding between solutions can find it. If you can't articulate meaningful advantages, you might be experiencing a prideful knee-jerk reaction. Take a beat, then move on.

When Migration Is Painful

If moving users to the better solution would be genuinely difficult, continuing maintenance can be justified. But add a note to your docs pointing new users toward the superior option, and consider building tools to make migration less painful.

When Collaboration Isn't Possible

If you can't work with the other maintainers, so be it. If their solution solves your problem, you're actually free — you can stop maintaining and focus on other projects.

When You Simply Enjoy the Work

That's fine. Just be honest in your docs about whether a better, recommended solution exists, so users can make an informed choice before investing their time.

These exceptions don't apply when you're selling a product. Commercial software is competition, and competition requires differentiating yourself — ideally before someone else does it for you.

Pride Costs Everyone

Multiple packages solving the same problem impose a real tax on the community. Sometimes that tax is worth paying for genuine differentiation. Far more often, it's not. When a clearly better solution arrived for glamorous, keeping the project alive would have meant asking people to keep investing in something inferior out of loyalty to my ego.

Deprecating glamorous was one of the best decisions I made. It freed everyone — users, contributors, and me — to move on to the next problem. The frustration of choosing between similar packages is one every developer knows. Every time a maintainer steps aside in favor of a genuinely better solution, they save the community from that frustration.

If you maintain an open source library and a better alternative exists, consider adding a link in your docs — or deprecating the package entirely. It will make things easier for everyone, yourself included.