18

I'll try to keep this question short, but it is in 2 parts, please:

  1. Where should config files for nodejs/npm CLI tools be saved?
  2. What should they be called?

Let's say I write a node.js CLI tool that, for example, grabs today's weather and displays it in terminal. I call it weather-getter. Note, the main goal is not to be called programmatically, but typed into terminal like BASH. It is intended to be run by typing its simple name after installing globally, or via a directory in the user's local /bin. (Sudo is not required for its install.)

This project would be installed normally via npm. It can receive a zipcode via an argument like:

gavin@localhost:~$ weather-getter -z "12345"

OK the program works fine like this. My next step would be to allow the user to save a config file somewhere, and pull from that config file for defaults. Similar to a .vimrc file. This config might look like this:

{
  "zipcode": "12345",
  "language": "en",
  "unit": "fahrenheit"
}

I suppose it should begin with a dot. I also suppose it should be located in the npm module install, and not in ~/. Or should I consider using ~/ or /etc/ or ~/.config or ~/.local like many other programs? Should node programs try to use a common directory, such as ~/.config/node/ or ~/.config/npm/? And if the file is in there, should it begin without the dot?

Note: My question is not about reading/writing a file with node.js, just recommendations on the config location and naming convention. Thank you!

Robert Rossmann
  • 11,931
  • 4
  • 42
  • 73
Gavin
  • 752
  • 8
  • 20
  • Similar question: https://stackoverflow.com/questions/1024114/location-of-ini-config-files-in-linux-unix Quite similar or same answers and directions. – Vladimir Vukanac Feb 09 '21 at 21:48
  • This also gives nice suggestioin: "As for your applications, **please use the XDG Standard**! I beg you, and your users will say thanks for you not cluttering their `$HOME` any further." https://unix.stackexchange.com/a/38871/157574 – Vladimir Vukanac Feb 09 '21 at 22:03

2 Answers2

12

Since this is a generic CLI application (which only so happens to be implemented in Node.js) installed into the system path, you should follow the best practices or rules established for the target operating system.

Unix/Linux/OS X, similar

In order of priority, these would be (but are not limited to):

  • ~ (User's home folder) - many programs store user-level config in their home directory, usually in a dot-prefixed file, followed by the application's name (or similar) - i.e. ~/.weather-getter

  • /usr/local/etc, /etc - system-level configuration files. These should generally apply to all users in the system and thus should take less precedence than settings in home folder. The difference between these two etc paths is usually that the former is used for user-installed programs, whereas the latter is for system-level programs (this is especially true for Mac users using Homebrew). This distinction is, however, not always respected and therefore both locations should be checked for config files (preferrably with the /etc directory having lesser priority).

  • Your application's root - these should be the default settings for your application, a fallback when no user or system config has been found.

  • Other locations may be considered if needed.

Windows

This is usually somewhere within %APPDATA% directory if your app allows GUI or at least CLI configuration management, or the Windows registry (using winreg, for example). I have personally little experience with Windows development/CLI so I welcome any further comments or answers on this topic. I believe using the user's homefolder would also be acceptable as long as the file can be marked as hidden (so it does not clutter the view).

Some general considerations

  • Many CLI applications install their default configurations into one of the mentioned locations so the user has a good starting point when configuring your app
  • The way your configuration options are treated when multiple configuration files are present (are they merged in some order? Is only one used? Which one takes precedence?) is completely up to you, but you should make it clear in your documentation, perhaps even mention it in the configuration files themselves
  • If your application requires multiple configuration files it is preferred that they are grouped in their own folder

Update about dotfiles

The reason why some files or folders are prefixed with a dot is to hide them from users' normal view (i.e. when browsing their home directory via a GUI). It is therefore common practice to use dot-prefixed file/folder names when storing configuration files in directories where users normally operate, but not do so when storing config files in system-level folders.

Robert Rossmann
  • 11,931
  • 4
  • 42
  • 73
  • Right inside ~/ seems like a bit too valuable real estate. Should I lean to ~/.config? I see many programs using ~/.config and ~/.local. One is ~/.config/google-chrome/. – Gavin Feb 24 '15 at 23:37
  • 1
    Just checked my `~` on Mac - almost all configuration files are stored directly in there. There is one under `.config` and one under `.local`, but that's it. Personally, `~` is the directory where I would expect a program's configuration to be located. – Robert Rossmann Feb 24 '15 at 23:40
  • Hmm. I wonder, do the config file differences above make it worthwhile to use some sort of common module that figures out the name/location of the tool's config, so there is less to worry about for the programmer? I think of a wrapper that makes writing to log simpler since the programmer doesn't need to figure out the log location. I also wonder about security, perhaps being able to 'jail' modules from reading/writing neighboring configs. – Gavin Feb 24 '15 at 23:54
  • 1
    Well, loading the config files should not really be an issue, just a matter of array and an async loop. You may, however, want to merge user-config with some defaults for which, as it happens, I recently published a nice module - [semantic-merge](https://www.npmjs.com/package/semantic-merge). Anyway, if you think writing a module for this will help someone, go for it! – Robert Rossmann Feb 24 '15 at 23:58
0

The ospath package has a function data() which returns a sensible location for such files for each of the major platforms.

nfelger
  • 823
  • 9
  • 21