DEV Community

Mr Smithnen
Mr Smithnen

Posted on

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

Intro to YINI Config Format

Hi, first you might wonder what yini - a Japanese poem or? :P

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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).
Enter fullscreen mode Exit fullscreen mode

👆 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
Enter fullscreen mode Exit fullscreen mode

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

^ Main
    ^^ Sub
    host = "db.example.com"
Enter fullscreen mode Exit fullscreen mode

One can nest multiple sections:

^ Root
^^ Sub
^^^ SubSub
^ BackToRoot
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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' }
}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

8. Disabled Lines

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

--maxRetries = 5
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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)

Top comments (0)