What is YINI and Why?

YINI is a human-friendly, text-based configuration format — less verbose than JSON, simpler than YAML, and more expressive than INI.

Designed to stay readable as files grow, with explicit structure and predictable parsing.

✨ The simple idea

Think of YINI as three familiar ideas combined:

  1. INI → simple key = value
  2. JSON → real types (arrays, objects, booleans, numbers)
  3. Headings → clear structure markers (^, ^^, ^^^)

That's YINI — familiar, readable, and structured.

❓ What is YINI?

YINI is an INI-inspired, text-based data format designed for humans first. It combines simple key-value writing with explicit section-based structure and support for common data types such as lists, objects, booleans, and numbers.

🧯 Why does YINI exist?

Many configuration formats become harder to maintain as projects grow.
  • INI is simple, but often too flat as configs grow.
  • JSON is explicit, but can become noisy to edit.
  • YAML is flexible, but indentation can make it fragile.
  • XML is structured, but often adds more syntax than needed.
YINI was designed to address these issues. To stay readable, predictable, and to remain manageable as projects grow. Because configuration lives for years, not minutes.

Example of YINI code:

File basic.yini Source file: basic.yini

✨ What makes YINI different?

  • Clear structure without indentation rules

    No fragile whitespace semantics.

  • Readable nesting that scales

    Files remain easy to scan even when large.

  • Predictable parsing

    Defined by a formal grammar and spec.

  • Human-first design

    Comments, consistency, minimal noise.

⚡ Try YINI in under a minute

No project setup required. Requires Node.js and a terminal.
  • Save the two lines below as config.yini:
    ^ App
    name = "Hello"
  • From your terminal (with Node.js installed), run this:

    npx yini-cli parse config.yini

    JSON is the default output format.

  • Results in JSON:

    {
        "App": {
            "name": "Hello"
        }
    }
That's it.

You just parsed your first YINI file.

💡 Use YINI in practice

Use YINI in real projects with practical tools for parsing, validation, and conversion.

Lenient by default. Strict when needed.

YINI parsers are expected to use lenient mode by default. The strict mode is optional and intended for cases where stronger validation is needed.

  • Lenient mode — for everyday editing.
  • Strict mode — for validation, robustness and CI.
  • Same format — different parser behavior.

Strict versus lenient is a parser mode choice, not a change to the format (language) itself.
The format is fully defined by the YINI specification.

This allows YINI to remain human-friendly by default, while still supporting stricter validation when needed.

⚖️ Quick comparison

JSON vs YINI

JSON can become harder to read and maintain as files grow.

JSON:

{
  "Service": {
    "id": "aurora-gateway",
    "environment": "prod",
    "Limits": {
      "requestsPerMinute": 1200,
      "burst": 60,
      "maxBodyKb": 512
    },
    "Webhooks": {
      "enabled": true,
      "targets": [
        {
          "name": "alerts",
          "url": "https://hooks.example.com/alerts",
          "secret": "****"
        },
        {
          "name": "billing",
          "url": "https://hooks.example.com/billing",
          "secret": "****"
        }
      ]
    },
    "_comment": "JSON can't do comments; people add fields like this (or separate docs)."
  }
}

Hear is the same config, but in YINI

YINI allows comments directly in the file and uses explicit section markers for structure.

YINI:

/* Aurora Gateway service configuration (human-edited) */

^ Service
id          = "aurora-gateway"
environment = "prod"

^^ Limits
requestsPerMinute = 1200
burst             = 60
maxBodyKb         = 512

^^ Webhooks
enabled = true

targets = [
  { name: "alerts",  url: "https://hooks.example.com/alerts",  secret: "****" },
  { name: "billing", url: "https://hooks.example.com/billing", secret: "****" }
]

YAML vs YINI

YAML can be sensitive to indentation and whitespace mistakes. YINI uses explicit section markers instead of indentation to define hierarchy.

YAML:

# One stray indent (whitespace) changes the structure

app:
  name: My App
  server:
    host: 127.0.0.1
    port: 8080
   allowedOrigins:   # <- off by one indent (hard to spot)
    - https://myapp.com
    - "http://localhost:3000"

Here is same config as above

YINI:

# Structure is defined by markers; indentation is optional

^ App
name = "My App"

^^ Server
host = "127.0.0.1"
port = 8080
allowedOrigins = ["https://myapp.com", "http://localhost:3000"]

Point: In YINI the hierarchy is signaled by markers, not whitespace.

🧪 Real example

YINI code:

File settings.yini Source file: settings.yini

This example uses features from the official YINI specification.

Parsed output (JSON):

{
    "Settings": {
        "serviceId": "NebulaService",
        "release": "3.2.1",
        "debugMode": false,
        "tagline": ""Nebula" is a cloud of gas and dust in outer space.",
        "Network": {
            "bindAddress": "127.0.0.1",
            "bindPort": 8080,
            "allowedOrigins": [
                "https://myapp.com",
                "http://localhost:3000"
            ]
        },
        "Capabilities": {
            "enableSearch": true,
            "experimental": [
                "new-ui",
                "streaming-api"
            ],
            "pools": {
                "min_units": 2,
                "max_units": 5,
                "size_mb": 128,
                "timeout_sec": 90
            }
        },
        "DB Config": {
            "host": "db.internal",
            "ssl": true,
            "Security": {
                "username": "service_user",
                "password": "****"
            }
        }
    }
}

New to YINI? Read a short learn the YINI format.


🔭 Next steps

YINI is open-source and actively maintained.