<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mr Smithnen</title>
    <description>The latest articles on Forem by Mr Smithnen (@marko_kseppnen_6250a7f).</description>
    <link>https://forem.com/marko_kseppnen_6250a7f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3380051%2Fab905cdb-117b-4e21-8430-277edad4f061.jpg</url>
      <title>Forem: Mr Smithnen</title>
      <link>https://forem.com/marko_kseppnen_6250a7f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marko_kseppnen_6250a7f"/>
    <language>en</language>
    <item>
      <title>YINI CLI 1.2.1-beta: Safer Validation, Improved Help, nd Smarter Output Handling</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Mon, 23 Feb 2026 19:00:31 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-cli-121-beta-safer-validation-improved-help-nd-smarter-output-handling-2nkk</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-cli-121-beta-safer-validation-improved-help-nd-smarter-output-handling-2nkk</guid>
      <description>&lt;p&gt;This release improves validation robustness in &lt;code&gt;yini-cli&lt;/code&gt; and makes CLI behavior more predictable and consistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  1.2.1-beta — 2026-02
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Improved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;validate&lt;/code&gt; command:

&lt;ul&gt;
&lt;li&gt;Strengthened diagnostics handling and metadata safety checks.&lt;/li&gt;
&lt;li&gt;Replaced unsafe internal assertions with controlled error handling.&lt;/li&gt;
&lt;li&gt;Improved &lt;code&gt;--silent&lt;/code&gt; behavior and exit code consistency.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  1.2.0-beta — 2026-02
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Improved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--help&lt;/code&gt; now displays full help for all commands.
Command-specific help remains available via:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  yini &lt;span class="nb"&gt;help&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Changed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Extended environment information is now available via the &lt;code&gt;info&lt;/code&gt; command.
The global &lt;code&gt;--info&lt;/code&gt; option has been removed. Use:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  yini info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;parse&lt;/code&gt; now defaults to formatted JSON output.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--compact&lt;/code&gt; outputs minified JSON (no whitespace).&lt;/li&gt;
&lt;li&gt;Improved &lt;code&gt;--output&lt;/code&gt; file handling:

&lt;ul&gt;
&lt;li&gt;Output is written only if the destination file does not exist or is older than the source &lt;code&gt;.yini&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--overwrite&lt;/code&gt; always replaces existing files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--no-overwrite&lt;/code&gt; prevents replacing existing files.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Added
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--js&lt;/code&gt; option for &lt;code&gt;parse&lt;/code&gt; to output JavaScript-style objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deprecated
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--pretty&lt;/code&gt; flag for &lt;code&gt;parse&lt;/code&gt; (use &lt;code&gt;--json&lt;/code&gt; explicitly if needed).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try YINI CLI
&lt;/h2&gt;

&lt;p&gt;Install globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; yini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or run without installing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx yini-cli &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Explore the Project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/YINI-lang/yini-cli" rel="noopener noreferrer"&gt;https://github.com/YINI-lang/yini-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/yini-cli" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/yini-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation &amp;amp; format specification: &lt;a href="https://yini-lang.org?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=yini_cli_release_1_2_x" rel="noopener noreferrer"&gt;YINI homepage&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>cli</category>
      <category>opensource</category>
      <category>tooling</category>
    </item>
    <item>
      <title>I spent a week working on regression tests &amp; metadata guarantees on the YINI config/settings parser</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Wed, 31 Dec 2025 01:09:58 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/i-spent-a-week-working-on-regression-tests-metadata-guarantees-on-the-yini-configsettings-parser-5f2m</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/i-spent-a-week-working-on-regression-tests-metadata-guarantees-on-the-yini-configsettings-parser-5f2m</guid>
      <description>&lt;p&gt;Hey 👋&lt;/p&gt;

&lt;p&gt;I just wanted to share a small win from my side project.&lt;/p&gt;

&lt;p&gt;I've been working on something called YINI for a while now - it's a configuration format together with a TypeScript parser (with spec, grammar, etc).&lt;br&gt;
The goal is basically to be a calmer middle ground between INI, JSON, and YAML for larger, real-world configuration files.&lt;/p&gt;

&lt;p&gt;This past week I didn't really add any new features.&lt;br&gt;
Instead, I finally sat down and did something I've been postponing for a long time: making the parser really solid.&lt;/p&gt;

&lt;p&gt;I just shipped v1.3.3-beta, and most of the work went into building proper smoke and regression tests around the parser.&lt;br&gt;
Not glamorous work at all - but it feels incredibly good now that it's in place.&lt;/p&gt;

&lt;p&gt;The new tests parse a couple of large production-style configurations (one corporate SaaS setup and one more high-security / distributed setup) and verify that:&lt;/p&gt;

&lt;p&gt;the output is identical in default mode, strict mode, and strict+metadata mode&lt;/p&gt;

