Bootstrap tooling lock-in

Something you want to be careful with is any tooling that locks you into a group of choices. I’m talking about “bootstrap tooling” like the Create React App and Vue-CLIs of this world. Once adopted, leaving the happy path and maintaining an up-to-date codebase is going to throw you into a world of pain. Using bootstrap tooling might initially save you 2 days at setup time. But that is less than the long term costs you’re going to have to pay. Taking this trade-off is fine for a weekend side-project, or a proof of concept, but not so cool for the next primary application of a company. The reason that there’s higher long term costs is twofold:

  1. The bootstrap tooling are built around popular use-case patterns and make those as simple as possible. But most real-life projects diverge from popular use-cases in one way or another, so you can expect to have to override the configuration generated by the tooling. And that can be non-trivial, since the bootstrap tooling abstracts the configuration of underlying tooling. This e.g. requires understanding another set of configuration interface to customize a Webpack configuration. Or you need to eject the project - in which case updating the big dependency tree used by the bootstrap tooling will be your job. More on that below.
  2. To achieve a configurable set of default use-cases, lots of dependency are included in the bootstrap tooling under the hood. When you’re deciding for a bootstrap tool, you’re deciding for hundreds of dependencies, only a fraction of which you might need. They are automatically glued together in a particular way. That’s the value provided - but it’s also a liability. The gluing couples these dependencies together. For example: It can be difficult to update to the latest version of ESLint without updating all of Vue CLI.

Keep everything new, or die trying

But being up-to-date is what you might have to be: In an average project you’ll have multiple Dependabot alerts for security issues every week, requiring dependency updates to patch them. That’s reinforced by the enlarged dependency tree size of the bootstrapping tool. Every additional dependency can not just contain security holes itself, but so can its dependencies, or any peer dependency - levels deep. It gets extra annoying when different peer dependencies require different versions of the a vulnerable dependency. Fixing’s not so easy then. It’s also not uncommon in the JS ecosystem for dependencies that support of old versions is quickly abolished. In the best case of that, the docs for old versions are no longer accessible. In the worst case, the dependency disappears from NPM. The dependency tree can be seen as complex, interconnected organism.

The crux of the story? Keep your configuration abstraction level and dependency tree lean, and try to keep control over them as best as possible.