My Software contains a lib package, a cli package and an arbitrary number of plugin packages.

The plugin packages do the algorithmic work.

The lib package basically just executes the plugins and passes the result of each plugin to the next plugin and exposes the libs functionality to the cli package. The cli package reads the configuration file and passes the configuration(which plugins to execute in which order) to the lib package. The lib is basically a single line of typescript code that uses the compose/pipe/flow function from functional programming and looks like this:

export const bumpup: (plugins: Plugin[])=> BumpupData = (plugins) => flow(...plugins)();

The reason for making an extra package for a single line is

  1. Eventually the lib should be usable without the cli by other packages
  2. The lib provides the interfaces for plugins and I don't want plugin authors to depend on the cli package to write their plugins, especially for the case where the lib is used without the cli

The plugins are read from the configuration and are loaded dynamically at runtime from the node_modules folder with the dynamic import from ES6.

That module loading code takes the name of the package that should be loaded and returns a function complying to the plugin interface that can be passed to the lib function.

In which package does the code for loading the modules belong and why? What are reason for and against putting that code in one of the packages. I have the feeling that the pattern of separating software in cliand lib package is very common, is there a name for that pattern so I can read more on that pattern?


Suppose you are also creating a REST API and/or a GUI for your system. Would the logic for loading plugins be different than for your current CLI?

If not, then the plugin loading logic belongs in the lib package on the grounds of DRY (Don't Repeat Yourself). You should avoid having the same logic in multiple places in the same project.

| improve this answer | |
  • Thanks for the advice, the example of a Rest api and GUI remembered me of the ports and adapters / hexagon / onion pattern from Domain Driven Design and is indeed a good advice for deciding where to put the module loading code. However for my specific problem I decided to delegate the module loading completely to the user following a pattern I have seen in many node apps like rollup or webpack: Use a .js file for configuration that gets evaluated at runtime and already contains the loaded plugins. But that might not be possible or very cumbersome in other languages. – danielr1996 Jul 12 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.