Bridging two ecosystems rather than forking one

Two good libraries occupying adjacent ground is a common situation in an ecosystem, and the temptation is always to absorb one into the other.

The situation

LexikJWTAuthenticationBundle is the standard way to authenticate a Symfony API with tokens. It handles the firewall, the user provider, the refresh flow. Its token encoder, however, covers a narrow slice of JOSE: signing, with a few algorithms.

If you need encrypted tokens, key sets, rotation by kid or an algorithm it does not implement, you are stuck between a bundle that does authentication well and a framework that does JOSE well.

The interesting decision

The bundle exposes its encoder as an interface. So the answer was not to fork it, nor to ask it to grow: it was to provide another implementation of that interface, backed by JWT-Framework.

A hundred lines or so. The bundle keeps doing authentication, the framework keeps doing JOSE, and neither had to learn the other’s job.

Why this is worth stating

Because a fork looks cheaper on the day you make it and is never cheaper afterwards. You inherit every future fix, every security advisory, and the obligation to explain to users which of the two they should install.

And because it puts a requirement on the library author: expose interfaces at the seams. The bridge exists only because somebody, in the other project, made their encoder replaceable. That decision cost them nothing and saved a fork.

lexik-jose-bridge, if you are in that situation.