AST parser for the MAML data format. Produces a full abstract syntax tree with node types, source positions, and comment preservation — designed for building formatters, linters, codemods, and editor tooling.
For a simpler parser that returns plain JavaScript values, see maml.js.
- Full AST with discriminated union node types
- Source positions (offset, line, column) on every node
- Comments preserved and attached to nodes
print()reconstructs source from AST, including comments- Zero dependencies, ESM first
- Works in Node.js, Deno, Bun and browsers
npm install maml-ast
import { parse, print, toValue } from 'maml-ast'
const doc = parse(`{
# Database config
host: "localhost"
port: 5432
}`)print() reconstructs MAML source from an AST, preserving comments:
print(doc)
// {
// # Database config
// host: "localhost"
// port: 5432
// }toValue() strips AST metadata and returns plain JavaScript values:
toValue(doc) // { host: 'localhost', port: 5432 }Every node has a type discriminant and a span with start/end positions.
| Node Type | type |
value |
raw |
|---|---|---|---|
| String | 'String' |
string |
yes |
| Raw String | 'RawString' |
string |
yes |
| Integer | 'Integer' |
number | bigint |
yes |
| Float | 'Float' |
number |
yes |
| Boolean | 'Boolean' |
boolean |
— |
| Null | 'Null' |
null |
— |
| Object | 'Object' |
properties |
— |
| Array | 'Array' |
elements |
— |
Object keys are either IdentifierKey (type: 'Identifier') for bare keys like foo, or StringNode (
type: 'String') for quoted keys like "foo bar".
Comments are attached to the nearest node:
Property.leadingComments— comments on lines before the propertyProperty.trailingComment— comment on the same line after the valueObjectNode.innerComments/ArrayNode.innerComments— comments inside an empty container or after the last entryDocument.leadingComments/Document.trailingComments— comments before/after the root value
parse() returns a Document node wrapping the root value:
interface Document {
type: 'Document'
value: ValueNode
leadingComments: CommentNode[]
trailingComments: CommentNode[]
span: Span
}