What is YINI and Why?
YINI is a clear, 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
YINI combines the familiar simplicity of INI with structured values similar to JSON, explicit section markers for nesting, and parser modes for flexible editing or stricter validation.
- INI → simple
key = value - JSON → useful types such as arrays, objects, booleans, and numbers
- Headings → clear section markers such as
^,^^, and^^^ - Parser modes → lenient for everyday editing, strict when stronger validation is needed
That's YINI — familiar, readable, structured, and practical to validate.
🧯 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.
Example of YINI code:
Source file: basic.yini
⚡ Try YINI in under a minute
This quick test uses the YINI CLI and 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.yiniJSON is the default output format.
-
Results in JSON:
{ "App": { "name": "Hello" } }
You just parsed your first YINI file.
✨ 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, and low syntax noise.
💡 Use YINI in practice
Use YINI in real projects with practical tools for parsing, validation, and conversion.
-
🛠 Validate and convert YINI files from the command line with
the YINI CLI tool.
The CLI can output JSON, YAML, XML, and JavaScript.
- 📦 Load YINI directly in TypeScript/JavaScript applications with the YINI Parser for TypeScript.
- 🐍 Load YINI directly in Python scripts, tools, and applications with the YINI Parser for Python.
- 🧩 Use YINI for config files, tools, and CI workflows.
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.
Lenient and strict mode are parser choices, not separate versions of
the format.
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)."
}
} Here is the same config 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 the same config in YINI
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:
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
- Get Started
Learn how to install and parse your first config in minutes.
- Code Examples
Real-world YINI examples showing common configuration patterns.
- Specification
Official YINI format rules with full technical details.
- YINI-lang on GitHub ↗
Official GitHub page.
YINI is open-source and actively maintained.
