VMGX
A lightweight, text-based format for storing and transmitting data and metadata. Built for creative work, archiving and publishing on the web.
@vmgx 1.0
# A publication record
@id: "vmg-pub-0001"
@type: "publication"
@created: 2026-11-14T22:30:00+01:00
title: "Northern Light"
authors: ["Alex Morgan"]
published: 2027-03-01
pages: 248
website: <https://example.com/books/northern-light>
summary: """
A photo book about "slow light" on the coast.
It follows one harbor through a full year of seasons.
"""
The simplicity of JSON, with what archives and publishers need
JSON is clean, but it has no comments, no dates, no links and no place for metadata. VMGX keeps JSON's shape and adds exactly those things, and nothing more.
Readable first
No outer braces, no quotes around keys, commas optional between lines. A person can read and edit a file without tools.
Real dates
2027-03-01 and 2026-11-14T22:30:00+01:00 are their own types, checked when the file is read. An impossible date is an error.
Links as links
Write <https://…> and tools know it is a web address, ready to check or to show as a hyperlink.
Metadata built in
Keys that start with @, such as @id, @source and @license, describe the record they sit in.
Comments and long text
Annotate with #. Write summaries, captions and bios over several lines in """ text blocks.
JSON in, JSON out
Every VMGX file converts to JSON, and every JSON object converts to VMGX. Nothing is locked in.
The whole language on one page
VMGX 1.0 has eleven value types and a handful of rules. If you know JSON, you can read it already.
Documents and entries
- A file is an object; its outer braces are left out.
- Each entry is
key: value. - Entries are separated by a new line or a comma. A trailing comma is allowed.
- A value starts on the same line as its key. Objects and lists may then span several lines.
- The header
@vmgx 1.0is optional but recommended.
@vmgx 1.0
name: "Vegte Media Group"
founded: 2026, active: true
address: {
city: "Lisbon"
country: "PT"
}
tags: ["media", "archive", "publishing"]
Value types
| Type | Example |
|---|---|
| Text | "Lisbon" |
| Text block | """…""" |
| Integer | 248, -3 |
| Decimal | 19.95, 1.5e3 |
| Boolean | true, false |
| Null | null |
| Date | 2027-03-01 |
| Date-time | 2026-11-14T22:30:00+01:00 |
| Link | <https://example.com> |
| Object | { key: "value" } |
| List | [1, 2, 3] |
Text is always in quotes. That one rule keeps the format unambiguous: true, 2027-03-01 and 248 can never be mistaken for words.
name: "Alex" # correct name: Alex # error: text must be in quotes
Keys
- Bare keys use letters, digits,
_and-, starting with a letter or_. - Quoted keys allow any text, including spaces.
- Metadata keys start with
@. - Keys are case-sensitive, and each key appears only once per object.
first-name: "Alex" isbn_13: "978-0-00-000000-0" "place of birth": "Lisbon" @id: "person-001"
Text and text blocks
Quoted text stays on one line and supports the JSON escapes (\n, \t, \" and others), plus \u{1F600} for any Unicode character.
Text blocks hold text over several lines with no escaping. The line breaks just inside the quotes and the shared indentation are removed, so blocks can be indented neatly.
motto: "Verba volant,\nscripta manent."
bio: """
Photographer and editor.
Writes about "slow travel"
without a single escape.
"""
Dates, times and links
- Dates:
YYYY-MM-DD. Impossible dates such as2026-02-30are rejected. - Date-times follow ISO 8601, with optional seconds and a time zone:
Zor an offset such as+01:00. - For archiving, always include the time zone.
- Links are URLs or URIs in angle brackets, without spaces.
born: 1985-06-15 scanned: 2026-11-14T09:15:00+01:00 published: 2027-03-01T00:00Z homepage: <https://example.com> contact: <mailto:info@example.com> book: <urn:isbn:9780000000000>
Metadata
A key that starts with @ describes the object it sits in, rather than being part of its content. At the top of a file it describes the whole document.
| Key | Meaning |
|---|---|
@id | Unique identifier |
@type | Kind of record |
@created | When it was created |
@modified | When it last changed |
@author | Who is responsible for it |
@source | Where it came from (provenance) |
@license | Usage rights |
@lang | Language code |
@version | Version of the record |
@id: "archive-2026-0412"
@type: "letter"
@source: "Family collection, box 3"
@license: "CC BY 4.0"
@lang: "en"
sender: "M. Clarke"
written: 1953-09-02
transcription: """
Dear family,
...
"""
Comments
# starts a comment that runs to the end of the line. It can stand on its own line or follow a value. A # inside text is just text.
# Catalog entry, checked by hand pages: 248 # including front matter edition: "#2" # this # is part of the text
Try VMGX in your browser
Type or paste on the left. The result updates as you type, and errors point to the exact line and column. Nothing leaves your browser.
VMGX next to JSON and XML
VMGX sits between the two: as light as JSON, with the room for meaning that people use XML for.
| Feature | JSON | XML | VMGX |
|---|---|---|---|
| Comments | No | Yes | Yes, # |
| Quotes around keys | Always | Not applicable | Only when needed |
| Commas | Required, no trailing comma | Not applicable | Optional between lines |
| Multi-line text | Escapes only | Yes | Yes, """ |
| Native dates | No | With a schema | Yes |
| Native links | No | With a schema | Yes, <…> |
| Metadata on records | No convention | Attributes | @ keys |
| Version header | No | Yes | Yes, @vmgx 1.0 |
| Size for the same data | Small | Large | Smallest |
Parsers for the web and for Python
JavaScript
One file, no dependencies. Works in the browser and in Node.js.
<script src="vmgx.js"></script> <script> const record = VMGX.parse(text); record.published.toDate(); // a JavaScript Date record.website.href; // "https://..." VMGX.stringify(record); // back to VMGX VMGX.toJSON(text); // VMGX → JSON VMGX.fromJSON(json); // JSON → VMGX </script>
Python
One file, standard library only. Python 3.11 or later.
import vmgx
record = vmgx.load(open("record.vmgx", encoding="utf-8"))
record["published"] # datetime.date(2027, 3, 1)
vmgx.dumps(record) # back to VMGX
vmgx.to_json(record) # VMGX → JSON
Command line
python vmgx.py check record.vmgx python vmgx.py to-json record.vmgx python vmgx.py from-json data.json python vmgx.py fmt record.vmgx
Downloads
File details
| Extension | .vmgx |
| Media type | application/x-vmgx |
| Encoding | UTF-8 |
| Current version | 1.0 |
| Maintained by | Vegte Media Group |
Grammar
document = [header] members
header = "@vmgx" version newline
members = [member {sep member} [","]]
member = key ":" value
key = ident | "@" ident | string
value = object | list | string | text
| number | "true" | "false" | "null"
| date | datetime | link
object = "{" members "}"
list = "[" [value {sep value} [","]] "]"
sep = "," | newline
link = "<" non-space characters ">"
comment = "#" to end of line