# appcfg

> Application Configuration Library for Node.js

Latest version **0.5.15** (published 2026-07-14) · MIT license · 0 weekly downloads

## Install

```sh
npm install appcfg
pnpm add appcfg
yarn add appcfg
bun add appcfg
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.5.15 |
| Published | 2026-07-14 |
| First published | 2014-01-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 3 |
| Unpacked size | 812.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 3 |
| Maintainers | tenbits |
| Keywords | config, settings |

## Links

- npm: https://www.npmjs.com/package/appcfg
- Repository: https://github.com/atmajs/appcfg
- Homepage: https://github.com/atmajs/appcfg#readme
- Issues: https://github.com/atmajs/appcfg/issues
- npm.io page: https://npm.io/package/appcfg

## Dependencies (3)

- [atma-io](https://npm.io/package/atma-io.md) ^1.3.7
- [atma-class](https://npm.io/package/atma-class.md) ^1.1.84
- [atma-utils](https://npm.io/package/atma-utils.md) ^0.2.66

## Alternatives

- [jsforce](https://npm.io/package/jsforce.md) — 851.2K weekly downloads
- [react-native-qrcode-svg](https://npm.io/package/react-native-qrcode-svg.md) — 693.5K weekly downloads
- [@salesforce/plugin-data](https://npm.io/package/@salesforce/plugin-data.md) — 394.9K weekly downloads
- [@backstage/plugin-search-common](https://npm.io/package/@backstage/plugin-search-common.md) — 308.5K weekly downloads
- [@chain-registry/types](https://npm.io/package/@chain-registry/types.md) — 38.4K weekly downloads

## Recent versions

- 0.5.15 (latest) — 2026-07-14
- 0.5.14 — 2026-07-14
- 0.5.12 — 2025-12-09
- 0.5.11 — 2025-12-09
- 0.5.8 — 2025-01-20
- 0.5.7 — 2025-01-20
- 0.5.5 — 2024-12-13
- 0.5.4 — 2024-07-18
- 0.5.3 — 2024-07-18
- 0.5.2 — 2024-07-18
- 0.5.1 — 2024-07-17
- 0.4.70 — 2023-12-21
- 0.4.69 — 2022-11-09
- 0.4.68 — 2022-07-11
- 0.4.67 — 2022-07-11
- … 66 more at https://npm.io/package/appcfg/versions

## README

#### Application Configuration Library for Node.js and Browser

[![CircleCI](https://dl.circleci.com/status-badge/img/gh/atmajs/appcfg/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/atmajs/appcfg/tree/master)
[![NPM version](https://badge.fury.io/js/appcfg.svg)](http://badge.fury.io/js/appcfg)

- [About](#about)
- [Api](#api)


### About

Load and Combine Configuration from many sources:
- Files
    - JavaScript Module
    - JSON
    - Yaml
    - ENV + `.env`
    - S3 Storage
- Directory (_combine files_)
- MongoDB

Additional features:

- [Command Line overrides](#command-line-overrides)
- [Conditions](#conditions)
- [Special Folder](#special-folder)
- [Interpolations](#interpolations)

When combining objects from many sources, **deep copy** is used:

```javascript
// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, arr: [ 'bar' ] }

// combined (a + b)
{
    sub: { foo: 'foo', bar: 'bar'},
    arr: ['foo', 'bar']
}

// E.g you want completely to overwrite `arr` property, then prefix the key's name with `!`

// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, '!arr': [ 'bar' ] }

// combined (a + b)
{
    sub: { foo: 'foo', bar: 'bar'},
    arr: ['bar']
}
```

Example:

```javascript
import AppCfg from 'appcfg'

const config = await AppCfg.fetch([
    // from file. (with Special Folder format syntax support)
    {
        path: '%APPDATA%/.appName/config.yml',

        // set this source as writable for configuration persistance
        writable: true
    },
    // ENV + .env
    {
        dotenv: true,
        // per default CWD is checked, can be overriden
        path: './foo/bar/'
    },
    // directory
    {
        path: 'defaults/**.yml'
    },
    // mongodb
    {
        mongo: 'barSettings'
    },
    // from file, but use only nested property
    {
        path: 'package.json',
        getterProperty: 'atma'
    }
]);
```

##### Command Line overrides
Command line arguments are parsed and also set to the configuration object.
```bash
$ node app --foo.bar barValue --debug
```

```javascript
let config = await Config.fetch(someSources);

assert.has(config, {
    foo: {
        bar: 'barValue'
    },
    debug: true
})

```

##### Conditions
Yaml conditions example. (_same is also for json format_)

```yml
# conditional root configuration example
'#if debug':
    name: Foo
    host: dev.example.com
'#if test':
    name: Baz
    host: localhost

# conditional property example
port:
    '#if debug': 5000
    '#if test': 5030
    'default': 8080

# conditional array item example
scipts:
    - lib.js
    - '#if debug || test'
        - lib.debug-extension.js

