crystal-toml v0.1.0

TOML v1.0 parser and serializer for Crystal, with comment-and-format preservation across round-trips. Drop-in replacement for crystal-community/TOML.cr.

= crystal-toml :source-language: crystal :toc: left :toc-title: Table of contents :toclevels: 2

image:https://github.com/aloli-crystal/crystal-toml/actions/workflows/ci.yml/badge.svg[CI,link=https://github.com/aloli-crystal/crystal-toml/actions/workflows/ci.yml]

French version: link:README.fr.adoc[README.fr.adoc]

TOML v1.0 parser and serializer for Crystal, with comment and formatting preservation across parse → modify → write round-trips. Pure Crystal, zero runtime dependencies.

100% conformance with the official https://github.com/toml-lang/toml-test[`toml-lang/toml-test`] v2.1.0 interop suite (205/205 valid, 473/473 invalid).

== Why

The Crystal ecosystem has one TOML shard today, https://github.com/crystal-community/TOML.cr[crystal-community/TOML.cr]. It parses only (no writer), targets the obsolete TOML v0.5 spec, and collapses the document into a flat Hash that drops every comment, blank line, and the declarative ordering.

For configuration files and secret vaults that humans read and edit, that is unworkable. crystal-toml is built around three goals:

. TOML v1.0 conformance, validated against the official https://github.com/toml-lang/toml-test[toml-test] interop suite. . Byte-identical round-trip: TOML.parse(s).to_toml == s for every valid s. The AST keeps trivia (comments, whitespace, blank lines, original number/string representation) attached to their nodes. . Targeted edits that only touch what you change. Modify one value in a 200-line config and the diff is one line, not the whole file reformatted.

== Installation

Add the dependency to your shard.yml:

[source,yaml]

dependencies: crystal-toml: github: aloli-crystal/crystal-toml version: "~> 0.1"

Then shards install.

== Usage

=== Simple read (drop-in for crystal-community/TOML.cr)

[source,crystal]

require "crystal-toml"

hash = TOML.parse_to_hash(File.read("config.toml")) puts hash["database"]["host"]

=== Edit while preserving comments

[source,crystal]

require "crystal-toml"

doc = TOML.parse(File.read("vault.toml"))

doc.set("DATABASE_URL", "postgres://new...") doc.set_with_comment("API_KEY", "ak_...", " rotated 2026-04-28") doc.delete("OLD_TOKEN")

Comments, blank lines, and key order are all preserved.

File.write("vault.toml", doc.to_toml)

== Status

v0.1.0 — first public release. Fully conformant with TOML v1.0 per the official toml-lang/toml-test interop suite. See CRYSTAL-TOML-SPECS.adoc in the sibling prod-crystal/ repository for the full functional and technical specification.

== License

MIT — see link:LICENSE[LICENSE].

Repository

crystal-toml

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 1
  • 15 minutes ago
  • April 28, 2026
License

MIT License

Links
Synced at

Tue, 28 Apr 2026 13:41:56 GMT

Languages