Skip to content

Quick Start

Patrik edited this page Oct 17, 2026 · 6 revisions

Quick Start

Pick a language, install the published 0.16.0 library, and parse your first AEON document. The language remains AEON v1.

The AEON Document

Create a file called hello.aeon:

aeon:header = {
  mode:string = "strict"
}

greeting:string = "Hello, World from AEON!"

TypeScript

Install

npm install --ignore-scripts @altopelago/aeon-runtime@0.16.0 @altopelago/aeon-core@0.16.0 @altopelago/aeos-core@0.16.0

Parse

import fs from 'node:fs';
import { runRuntime } from '@altopelago/aeon-runtime';

const source = fs.readFileSync('./hello.aeon', 'utf8');

const result = runRuntime(source, { mode: 'strict', output: 'json' });

if (result.meta.errors.length > 0) {
  throw new Error(JSON.stringify(result.meta.errors));
}
console.log("Greeting:", result.document.greeting);
console.log("Diagnostics:", result.meta.errors);

Add AEOS validation when you need a schema boundary

import fs from 'node:fs';
import { compile } from '@altopelago/aeon-core';
import { runRuntime } from '@altopelago/aeon-runtime';
import { validate } from '@altopelago/aeos-core';

const source = fs.readFileSync('./hello.aeon', 'utf8');
const compiled = compile(source);
if (compiled.errors.length > 0) {
  console.error('Compile failed:', compiled.errors);
  process.exit(1);
}

const schema = {
  rules: [
    { path: '$.greeting', constraints: { required: true, type: 'StringLiteral' } }
  ]
};

const schemaResult = validate(compiled.events, schema);
if (!schemaResult.ok) {
  console.error('Schema validation failed:', schemaResult.errors);
  process.exit(1);
}

const loaded = runRuntime(source, { mode: 'strict', output: 'json' });
if (loaded.meta.errors.length > 0) {
  throw new Error(JSON.stringify(loaded.meta.errors));
}
console.log("Greeting:", loaded.document.greeting);

Or use the runtime shorthand

import { runRuntime } from '@altopelago/aeon-runtime';

const result = runRuntime('greeting:string = "Hello"', { output: 'json' });
if (result.meta.errors.length > 0) {
  throw new Error(JSON.stringify(result.meta.errors));
}
console.log(result.document);

Rust

Install

Add to Cargo.toml:

[dependencies]
altopelago-aeon = "=0.16.0"
serde = { version = "1.0", features = ["derive"] }

Parse into a typed struct

use altopelago_aeon::{LoadOptions, load_file};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct HelloDocument {
    greeting: String,
}

fn main() {
    let loaded = load_file::<HelloDocument, _>("hello.aeon", LoadOptions::default())
        .expect("failed to load AEON document");
    println!("Greeting: {}", loaded.document.greeting);
}

Python

Install

Use non-free-threaded CPython 3.12, 3.13 or 3.14 in a virtual environment:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install altopelago-aeon==0.16.0

This installs the native Rust-backed package from PyPI. It does not silently fall back to the repository's pure-Python reference implementation.

Parse and print

from altopelago.aeon import load_file
from pathlib import Path

loaded = load_file(Path("hello.aeon"))
loaded.require_ok()
print("Greeting:", loaded.document["greeting"])

Or access values by canonical path:

print("Greeting:", loaded.require("$.greeting"))

load_file and load_text return JSON-profile application data. For schema validation, pass a serialized schema contract via schema= or an artifact path via schema_file=; native event records use properties such as event.path, not dictionary access. The native loader does not take the old reference implementation's LoadOptions object.

For metadata-preserving navigation without JSON materialization, opt into Pytonic:

from altopelago.aeon import pytonic

document = pytonic.loads('status = |approved|')
status = document["status"]
print(status.address)        # $.status
print(status.value.kind)     # SymbolicLiteral
print(status.value.decoded)  # approved

Pytonic views are immutable and support SANSA Query. Experimental mutation planning and target validation are separate from schema approval; mutation apply is not exposed. Strict JSON loading rejects symbols rather than silently turning them into ordinary strings.

Upgrading to 0.16.0

Canonical source formatting now uses reference-safe ordering and rejects invalid authored references before sorting. Generic arguments must be types; numeric clarifiers are preserved exactly rather than converted to host numbers. See the 0.16.0 migration guide for byte compatibility, parser AST changes and exact GP/radix validation. Historical integrity verification bytes are unchanged.

Upgrading Namespace Consumers

The 0.15.0 TypeScript SANSA adapter uses portable node topology: $.value[0] identifies a node head; its first content item is $.value[0][0]. Representation names use PascalCase, reference payload paths are absolute portable strings, and binding/head metadata stay distinct. These changes affect consumers of that adapter, not ordinary JSON loader calls or AEON source syntax. See the migration guide.

What Just Happened

In all three languages, the same pipeline ran:

  1. Lexing — the AEON text was tokenized
  2. Parsing — tokens became an Assignment Event Stream (AES)
  3. Validation — the stream was checked for structural correctness
  4. Finalization — the stream was materialized into a native data structure

This is the AEON processing model in action. Each phase has a strict, limited role — the parser never guesses types, the validator never coerces values, and the finalizer only materializes what the earlier phases approved.

Next Steps

Clone this wiki locally