Getting Started with YINI: A Modern, Human-Friendly Config Format



This content originally appeared on DEV Community and was authored by Mr Smithnen

Intro to YINI Config Format

Hi, first you might wonder what yini – a Japanese poem or? 😛

Nah, no 🙂 – YINI is a minimal and human-readable configuration file format (with a formally defined grammar and a specification).

Quick Start

^ App
name = "MyApp"
enabled = true

It was designed for clarity and simplicity, offering features that aims to improve on classic INI while avoiding the complexity of formats like YAML – yet being less noisy than JSON and TOML.

Here’s an introduction to the YINI config format…

1. Sections

Group settings under a named header. A section header name starts with ^.

Start a section with ^, e.g.:

^ App
title = "AppName"

Alternative section markers to ^ are also supported: <, §, (e.g. < Section).

2. Key = Value

Each line inside a section is a key (name) and value, separated by =.

Write settings as key = value:

maxConnections = 100
enableLogging  = true

3. Values

Values can be:

  • Strings (always quoted): "hello" or 'world' (either single or double quoted)
  • Numbers: 42, 3.14 or -10
  • Booleans: true, false, on, off, yes, no (all case-insensitive)
  • Nulls: Use null or leave the value blank after = (in lenient mode)
  • Lists:

    • JSON‑style: ["red", "green", "blue"]
    • Colon‑style:

      fruits:
          "Pear",
          "Cherry",
          "Banana"
      

4. Comments

Various commenting styles are supported:

// This is a line comment
timeout = 30  // inline comment
# This is also a line comment (must have a space after #)
interval = 30  # inline comment (must have a space after #)
/* Block comment spanning
   multiple lines */
; Full line comment (must be whole line).

👆 Caveat: If you use # for comments, always put a space after the #.
(Otherwise, the parser might misinterpret it as part of a value.)

5. Nested Sections

Use extra carets ^ for sub‑sections:

^ Parent
^^ Child

// Add another caret `^` and you get a sub-section
// of the previous section, and so...
^^^ SubChild

If you prefer, you can indent the nested section for visibility:

^ Main
    ^^ Sub
    host = "db.example.com"

One can nest multiple sections:

^ Root
^^ Sub
^^^ SubSub
^ BackToRoot

Example with indented sections:

^ Root
value = 'At level 1'
    ^^ Sub
    value = 'At level 2'
        ^^^ SubSub
        value = 'At level 3'

^ BackToRoot
value = 'Back at level 1'

The above Yini code will produce the following JavaScript object:

// JS object
{
  Root: {
    value: 'At level 1',
    Sub: { value: 'At level 2', SubSub: { value: 'At level 3' } }
  },
  BackToRoot: { value: 'Back at level 1' }
}

See section 9 for more advanced marker and naming options.

6. Lists

👆 List support is planned for an upcoming release.

// JSON‑style list
colors = ["red", "green", "blue"]

// Colon‑style list
fruits:
  "Pear",
  "Cherry",
  "Banana"

You can use either single or double quotes for string values in YINI.

7. Document Terminator (strict mode)

The /END marker is required only in strict mode, and optional in lenient (default) mode.

End a file explicitly with:

^ App
title = "MyTitle"

/END    // Must be included in strict mode.

8. Disabled Lines

Prefix any valid line with -- to skip it entirely:

--maxRetries = 5

Complete Example

@yini       # Optional marker to identify YINI format.

^ App
name    = "MyApp"
version = "1.0.0"
debug   = off  // Turn on for debugging.

^^ Database
host     = "db.local"
port     = 5432
--user   = "secret"  # This line is disabled due to --.
--userList = ["alice", "bob", "carol"]

/END

Advanced Example

const YINI = require('yini-parser').default; // Or: import YINI from 'yini-parser';

const config = YINI.parse(`
    /*
        This is a multi-line block comment.
    */

    @yini

    ^ App
    name = "Nested Example"
    version = "1.0.0"
    debug = OFF  // This is a comment.

        # Database settings.
        ^^ Database
        host = "db.example.com"
        port = 3306
        user = "appuser"
        --password = "dbpassword"  # Disabled line due to --.
        //password = "dbpassword"  # Not sure yet about this pw.
        password = "dbpassword"  # Keep this secret.

            // Commenting with slashes works too.
            ^^^ Pool
            min = 2
            max = 10
            idleTimeout = 300

        /* Block comment on a single line. */
        ^^ Logging
        level = "info"
        logToFile = ON # This is a comment.
        filePath = "./logs/app.log"

    /END
`);

console.log(config);

Output:

// JS object
{
    App: {
        name: "Nested Example",
        version: "1.0.0",
        debug: false,
        Database: {
            host: "db.example.com",
            port: 3306,
            user: "appuser",
            password: "dbpassword",
            Pool: {
                min: 2,
                max: 10,
                idleTimeout: 300
            }
        },
        Logging: {
            level: "info",
            logToFile: true,
            filePath: "./logs/app.log"
        }
    }
}

Thanks for reading!

If you like what you read, check out the below too 🙂

🤝 Contributing to YINI parser (TypeScript)

We welcome feedback, bug reports, feature requests, and code contributions!

Bye, Marko Seppänen (author of YINI)


This content originally appeared on DEV Community and was authored by Mr Smithnen