npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sylphx/synth-ini

v0.2.3

Published

INI parser using Synth's universal AST - hand-written, zero dependencies

Readme

@sylphx/synth-ini

INI parser using Synth's universal AST. Hand-written, zero dependencies.

Features

  • 100% In-House - Hand-written parser, zero external dependencies
  • 🚀 INI Format Support - Windows INI, .gitconfig, .editorconfig, PHP INI
  • 🎯 Universal AST - Converts INI to Synth's language-agnostic format
  • 🔌 Plugin System - Transform AST with sync/async plugins
  • 📦 Lightweight - No dependencies except @sylphx/synth core
  • ⚙️ Flexible - Supports both ; and # comments, = and : separators

Installation

npm install @sylphx/synth-ini

Usage

Quick Start

import { parse } from '@sylphx/synth-ini'

const ini = `
  [user]
  name = John Doe
  email = [email protected]

  [core]
  editor = vim
`

const tree = parse(ini)
console.log(tree.nodes[tree.root])

Parser API

import { INIParser, createParser, parse, parseAsync } from '@sylphx/synth-ini'

// Standalone function (recommended)
const tree = parse('key = value')

// Async parsing (for plugins)
const tree = await parseAsync('key = value')

// Class instance
const parser = new INIParser()
const tree = parser.parse('key = value')

// Factory function
const parser = createParser()
const tree = parser.parse('key = value')

Plugin System

import { parse, type Tree } from '@sylphx/synth-ini'

// Sync plugin
const myPlugin = {
  name: 'my-plugin',
  transform(tree: Tree) {
    // Modify tree
    return tree
  }
}

const tree = parse('key = value', { plugins: [myPlugin] })

// Async plugin
const asyncPlugin = {
  name: 'async-plugin',
  async transform(tree: Tree) {
    // Async modifications
    return tree
  }
}

const tree = await parseAsync('key = value', { plugins: [asyncPlugin] })

Custom Options

// Custom comment characters
const tree = parse(iniSource, {
  commentChars: ['//', '#']
})

// Allow duplicate keys
const tree = parse(iniSource, {
  allowDuplicates: true
})

AST Structure

The parser generates a universal Synth AST with these INI-specific node types:

Section

{
  type: 'Section',
  data: {
    name: 'user'
  },
  children: [/* KeyValue nodes */]
}

KeyValue

{
  type: 'KeyValue',
  data: {
    key: 'name',
    value: 'John Doe'
  }
}

Supported INI Features

Syntax

  • ✅ Sections: [section]
  • ✅ Key-value pairs: key = value
  • ✅ Alternative separator: key: value
  • ✅ Comments: ; comment or # comment
  • ✅ Inline comments: key = value ; comment
  • ✅ Quoted values: key = "quoted"
  • ✅ Empty values: key =
  • ✅ Nested section names: [parent.child]
  • ✅ Global keys (before any section)
  • ✅ Windows line endings (\r\n)

Comment Styles

  • ✅ Semicolon: ; comment
  • ✅ Hash: # comment
  • ✅ Custom: configurable via commentChars option

Examples

.gitconfig (Git Configuration)

const ini = `
  [user]
  name = John Doe
  email = [email protected]

  [core]
  editor = vim
  autocrlf = input

  [alias]
  st = status
  co = checkout
  br = branch

  [color]
  ui = auto

  [remote "origin"]
  url = https://github.com/user/repo.git
  fetch = +refs/heads/*:refs/remotes/origin/*
`

const tree = parse(ini)

.editorconfig (Editor Configuration)

const ini = `
  # EditorConfig is awesome
  root = true

  # Unix-style newlines with a newline ending every file
  [*]
  charset = utf-8
  end_of_line = lf
  insert_final_newline = true
  trim_trailing_whitespace = true

  # Matches multiple files with brace expansion notation
  [*.{js,ts,jsx,tsx}]
  indent_style = space
  indent_size = 2

  # Markdown files
  [*.md]
  trim_trailing_whitespace = false
  max_line_length = off

  # Python files
  [*.py]
  indent_style = space
  indent_size = 4
`

const tree = parse(ini)

Windows INI (Application Settings)

const ini = `
  [Settings]
  WindowWidth=1024
  WindowHeight=768
  Fullscreen=false
  Language=English

  [Graphics]
  Quality=High
  VSync=true
  AntiAliasing=4x
  Shadows=Medium

  [Audio]
  MasterVolume=80
  MusicVolume=60
  SFXVolume=70
`

const tree = parse(ini)

PHP Configuration

const ini = `
  ; PHP Configuration File

  [PHP]
  engine = On
  short_open_tag = Off
  precision = 14
  output_buffering = 4096
  zlib.output_compression = Off

  [Date]
  date.timezone = America/New_York

  [Session]
  session.save_handler = files
  session.use_cookies = 1
  session.use_only_cookies = 1
  session.name = PHPSESSID
  session.auto_start = 0
  session.cookie_lifetime = 0
  session.cookie_path = /
  session.cookie_domain =
  session.cookie_httponly = 1
`

const tree = parse(ini)

Database Configuration

const ini = `
  [database]
  host = localhost
  port = 5432
  name = myapp
  user = admin
  password = secret123

  [cache]
  enabled = true
  driver = redis
  host = 127.0.0.1
  port = 6379
  ttl = 3600

  [logging]
  level = debug
  file = /var/log/app.log
  max_size = 10485760
`

const tree = parse(ini)

Performance

Hand-written parser optimized for:

  • Fast line-by-line parsing
  • Minimal memory allocations
  • Arena-based AST storage (O(1) node access)
  • Zero external dependencies

Development Philosophy

This package is 100% in-house - we own the entire parsing pipeline:

  • Hand-written parser - Direct line-by-line parsing
  • Zero dependencies - Only depends on @sylphx/synth core
  • Simple format - INI is well-suited for custom implementation

INI is a simple configuration format with straightforward syntax, making it ideal for in-house implementation without a separate tokenization phase.

Use Cases

  • Git configuration: Parse .gitconfig files
  • Editor configuration: Parse .editorconfig files
  • Windows applications: Parse INI config files
  • PHP configuration: Parse php.ini files
  • Database configuration: Parse database config files
  • Static analysis: Analyze configuration structure
  • Config validation: Validate configuration files
  • Code generation: Transform config to code

Comparison with Other Parsers

Unlike many INI parsers that return plain JavaScript objects, @sylphx/synth-ini returns a universal Synth AST that:

  • Preserves structural information (sections, key-value pairs)
  • Supports powerful transformations via plugins
  • Integrates with other Synth parsers
  • Enables cross-language AST operations
  • Provides consistent API across all formats

License

MIT