Styx

A document language for mortals.

styx
styx-is (a document language)
with-features {
    that make 
    it {easy to-love} // also comments
} 

Minimal punctuation

Everything is space-separated, except inline object form:

styx
sequences (look super clean)
an-object {
    can be
    multi line
}
or {inline style, with commas}

Minimal quoting

Of course, you can have spaces and special chars:

styx
one bare-scalar
two "double-quoted"
raw r#"raw quoted a-la Rust"#
finally <<HEREDOCS
    they work!
    HEREDOCS

Minimal typing

Objects and sequences contain scalar key-values. Scalars are just opaque text at this stage.

yaml
country: NO   # boolean false
version: 3.10 # 3.1
comment: "This is a string for sure"
styx
country NO   // opaque scalar "NO"
version 3.10 // opaque scalar "3.10"
comment "This is a string for sure" // nope, an opaque scalar

Get those types out of your document

and into your schema.

Styx schemas aren't just for objects and arrays — they're for every scalar.

styx
// input
host localhost
port 8080
validated by
styx
// schema
host @string
port @int
deserialized into
rust
Server {
    host: "localhost",
    port: 8080,
}

It starts with a tree

At this point, it's all still objects, sequences, and opaque scalars.

server
├─ host: "localhost"
├─ port: "8080"          ← still text
└─ tls
   ├─ cert: "/path/cert.pem"
   └─ key: "/path/key.pem"

Meaning on tap

Interpret scalars as typed values when you need them.

Durations, integers, dates — the rules are in the spec, not implementation-defined.

rust
let port: u16 = doc["server"]["port"].get()?;
let timeout: Duration = doc["timeout"].get()?;
let created: DateTime = doc["created"].get()?;
javascript
let port = doc.server.port.asInt()
let timeout = doc.timeout.asDuration()
let created = doc.created.asDateTime()
python
port = doc["server"]["port"].as_int()
timeout = doc["timeout"].as_duration()
created = doc["created"].as_datetime()

Standardized interpretation

not implementation-defined.

Durations like 30s or 1h30m. Integers like 0xff or 1_000_000. RFC 3339 dates. It's all in the spec.

styx
timeout 30s
retry 1h30m
poll 500ms
ttl 7d
rust
Duration::from_secs(30)
Duration::from_secs(5400)
Duration::from_millis(500)
Duration::from_secs(604800)
styx
count 1_000_000
color 0xff5500
mask 0b1111_0000
mode 0o755
rust
1000000_i64
16733440_u32
240_u8
493_u32
styx
pi 3.141_592_653
avogadro 6.022e23
small 1.5e-10
max inf
rust
3.141592653_f64
6.022e23_f64
1.5e-10_f64
f64::INFINITY
styx
created 2024-03-15T14:30:00Z
enabled true
debug false
rust
DateTime(2024, 3, 15, 14, 30, 0, UTC)
true
false

Skip the schema

Using Rust? Derive Facet on your types and deserialize directly.

No schema files, no code generation — your types are the schema.

rust
#[derive(Facet)]
struct Server {
    host: String,
    port: u16,
    tls: Option<bool>,
}

let server: Server = facet_styx::from_str(input)?;

Live the schema

Generate schemas from Rust types or write them by hand.

Doc comments become hover text in your editor and show up in error messages.

styx
/// A server configuration.
Server @object {
  /// Hostname or IP address to bind to.
  host @default(localhost @string)

  /// Port number (1-65535).
  port @default(8080 @int{ min 1, max 65535 })

  /// Enable TLS. Defaults to false.
  tls @default(false @bool)
}

Love the schema

Dynamically typed languages like JavaScript can get a fully-typed object through the schema:

typescript
import { parse } from "@bearcove/styx";

const config = parse(input, schema);
console.log(config);
bash
$ node index.ts
{
  "host": "localhost",
  "port": 8080,
  "created": 2024-03-15T14:30:00.000Z  // a Date!
}

Offensively nice tooling

because you deserve better.

Errors that actually help. Autocomplete that actually works. From your editor to your CI pipeline.

Editor Integration

Hover docs, autocomplete, inline errors — powered by LSP.

Set up your editor →

CLI Validation

Validate in CI. Get actionable errors with "did you mean?" suggestions.

See the CLI →

Web Playground

Try Styx in your browser with full syntax highlighting and validation.

CodeMirror | Monaco