Omniconf: comprehensive configuration library for Clojure

TL; DR: Omniconf is a new configuration library for Clojure that unifies environment variables, command-line options, and config files; and ensures the configuration is complete and correct before the main application code runs.

Configuring your application is often a daunting and thankless task. It very much depends on the way you launch your program, so it is difficult to solve the configuration problem for the general case. Twelve-factor app guidelines suggest using environment variables for everything, but that rule is unnecessarily rigid. If you have many options, configuration files are more appropriate. When you launch the app from the command line (on a dev machine, for example), command-line arguments are preferable. But now you suddenly need a unified access to all those configuration sources.

There are already libraries that solve the configuration problem in Clojure, namely: Environ, Aero, Nomad, Fluorine. All of them are quite good at what they do; however, we at Grammarly needed extra functionality — to check the final configuration state before the main program executes, and make sure there are no missing or incorrect options. What began as a few helper functions were extracted into a separate library and called Omniconf.

Using Omniconf may not be as easy as other libraries: here you must define a schema for each option your application supports. Schema describes the type of the option, how it should be parsed, whether it is required, any additional restrictions on the value. Options can be nested for easier structuring. Then, after you have tapped all configuration sources (ENV, CMD, edn files), you call verify, and any inconsistencies will result in an exception. If everything is good, your whole configuration map will be pretty-printed into the console.

Another benefit of having a predefined schema is that you get automatically generated help message when running your program with --help flag; the message exhaustively describes every option your program support.

In conclusion, Omniconf solves a particular subset of configuration problems that you might not be facing; but if you do face them, then you'll probably appreciate this little library. As always, please report any bugs or suggestions in Github issues. Happy hacking!