&lt;p&gt;metadata and diagnostics behave correctly for both valid and broken inputs&lt;/p&gt;

&lt;p&gt;The API didn't change at all in this release - it's simply about making the project more predictable, safer to depend on, and easier to evolve.&lt;/p&gt;

&lt;p&gt;It took longer than I expected, but I'm genuinely happy with where it landed.&lt;/p&gt;

&lt;p&gt;This release was also important to get out because I'm using this parser as the foundation for the next big step of the project: expanding and refactoring the YINI CLI to make it more robust and production-ready.&lt;/p&gt;

&lt;p&gt;If you're building developer tools, working with config-heavy systems, or just dealing with a lot of INI/JSON/XML files in general, you might find YINI interesting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;https://github.com/YINI-lang/yini-parser-typescript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd really appreciate any real-world testing or feedback. And good luck with your own side projects, they always end up being a lot more work than they first appear.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sideprojects</category>
      <category>opensource</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>🔧 yini-cli v1.1.1-beta released</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Sat, 20 Dec 2025 22:52:18 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-cli-v111-beta-released-488f</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-cli-v111-beta-released-488f</guid>
      <description>&lt;p&gt;A new &lt;strong&gt;beta release&lt;/strong&gt; of &lt;code&gt;yini-cli&lt;/code&gt;, the command-line tool for working with YINI configuration files, is now available.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in v1.1.1-beta
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Updated: The CLI now uses YINI Parser &lt;code&gt;v1.3.2-beta&lt;/code&gt; (previously &lt;code&gt;v1.3.0-beta&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This brings in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UTF-8 BOM handling (with and without BOM).&lt;/li&gt;
&lt;li&gt;Shebang (#!) support (the line will be skipped if detected, without breaking parsing).&lt;/li&gt;
&lt;li&gt;Additional parser robustness and test coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About YINI
&lt;/h2&gt;

&lt;p&gt;YINI is an &lt;strong&gt;INI-inspired configuration format&lt;/strong&gt; designed for clarity and predictable behavior.&lt;br&gt;
It supports nesting, comments, and a formally defined syntax, while remaining easy to read and edit by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/yini-cli" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/yini-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 Source code: &lt;a href="https://github.com/YINI-lang/yini-cli" rel="noopener noreferrer"&gt;https://github.com/YINI-lang/yini-cli&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback and small improvements are always welcome.&lt;br&gt;
No breaking CLI changes were introduced.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cli</category>
      <category>node</category>
      <category>tooling</category>
    </item>
    <item>
      <title>YINI Config Parser v1.3.2-beta Released (Node.js)</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Tue, 16 Dec 2025 20:46:37 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-config-parser-v132-beta-released-nodejs-kcg</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-config-parser-v132-beta-released-nodejs-kcg</guid>
      <description>&lt;p&gt;A new beta of the official TypeScript parser for YINI is out!&lt;br&gt;
This release focuses on real-world usability, robust file handling, and dependency hygiene.&lt;/p&gt;

&lt;p&gt;If you're new to YINI: it's a modern, human-friendly configuration format that aims to keep INI-style readability while supporting real structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in 1.3.2-beta
&lt;/h2&gt;

&lt;h3&gt;
  
  
  UTF-8 BOM support
&lt;/h3&gt;

&lt;p&gt;YINI now correctly handles UTF-8 files with or without a Byte Order Mark (BOM).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safe stripping of a leading BOM (U+FEFF)&lt;/li&gt;
&lt;li&gt;Identical parsing behavior for:

&lt;ul&gt;
&lt;li&gt;UTF-8 without BOM&lt;/li&gt;
&lt;li&gt;UTF-8 with BOM&lt;/li&gt;
&lt;li&gt;BOM followed by a blank line&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Explicitly does not treat mid-file U+FEFF as a BOM&lt;/li&gt;

&lt;li&gt;Comprehensive test fixtures added for all cases&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This makes YINI more robust when consuming files created by different editors, platforms, and tooling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shebang (#!) support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;YINI files can now start with a shebang line, which is ignored by the parser.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency updates &amp;amp; security hygiene
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All project dependencies (~14) updated to their latest versions&lt;/li&gt;
&lt;li&gt;Includes TypeScript and packages with reported security advisories&lt;/li&gt;
&lt;li&gt;Node.js type definitions intentionally left unchanged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No breaking API changes were introduced.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install yini-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you're already using it, just bump to 1.3.2-beta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Source code: &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;https://github.com/YINI-lang/yini-parser-typescript&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/yini-parser&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Specification &amp;amp; docs: &lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feedback welcome
&lt;/h2&gt;

&lt;p&gt;YINI is still evolving, and feedback from real users is invaluable.&lt;br&gt;
If you try this release and run into anything odd, or have thoughts on the format itself, feel free to open an issue or start a discussion.&lt;/p&gt;

&lt;p&gt;Thanks to everyone following and testing the project 🙌&lt;br&gt;
Thanks to everyone following and testing the project 🙌&lt;/p&gt;

</description>
      <category>node</category>
      <category>typescript</category>
      <category>tooling</category>
    </item>
    <item>
      <title>The New YINI Homepage Is Live — A Modern, Human-Friendly Config Format</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Sun, 09 Nov 2025 02:20:41 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/the-yini-homepage-is-live-a-modern-human-friendly-config-format-28al</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/the-yini-homepage-is-live-a-modern-human-friendly-config-format-28al</guid>
      <description>&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;I’m excited to share that the new homepage for &lt;a href="https://yini-lang.org/" rel="noopener noreferrer"&gt;YINI config format↗&lt;/a&gt; is now live!&lt;br&gt;&lt;br&gt;
YINI is a &lt;strong&gt;modern, structured, human-friendly configuration&lt;/strong&gt; format that tries to bring together the simplicity of INI with the flexibility of YAML.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 What Is YINI?
&lt;/h2&gt;

&lt;p&gt;YINI was designed to make configuration files both readable for humans and consistent for machines.&lt;/p&gt;

&lt;p&gt;It takes inspiration from INI, YAML, and JSON — but simplifies the rules while still supporting modern features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nested sections using clear markers (&lt;code&gt;^&lt;/code&gt;, &lt;code&gt;^^&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Arrays &lt;code&gt;[1, 2, 3]&lt;/code&gt; and objects &lt;code&gt;{ key: "value" }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inline and full-line comments&lt;/li&gt;
&lt;li&gt;Strict and lenient parsing modes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
name = "Demo"
features = ["search", "dark-mode"]

^^ Server
host = "0.0.0.0"
port = 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌐 The New Homepage
&lt;/h2&gt;

&lt;p&gt;The new site — &lt;a href="https://yini-lang.org/" rel="noopener noreferrer"&gt;yini-lang.org ↗&lt;/a&gt; — brings everything together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧭 Get Started guide&lt;/li&gt;
&lt;li&gt;⚙️ Quick Tutorial with examples&lt;/li&gt;
&lt;li&gt;📘 Full Specification&lt;/li&gt;
&lt;li&gt;💡 FAQ and explanations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s built with Astro + Tailwind, and designed to be fast, clean, and accessible — the perfect home for YINI as the ecosystem continues to grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 The YINI Ecosystem
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yini-parser-typescript&lt;/code&gt; — the official TypeScript parser library&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yini-cli&lt;/code&gt; — a simple CLI for parsing, validating, and converting YINI files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specification&lt;/strong&gt; — now at v1.0 RC stage, aligning parser behavior with the spec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both projects are open-source on GitHub under &lt;a href="https://github.com/YINI-lang" rel="noopener noreferrer"&gt;@YINI-lang ↗&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🗣️ Feedback Welcome
&lt;/h2&gt;

&lt;p&gt;This is still early days for YINI, and community feedback is incredibly valuable.&lt;br&gt;
If you’d like to try it out, explore the homepage, or contribute ideas, you’re more than welcome!&lt;br&gt;
👉 &lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;Check the parser on GitHub → yini-parser-typescript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading — and for helping shape a cleaner, more predictable future for config files 💡&lt;/p&gt;

&lt;p&gt;— Marko Seppänen&lt;/p&gt;

</description>
      <category>config</category>
      <category>programming</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 YINI Parser v1.3.0-beta – Smarter Options, Safer Metadata, and New Controls</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Tue, 23 Sep 2025 14:20:52 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-parser-v130-beta-smarter-options-safer-metadata-and-new-controls-2gn0</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-parser-v130-beta-smarter-options-safer-metadata-and-new-controls-2gn0</guid>
      <description>&lt;p&gt;I've just released yini-parser v1.3.0-beta 🎉 (Node package) - a big step forward for ergonomics, diagnostics, and developer experience when working with &lt;a href="https://github.com/YINI-lang/YINI-spec" rel="noopener noreferrer"&gt;YINI configuration format&lt;/a&gt;, the human-friendly configuration format inspired by INI but with modern clarity.&lt;/p&gt;

&lt;p&gt;This release focuses on &lt;strong&gt;cleaner public APIs&lt;/strong&gt;, &lt;strong&gt;new output controls&lt;/strong&gt;, and &lt;strong&gt;better tooling&lt;/strong&gt; around metadata and CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ What's New
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🐛 Fixed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed a bug where &lt;code&gt;buildResultMetadata(..)&lt;/code&gt; could occasionally produce an &lt;code&gt;undefined&lt;/code&gt; error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔄 Renamed (Breaking API Changes)
&lt;/h3&gt;

&lt;p&gt;To make public types more ergonomic for end-users, several interfaces were renamed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AllUserOptions&lt;/code&gt; → &lt;code&gt;ParseOptions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PrimaryUserParams&lt;/code&gt; → &lt;code&gt;BasicOptions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OnDuplicateKey&lt;/code&gt; → &lt;code&gt;DuplicateKeyPolicy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes names shorter, more consistent, and closer to their intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  📖 Clarified
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;strictMode&lt;/code&gt; parameter in TSDoc has been clarified:
It defines the baseline ruleset (&lt;code&gt;true&lt;/code&gt; = strict, &lt;code&gt;false&lt;/code&gt; = lenient).
Rule-specific options (e.g., &lt;code&gt;treatEmptyValueAsNull&lt;/code&gt;, &lt;code&gt;onDuplicateKey&lt;/code&gt;) may override the baseline.
When overrides are applied, the effective mode becomes &lt;strong&gt;custom&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🆕 New Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DocumentTerminatorRule and EmptyValueRule: new user-facing parsing rule value types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quiet&lt;/code&gt; option:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only prints errors to the console.&lt;/li&gt;
&lt;li&gt;Warnings, notices, etc. are suppressed.&lt;/li&gt;
&lt;li&gt;Diagnostics are still captured in metadata.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;code&gt;silent&lt;/code&gt; option:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suppresses all console output, even errors.&lt;/li&gt;
&lt;li&gt;Programmatic callers should use metadata; CLI users should rely on the exit code.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;code&gt;throwOnError&lt;/code&gt; option:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;true&lt;/code&gt; (default): parser throws on parse errors.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;false&lt;/code&gt;: errors are reported via diagnostics without throwing.&lt;/li&gt;
&lt;li&gt;⚠️ Planned change: next release will switch the default to false.&lt;/li&gt;
&lt;li&gt;✅ Action: set &lt;code&gt;throwOnError: true&lt;/code&gt; to keep current behavior, or &lt;code&gt;throwOnError: false&lt;/code&gt; to adopt the upcoming behavior.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Metadata Improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Added effectiveMode inside meta.diagnostics.effectiveOptions.&lt;/li&gt;
&lt;li&gt;Metadata bumped to v1.1.1.&lt;/li&gt;
&lt;li&gt;Fields strictMode and effectiveOptions now correctly reflect when rules override the initial mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resultet metadata looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parserVersion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.3.0-beta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;totalErrors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;totalWarnings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;totalMessages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;runStartedAt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-09-23T14:23:22.587Z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;runFinishedAt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-09-23T14:23:22.618Z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;durationMs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;30.746&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preservesOrder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orderGuarantee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;implementation-defined&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sourceType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hasDocumentTerminator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hasYiniMarker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lineCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;byteSize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;d79db628387ad8244fc3d394916e20b12c7fe6ef9c39fbf525b9579cdc95130a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;structure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maxDepth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sectionCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;memberCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keysParsedCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sectionNamePaths&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User2.PrefsOfUser2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User2.PrefsOfUser2.DeepSection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User2.PrefsOfUser2.DeepSection.DeeperSection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User2.PrefsOfUser2.DeepSection.DeeperSection.YetDeeperSection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metaSchemaVersion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.1.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🛠️ CI &amp;amp; Tooling
&lt;/h3&gt;

&lt;p&gt;The repo now runs stronger checks on every PR &amp;amp; release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; CodeQL, npm audit, lockfile-lint, Gitleaks (SARIF), Semgrep (SARIF).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grammar drift check:&lt;/strong&gt; Ensures ANTLR-generated sources are committed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regression tests:&lt;/strong&gt; Node/OS matrix coverage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Releases:&lt;/strong&gt; npm publish with provenance (tag-driven).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💬 Other
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parser summary logic and messages have been updated for clearer output.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Install / Upgrade
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;yini-parser@1.3.0-beta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update yini-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📚 Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;yini-parser on npm&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 This release lays groundwork for safer defaults and better developer ergonomics.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🎉 YINI Parser v1.2.0-beta Released</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Sat, 13 Sep 2025 22:36:32 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-parser-v120-beta-released-ef2</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-parser-v120-beta-released-ef2</guid>
      <description>&lt;p&gt;Hi folks!&lt;/p&gt;

&lt;p&gt;I just published &lt;strong&gt;YINI Parser v1.2.0-beta&lt;/strong&gt; 🎊 — the latest beta release of the TypeScript/Node.js parser for the &lt;a href="https://github.com/YINI-lang/YINI-spec" rel="noopener noreferrer"&gt;YINI configuration format&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This release comes with a mix of &lt;strong&gt;fixes, refactors, and quality-of-life improvements&lt;/strong&gt;, especially around runtime safety and metadata handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ What's New
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🛠️ Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;parseFile()&lt;/code&gt; now correctly passes through all options (e.g. &lt;code&gt;includeDiagnostics&lt;/code&gt;), so behavior now matches &lt;code&gt;parse(..)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fixed a small typo (&lt;code&gt;in in&lt;/code&gt;) in file parsing error messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Metadata Improvements
&lt;/h3&gt;

&lt;p&gt;The result metadata structure has been bumped to version 1.1.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;preservesOrder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// Member/section order is implementation-defined, not mandated by the spec.&lt;/span&gt;
&lt;span class="nx"&gt;orderGuarantee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;implementation-defined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;orderNotes&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These fields make it easier for tooling to reason about how order is preserved.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔒 Safer Runtime
&lt;/h3&gt;

&lt;p&gt;The public &lt;code&gt;YINI&lt;/code&gt; class was refactored to use per-invocation runtime state.&lt;br&gt;
This prevents race conditions when multiple &lt;code&gt;parse(..)&lt;/code&gt; / &lt;code&gt;parseFile(..)&lt;/code&gt; calls run in parallel.&lt;/p&gt;

&lt;h3&gt;
  
  
  🗂️ File Layout &amp;amp; Naming
&lt;/h3&gt;

&lt;p&gt;To keep things consistent and tidy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/parseEntry.ts → src/pipeline.ts&lt;/code&gt; (and &lt;code&gt;_parseEntry(..)&lt;/code&gt; → &lt;code&gt;runPipeline(..)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;core/types.ts&lt;/code&gt; → &lt;code&gt;core/internalTypes.ts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Public-facing types/interfaces moved to &lt;code&gt;src/types/index.ts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/yiniHelpers.ts&lt;/code&gt; → &lt;code&gt;src/utils/yiniHelpers.ts&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧹 Naming Consistency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Renamed &lt;code&gt;includeMetaData&lt;/code&gt; → &lt;code&gt;includeMetadata&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Replaced old &lt;code&gt;TJSObject&lt;/code&gt; type with the clearer &lt;code&gt;ParsedObject&lt;/code&gt; type throughout the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📚 Documentation &amp;amp; Tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Expanded and improved &lt;strong&gt;TSDoc comments&lt;/strong&gt; across the public API.&lt;/li&gt;
&lt;li&gt;Unit tests are now colocated with source files (&lt;code&gt;src/**&lt;/code&gt;), ensuring 1:1 visibility between code and its tests.
This reduces the chance of missing coverage when refactoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 Why This Matters
&lt;/h3&gt;

&lt;p&gt;This release is all about stability and clarity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You get more accurate metadata out of the box.&lt;/li&gt;
&lt;li&gt;Safer runtime behavior when parsing concurrently.&lt;/li&gt;
&lt;li&gt;Cleaner project layout that makes contributing and navigating the repo easier.&lt;/li&gt;
&lt;li&gt;Better docs for anyone building on top of YINI Parser.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ParsedObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;YiniParseResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../YINI&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;YiniParseResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myConfigFile.yini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;includeMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔗 Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;yini-parser&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 GitHub: &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;YINI Parser&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 &lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🙏 Feedback
&lt;/h3&gt;

&lt;p&gt;As always, feedback and contributions are super welcome! Try it out and let me know if you hit any edge cases.&lt;/p&gt;

</description>
      <category>node</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>YINI CLI v1.0.2-beta — Smarter Number Parsing 🚀</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Mon, 11 Aug 2025 17:26:43 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-cli-v102-beta-smarter-number-parsing-3le9</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-cli-v102-beta-smarter-number-parsing-3le9</guid>
      <description>&lt;p&gt;Just rolled out YINI v1.0.2-beta, and this one focuses on making the parser more capable and rock-solid when it comes to handling numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 What's New
&lt;/h3&gt;

&lt;p&gt;The internal YINI Parser has been upgraded to v1.0.2-beta, bringing full support for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Negative values&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edge cases across all number types:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Integers
- Floats
- Hexadecimal
- Binary
- Octal
- Duodecimal (base-12)
- Exponential notation
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💡 Why It Matters
&lt;/h3&gt;

&lt;p&gt;If you're working with configs that push the limits—maybe big integer IDs, scientific values, or alternative base notations—this update ensures they'll parse correctly, consistently, and without surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install it globally from npm&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Open your terminal and run:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g yini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test functionality&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Create a simple test file, for example: &lt;code&gt;config.yini&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
  name = 'My App Title'
  version = '1.2.3'
  pageSize = 25
  darkTheme = off
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yini parse config.yini
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Expected result, your CLI should output a parsed version of the config and output something similar to:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My App Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.2.3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;darkTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  All Supported Number Format
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In YINI config format below:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        @yini

        ^ App
          name = 'My App Title'
          version = "1.2.3"
          pageSize = 25
          darkTheme = off

        ^ NumberFormats

          ^^ HexFormat              // Hexadecimal (base-16)
             hex    = #FF0066       // Default notation
             altHex = 0xFF0066      // Alternative notation
          ^^ BinFormat              // Binary (base-2)
             bin    = %10101111     // Default notation
             altBin = 0b10101111    // Alternative notation
          ^^ OctFormat              // Octal (base-8)
             oct    = 0o755         // (decimal 493)
          ^^ DozFormat              // Duodecimal (base-12)
             doz    = 0z10XE        // Default notation:     X=10, E=11
             altDoz = 0z10AB        // Alternative notation: A=10, B=11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will produce following JS object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My App Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.2.3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;darkTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;NumberFormats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;HexFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16711782&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;altHex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16711782&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;BinFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nl"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="nx"&gt;altBin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;OctFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nl"&gt;oct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;493&lt;/span&gt; 
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;DozFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nl"&gt;doz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1859&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="nx"&gt;altDoz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1859&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/YINI-lang/yini-cli/" rel="noopener noreferrer"&gt;yini-cli on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/YINI-lang" rel="noopener noreferrer"&gt;YINI Project&lt;/a&gt;
&lt;em&gt;YINI home.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>node</category>
      <category>webdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How to Use YINI Config Files in a Node.js App (with Real Examples)</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Sat, 02 Aug 2025 23:29:53 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/how-to-use-yini-config-files-in-a-nodejs-app-with-real-examples-4e20</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/how-to-use-yini-config-files-in-a-nodejs-app-with-real-examples-4e20</guid>
      <description>&lt;p&gt;🙋‍♂️ &lt;strong&gt;Why I Wrote This&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You know that moment when you're knee-deep in a side project and you just want a clean config file?&lt;br&gt;&lt;br&gt;
Something easier on the eyes than JSON, but more structured than old-school INI?&lt;/p&gt;

&lt;p&gt;That was me — and that's how &lt;strong&gt;YINI&lt;/strong&gt; started.&lt;/p&gt;

&lt;p&gt;Not to reinvent configuration formats, but just to make one that I wouldn't dread editing.&lt;/p&gt;

&lt;p&gt;In this post, I'll walk you through how to actually use YINI in a Node.js app, with real examples pulled straight from my own parser tests and tooling setup. It's simple, flexible, and (hopefully) a bit fun.&lt;/p&gt;


&lt;h3&gt;
  
  
  📦 Installing the Parser
&lt;/h3&gt;

&lt;p&gt;First, install the YINI parser from npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;yini-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧪 Parsing a Basic Config
&lt;/h3&gt;

&lt;p&gt;Let's start with a simple YINI config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
title = 'My App Title'
items = 25
isDarkTheme = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how you load it in your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yini-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    ^ App
    title = 'My App Title'
    items = 25
    isDarkTheme = true
`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'My App Title'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;YINI &lt;strong&gt;requires strings to be quoted for&lt;/strong&gt; clarity.&lt;br&gt;
Numbers, booleans, and nulls are parsed correctly too — without weird surprises.&lt;/p&gt;

&lt;p&gt;The above config corresponds to this JavaScript object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My App Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isDarkTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📂 Loading from a File
&lt;/h3&gt;

&lt;p&gt;In most real projects, you'll want to load your config from a file.&lt;br&gt;
&lt;code&gt;yini-parser&lt;/code&gt; provides a helper for that: &lt;code&gt;YINI.parseFile(..)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yini-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./config.yini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// e.g., 'My App Title'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works with &lt;code&gt;.yini&lt;/code&gt; files, and supports options like strict mode or metadata.&lt;/p&gt;

&lt;p&gt;Under the hood, &lt;code&gt;parseFile(..)&lt;/code&gt; just reads the file and passes it to &lt;code&gt;YINI.parse(..)&lt;/code&gt;. Simple and clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Structured Config with Nested Sections
&lt;/h3&gt;

&lt;p&gt;Sometimes your config grows — and when it does, structure helps.&lt;br&gt;
YINI supports &lt;strong&gt;nested sections&lt;/strong&gt; (similar as to in Markdown) but with using caret-based indentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@yini

^ App
name = "Nested Example"
version = "1.0.0"
debug = OFF

    ^^ Database
    host = "db.example.com"
    port = 3306
    user = "appuser"
    password = "dbpassword"

        ^^^ Pool
        min = 2
        max = 10
        idleTimeout = 300

    ^^ Logging
    level = "info"
    logToFile = ON
    filePath = "./logs/app.log"

/END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can parse this in &lt;strong&gt;strict mode&lt;/strong&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yiniString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true = strict mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nested Example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;db.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;appuser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dbpassword&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;idleTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;logToFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./logs/app.log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🛠 Optional Metadata
&lt;/h3&gt;

&lt;p&gt;Want more than just key/values?&lt;br&gt;
You can enable &lt;strong&gt;metadata mode&lt;/strong&gt; to get some stats and some other info — useful for diagnostics, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configWithMeta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yiniString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🗨️ Comments — Your Way
&lt;/h3&gt;

&lt;p&gt;YINI supports a variety of comment styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This is a comment
# So is this
-- And this

/*
Block comments
are supported too
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Recap
&lt;/h3&gt;

&lt;p&gt;YINI isn't trying to be better than JSON, TOML, or YAML.&lt;br&gt;
It just tries to be clear, consistent, and pleasant to use — especially when you want nesting without indentation sensitivity, or strict validation without a mess of brackets.&lt;/p&gt;

&lt;p&gt;If you like working with structured configs in Node.js and want something that's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Human-friendly&lt;/li&gt;
&lt;li&gt;Easy to read&lt;/li&gt;
&lt;li&gt;Tooling-ready&lt;/li&gt;
&lt;li&gt;Just structured enough…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Links&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;yini-parser&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;YINI-lang/yini-parser-typescript&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;– Marko&lt;br&gt;
&lt;em&gt;Creator of YINI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This article was originally published on Medium.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>YINI Parser Hits Beta - Human-Friendly, Modern Config Format with Minimal Syntax Noise</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Sun, 27 Jul 2025 18:49:02 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/yini-parser-hits-beta-human-friendly-modern-config-format-with-minimal-syntax-noise-2goo</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/yini-parser-hits-beta-human-friendly-modern-config-format-with-minimal-syntax-noise-2goo</guid>
      <description>&lt;h2&gt;
  
  
  🚀 YINI Parser 1.0.0 Beta 1 is out!
&lt;/h2&gt;

&lt;p&gt;If you're tired of bloated, hard-to-read configuration formats. Or just looking for something truly human-friendly, simple section nesting, etc - Check out &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;YINI&lt;/a&gt;: a modern, minimal configuration file format, now with a TypeScript parser for Node.js.&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;beta release&lt;/strong&gt; includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The parser is now in beta - moved from alpha status, reflecting increased stability and feature completeness.&lt;/li&gt;
&lt;li&gt;Cleaned up exports to support importing this library in both CommonJS (CJS) and ECMAScript Modules (ESM) environments.&lt;/li&gt;
&lt;li&gt;Implemented full support for parsing YINI lists, according to the latest specification.&lt;/li&gt;
&lt;li&gt;Updated the grammar and parsing logic to match the latest YINI specification v1.0.0-RC.1.&lt;/li&gt;
&lt;li&gt;An expanding set of real-world fixtures and tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;A minimal example using YINI in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yini-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
^ App
name     = 'My Title'    // App display name.
items    = 25
darkMode = true

    // Sub-section of App.
    ^^ Special
    primaryColor = #336699
    isCaching = false
`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// To parse from a file instead:&lt;/span&gt;
&lt;span class="c1"&gt;// const config = YINI.parseFile('./config.yini')&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;// My Title&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Special&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCaching&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Title&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;darkMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Special&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3368601&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isCaching&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;And installation in Node.js is just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;yini-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library is out on npm here: &lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;YINI Parser on npm&lt;/a&gt;, so you can try it out for real :P&lt;/p&gt;

&lt;p&gt;If you like what you reading, I want to get more into the YINI format:  &lt;a href="https://github.com/YINI-lang/yini-parser-typescript?tab=readme-ov-file#intro-to-yini-config-format" rel="noopener noreferrer"&gt;Here's intro to YINI Config Format&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Questions, feedback, or bugs? Open an issue on GitHub or drop a comment below!&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Marko Seppänen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;:)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>node</category>
      <category>opensource</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Getting Started with YINI: A Modern, Human-Friendly Config Format</title>
      <dc:creator>Mr Smithnen</dc:creator>
      <pubDate>Tue, 22 Jul 2025 22:46:13 +0000</pubDate>
      <link>https://forem.com/marko_kseppnen_6250a7f/getting-started-with-yini-a-modern-human-friendly-config-format-4n6p</link>
      <guid>https://forem.com/marko_kseppnen_6250a7f/getting-started-with-yini-a-modern-human-friendly-config-format-4n6p</guid>
      <description>&lt;h2&gt;
  
  
  Intro to YINI Config Format
&lt;/h2&gt;

&lt;p&gt;Hi, first you might wonder what yini - a Japanese poem or? :P&lt;/p&gt;

&lt;p&gt;Nah, no :) - YINI is a minimal and human-readable configuration file format (with a formally defined grammar and a specification).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quick Start&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
name = "MyApp"
enabled = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Here's an introduction to the YINI config format...&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Sections
&lt;/h3&gt;

&lt;p&gt;Group settings under a named header. A section header name starts with &lt;code&gt;^&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Start a section with &lt;code&gt;^&lt;/code&gt;, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
title = "AppName"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Alternative section markers to &lt;code&gt;^&lt;/code&gt; are also supported: &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;§&lt;/code&gt;, &lt;code&gt;€&lt;/code&gt; (e.g. &lt;code&gt;&amp;lt; Section&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Key = Value
&lt;/h3&gt;

&lt;p&gt;Each line inside a section is a &lt;strong&gt;key&lt;/strong&gt; (name) and &lt;strong&gt;value&lt;/strong&gt;, separated by &lt;code&gt;=&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Write settings as &lt;code&gt;key = value&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maxConnections = 100
enableLogging  = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Values
&lt;/h3&gt;

&lt;p&gt;Values can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strings&lt;/strong&gt; (always quoted): &lt;code&gt;"hello"&lt;/code&gt; or &lt;code&gt;'world'&lt;/code&gt; (either single or double quoted)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Numbers:&lt;/strong&gt; &lt;code&gt;42&lt;/code&gt;, &lt;code&gt;3.14&lt;/code&gt; or &lt;code&gt;-10&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Booleans:&lt;/strong&gt; &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;yes&lt;/code&gt;, &lt;code&gt;no&lt;/code&gt; (all case-insensitive)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nulls:&lt;/strong&gt; Use &lt;code&gt;null&lt;/code&gt; or leave the value blank after &lt;code&gt;=&lt;/code&gt; (in lenient mode)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lists:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; JSON‑style: &lt;code&gt;["red", "green", "blue"]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Colon‑style:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fruits:
    "Pear",
    "Cherry",
    "Banana"
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Comments
&lt;/h3&gt;

&lt;p&gt;Various commenting styles are supported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;👆 &lt;strong&gt;Caveat:&lt;/strong&gt; If you use &lt;code&gt;#&lt;/code&gt; for comments, always put a space after the &lt;code&gt;#&lt;/code&gt;.&lt;br&gt;
(Otherwise, the parser might misinterpret it as part of a value.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Nested Sections
&lt;/h3&gt;

&lt;p&gt;Use extra carets &lt;code&gt;^&lt;/code&gt; for sub‑sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ Parent
^^ Child

// Add another caret `^` and you get a sub-section
// of the previous section, and so...
^^^ SubChild
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you prefer, you can indent the nested section for visibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ Main
    ^^ Sub
    host = "db.example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One can nest multiple sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ Root
^^ Sub
^^^ SubSub
^ BackToRoot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example with indented sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ Root
value = 'At level 1'
    ^^ Sub
    value = 'At level 2'
        ^^^ SubSub
        value = 'At level 3'

^ BackToRoot
value = 'Back at level 1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above Yini code will produce the following JavaScript object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JS object&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;At level 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;At level 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;SubSub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;At level 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;BackToRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Back at level 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;See section 9 for more advanced marker and naming options.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  6. Lists
&lt;/h3&gt;

&lt;p&gt;👆 &lt;em&gt;List support is planned for an upcoming release.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// JSON‑style list
colors = ["red", "green", "blue"]

// Colon‑style list
fruits:
  "Pear",
  "Cherry",
  "Banana"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can use either single or double quotes for string values in YINI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7. Document Terminator (strict mode)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;/END&lt;/code&gt; marker is required only in strict mode, and optional in lenient (default) mode.&lt;/p&gt;

&lt;p&gt;End a file explicitly with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ App
title = "MyTitle"

/END    // Must be included in strict mode.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Disabled Lines
&lt;/h3&gt;

&lt;p&gt;Prefix any valid line with &lt;code&gt;--&lt;/code&gt; to skip it entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--maxRetries = 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complete Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Advanced Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yini-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Or: import YINI from 'yini-parser';&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YINI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    /*
        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
`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Output:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JS object&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nested Example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;db.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appuser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dbpassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;idleTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;logToFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./logs/app.log&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;If you like what you read, check out the below too :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;➡️ &lt;a href="https://github.com/YINI-lang/yini-parser-typescript" rel="noopener noreferrer"&gt;YINI Parser GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;➡️ &lt;a href="https://medium.com/@marko.seppanen/why-i-created-yini-a-human-friendly-structured-configuration-format-6e23ac5a1d44" rel="noopener noreferrer"&gt;Blog post: Why I created YINI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;➡️ If you have a Node.js project, you might give it a go &lt;a href="https://www.npmjs.com/package/yini-parser" rel="noopener noreferrer"&gt;Official YINI Parser on npm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🤝 Contributing to YINI parser (TypeScript)
&lt;/h3&gt;

&lt;p&gt;We welcome feedback, bug reports, feature requests, and code contributions!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://yini-lang.org/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=yini_launch" rel="noopener noreferrer"&gt;YINI Homepage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bye, Marko Seppänen (author of YINI)&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
