YAML Lite parser for Mojo - Native, zero-dependency YAML reader
Parse YAML configuration files in native Mojo with zero Python dependencies.
This is a working YAML Lite parser covering ~80% of common YAML patterns.
Current Capabilities:
- ✅ Nested mappings and sequences
- ✅ Inline list-mappings:
- name: Alice\n age: 30 - ✅ All scalar types (int, float, bool, null, string)
- ✅ Comments anywhere
- ✅ 91/91 tests passing (100%)
- ✅ Works with real configs (pre-commit, custom YAMLs)
Limitations: See COMPATIBILITY.md for details
from yaml import parse
# Parse YAML string
var config = parse("""
server:
host: localhost
port: 8080
debug: true
users:
- name: Alice
role: admin
- name: Bob
role: user
""")
# Access values with type-safe methods
var server = config.get("server")
print(server.get("host").as_string()) # localhost
print(server.get("port").as_int()) # 8080
print(server.get("debug").as_bool()) # True
# Navigate nested structures
var users = config.get("users")
var first_user = users.get_at(0)
print(first_user.get("name").as_string()) # Alice
print(first_user.get("role").as_string()) # admin- Nested Mappings: Any depth, e.g.,
server: {nested: {deep: value}} - Nested Sequences: Any depth, e.g.,
- [- item] - Inline List-Mappings:
- name: value\n key2: value2 - All Scalar Types:
42,3.14,true,null,"string" - Comments:
# anywhere in file - Mixed Structures: Lists in dicts, dicts in lists
- Multi-word strings: Must use
"Hello world"notHello world - Version numbers: Must use
"1.0.0"not1.0.0 - Single-word strings work:
host: localhost✅
- Flow style:
[1, 2, 3]or{key: value}→ use block style - Empty values:
key:→ usekey: nullorkey: "" - Anchors/Aliases:
&anchor,*reference - Multi-document:
---separator - Literal/Folded:
|,> - Writing YAML: Reader-only in v0.1.0
# Add as submodule
git submodule add https://github.com/databooth/mojo-yaml vendor/mojo-yaml
# Use in your code
mojo -I vendor/mojo-yaml/src your_app.mojo# Copy source files
cp -r mojo-yaml/src/yaml your-project/lib/yaml
# Use in your code
mojo -I your-project/lib your_app.mojopixi add modular-community::mojo-yaml # After publication to modular-communityfrom yaml import parse
from pathlib import Path
# From string
var config = parse("name: value")
print(config.get("name").as_string()) # value
# From file
var content = Path("config.yaml").read_text()
var data = parse(content)# Check type before accessing
if value.is_string():
print(value.as_string())
elif value.is_int():
print(value.as_int())
# Or handle errors
try:
var num = value.as_int()
print("Got number:", num)
except:
print("Not a number")var yaml_str = """
config:
database:
host: localhost
port: 5432
servers:
- name: web1
ip: 192.168.1.10
- name: web2
ip: 192.168.1.11
"""
var data = parse(yaml_str)
# Navigate nested mappings
var config = data.get("config")
var db = config.get("database")
print(db.get("host").as_string()) # localhost
print(db.get("port").as_int()) # 5432
# Navigate sequences
var servers = config.get("servers")
for i in range(len(servers.sequence_value)):
var server = servers.get_at(i)
print(server.get("name").as_string())
print(server.get("ip").as_string())✅ Do:
version: "1.0.0" # Quote version numbers
description: "My app" # Quote multi-word strings
host: localhost # Single words OK unquoted
list:
- item1 # Use block style
- item2❌ Don't:
version: 1.0.0 # ❌ Multiple dots fail
description: My app # ❌ Spaces in unquoted strings
list: [item1, item2] # ❌ Flow style not supported
key: # ❌ Empty values failSee examples/ directory for working code:
quickstart.mojo- Quick start from READMEbasic_usage.mojo- Type-safe access patternsnested_data.mojo- Navigate complex structuresread_file.mojo- Reading YAML from disk
Run with: pixi run example-quickstart (or example-all for all)
Real-world YAML files in fixtures/:
yaml_lite_working.yaml- Reference implementationyaml_lite_example.yaml- Comprehensive demopre_commit.yaml- Actual pre-commit config
For detailed compatibility info, see COMPATIBILITY.md.
Compare mojo-yaml performance against Python's pyyaml:
pixi run benchmark-mojo # Run mojo-yaml benchmarks
pixi run benchmark-python # Run Python baseline
pixi run benchmark-all # Run both and compareApple M1 Pro:
| Test Case | mojo-yaml | Python pyyaml | Speedup |
|---|---|---|---|
| Simple sequence (5 items) | 8 μs | 111 μs | 14x |
| Simple mapping (5 pairs) | 9 μs | 185 μs | 21x |
| Sequence of mappings (9 keys) | 19 μs | 367 μs | 19x |
| Nested structure (2 levels) | 22 μs | 433 μs | 20x |
| Large document (30+ values) | 60 μs | 1.1 ms | 18x |
| Real-world config file | 133 μs | 1.2 ms | 9x |
Summary: mojo-yaml is 9-21x faster than Python's pyyaml for typical YAML Lite parsing tasks! 🚀
Detailed reports are saved to benchmarks/reports/ after running benchmarks.
- CHANGELOG.md - Version history and changes
- docs/planning/ - Technical documentation and design docs
- examples/ - Usage examples
- benchmarks/ - Performance benchmarks and reports
- mojo-toml - TOML 1.0 parser/writer for modern configs
- mojo-ini - INI/ConfigParser for Mojo
- mojo-dotenv - Environment variable management
Together these provide comprehensive configuration file support for Mojo! 🎯
Contributions welcome! Please:
- Follow existing code style (see mojo-toml for reference)
- Add tests for new features
- Update documentation
- Australian or US English fine for docs, US spelling for code
Apache 2.0 License - see LICENSE file for details
Open source project with initial development sponsored by DataBooth 🔥