Script Files as Configs (Instead of JSON and YAML)
Tags: softwaredesign, json, yaml, xml
Published: 2024-03-23 05:01:08

This is a small post to share a general idea that might be helpful in scenarios involving a lot of config files.

The idea is for the host the program to **not** read text configs via **file operations**. Instead, host program runs **script files** and uses their **std outputs**. Both of the approaches result in a string that is further processed in the host program. However, there are many merits to the latter approach that is simply not available in a text file.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z2xiex991bjmx78heap8.png)


## Why would this be helpful?
At the end of the day, the host program only wants a string for configs, whether it reads the text file or runs the script process. 
However, using a script as config will allow for more operations and freedom in defining configs. 

The data that is treated as a series of characters in the text config are variables in the script configs. Those variables are processed, and eventually serialized and printed to stdout. Then the stdout is used by the host program. You can use any feature that the scripting language provides before presenting the serialized config to the host.

This approach doesn't clash with the idea of **separation of code and data**. A lot of times, being mindful of the data in the code is a helpful policy for decreasing hard-coding. However, in the use-case of configs, we are treating script files as "data showcased with finesse" rather than "code".

## Examples
Here are some scenarios as examples: 
- **OS specific configs**:
    - **Text config**: Add multiple config files, have the host program detect the os settings and access the right config file
    - **Script config**: Use the scripting language's OS library to automatically present the right config
- **Variation/presets of configs**: 
    - **Text config**: Add multiple config files
    - **Script config**: Host uses the process **command line arguments** when spawning it in order to pass any variables for the config.
- **Config content might not be present and need to be fetched**:
    - **Text config**: The text config doesn't exist. Host program needs to fetch it from disk/network and parse that data. Text config doesn't work.
    - **Script config**: Script can handle the fetching of the config instead of host. It can use the language's networking libraries.
- **Config content has errors or is corrupted**:
    - **Text config**: Text config doesn't recognize it. Host will have to handle it completely.
    - **Script config**: Script can neutralize and defuse the errors to some extent instead of leaving it all to the host program.

## Config of configs
Of course script config can use it's own text configs too, if you find that kind of design to be helpful for your application: 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ptqx4ku5owk8h3qusb0n.png)

## ...
I originally got the idea when I was playing with Neovim, in which you set your personalized configs in a Lua file rather than a text-based config file extension such as JSON.

Anyways, I think this is a cool idea. Thought I'd share it here.