```
Arguments lookup:
- in configuration object
- in cli overrides
- in `process.env`
- compare value as string from `process.env.ENV`

```bash
# from cli example
$ node app --debug

# from environment
$ set ENV=DEBUG
$ node app
```
```javascript
{
    name: 'Foo',
    host: 'localhost',
    port: 5000,
    scripts: [
        "lib.js",
        "lib.debug-extension.js"
    ]
}
```

##### Special Folder
Use special folders for loading/writing configurations, like `%APPDATA%` or `%HOME%`.
Is system agnostic and is parsed from the environment variables.
```javascript
Config.fetch({
    path: '%APPDATA%/.myApplication/global.yml',
    writable: true
});
```

#### Interpolations
Sometimes to not repeat the configuration it is convenient to use interpolations.
It will embed configuration from itself.
```javascript
# someConfig.yml
name: 'Foo'
A:
    lorem: '#[name]'
B:
    ipsum: '#[A.lorem]'
```
```
let config = await Config.fetch({
    path: 'someConfig.yml'
});

assert.has(config, {
    name: 'Foo',
    A: { lorem: 'Foo' },
    B: { ipsum: 'Foo' }
});
```

### API

#### Config

**static**
##### `.fetch(Array<Source>)` => Config Instance
Start loading the configuration from specified sources, returns new deferrable configuration instance

**methods**

##### `<Constructor> (Array<Source>)`

- **`.$read(?Mix)`**
    - `Mix`:
        - `String`: File/Directory/Glob path
        - `Source`: Source object
        - `Array<Source>`
        - `@default` - Array<Source> taken from constructor
    - `@return`: `self`. Is deferrable, so you can attach `done` callbacks to it.

    Load configuration from sources

- **`.$write(config:Object [, ?deepExtend:Boolean, ?setterPath:String):Deferred`**

    Update and save the configuration. Use first matched writable source.
    - `deepExtend`: complex objects and arrays are merged
    - `setterPath`: define nested object in current configuration

- **`.$get(property:String)`**

    - `property`: Dot delimited accessor `config.$get('foo.bar.quux')`

        ```javascript
        // is the same as you if you would write null-check expressions yourself:
        var quuxVal = config.foo && config.foo.bar && config.foo.bar.quux;
        ```
    - `@return`: null or value

- **`.$is(name:String):Boolean`**

    Check conditional environment variable, e.g.: `config.$is('debug')`

    Ways to define the variables. (_Example defines DEBUG **and** TEST flags_)

    - directly in the configuration
        ```yml
        // foo.yml
        debug: true
        test: true
        ```
    - from the command line:
        ```bash
        > node index --debug --test
        ```
    - using environment configuration(_comma delimited_)
        ```bash
        $ set ENV=DEBUG,TEST
        # also
        $ set NODE_ENV=DEBUG,TEST
        $ node index
        ```

- **`.toJSON():Object`**

    Returns clean json configuration object.

- **`.done(callback)`**

    Fire the callback when the configuration is loaded

#### Source

##### Common properties for all source types
```javascript
{
    // Define specific property to extract SUB-JSON from the loaded configuration
    // @default: null
    getterProperty: String

    // Define specific property in the root configuration,
    // where the loaded configuration should be inserted into
    // @default: null
    setterProperty: String

    // Specify if this source can be used for persistence
    // @default: false
    writable: Boolean

    // Fires before source $read function is called
    // (e.g. change this.path property or any other things)
    beforeRead: Function<Source, RootConfig>

    // Fires after source completes reading
    // (e.g. access config object in `Source.config`)
    afterRead: Function<Source, RootConfig>

    // If true, do not log any warning if the source returns 404
    // @default: false
    optional: true

    // If true, then waits until all previous sources are loaded
    // @default: false
    sync: true
}
```


##### FileSource
```javascript
{
    // File path
    path: String
}
```

##### DirectorySource
It will be mapped to multiple FileSources
```javascript
{
    // Directory path with GLOB look-up, e.g. 'configs/**.json'
    path: String
}
```

##### MongoDBSource
_**Depends on ClassJS**_
```javascript
{
    // Collection name
    mongo: String,

    // if source is writable
    // @default: true
    writable: Boolean

    // MongoDB Connection Settings
    // It can be also specified in previous configuration source, under `mongodb` property
    // @default: null -
    settings: {
        // connection string
        connection: String
        // or

        // Port, default 27017
        port: Number,
        // IP, default '127.0.0.1'
        ip: String,

        // Database name, no default
        db: String
    }
}
```

##### CustomSource
This source type can suit any needs.

```javascript
// Constructor with the Deferrable Interface and the method `read`
Function

class Foo {
    config: any
    async read (){
        // do any reads and calcs, after that resolve the source
        this.config = await loadConfig();
    }
}

```

##### Embedded
Include config direct into the source
```javascript
{
    config: Object
}
```


#### Test
```bash
$ npm install
$ npm test
```
----
(c) 2014-2022 MIT License

---
_Source: https://npm.io/package/appcfg · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
