XferLang

XferLang is a data format for data transfer, configuration, and structured content. If you know JSON, you'll feel at home right away, and then you'll start to notice the differences: explicit types, strings that never need escape sequences, text that can pull in values from elsewhere, and processing instructions that let a document tell the parser what to do.

You're reading a page that depends on it, by the way. The navigation for this whole site, including the tabs, the article lists, and the tags, lives in a single XferLang file.

What it looks like

<! document { version "1" } !>
{
    title "Demo"
    active ~true
    retries 3
    ratio *0.8125
    launched @2025-08-01T09:30:00Z@
    tags [ "alpha" "preview" ]
    location ( *42.3601 *-71.0589 )
    banner 'User=<|USER|> ok=<~true~>'
}

Whitespace separates elements, so there are no commas to forget and no colons to line up, and you can spread a document out or squeeze it onto one line without changing what it means. The little prefix on each value says exactly what it is. ~true is a Boolean, *0.8125 is a decimal, and @...@ is a date and time. The parser never has to guess.

Why I made it

Every data format I've used has some tax you pay over and over. With JSON it's the missing comments, the trailing commas, and the backslashes. With YAML it's the guessing, where an unquoted no turns into false and a version number turns into a float. I wanted a format that was as readable as either of them but never made me guess or escape anything.

  • Types are explicit. There are no heuristics.
  • There's no escape tax. When your content contains a delimiter, you lengthen the delimiter instead of adding backslashes, so ""He said, "Hello" then left."" is a perfectly good string.
  • Parsing is programmable. Processing instructions attach metadata, bind names to values, pull values from files or environment variables, and include or skip elements based on conditions. You can extend them or write your own.

That last point is the one I use most. A configuration file can read a secret from a file and the user name from the environment, and only include a block of settings if the secret is there:

<! dynamicSource { apiKey file "secrets/api-key.txt" user env "USER" } !>
<! if defined |apiKey| !> { auth { key |apiKey| user |user| } }

Using it

The reference implementation is a .NET library, on NuGet as ParksComputing.Xfer.Lang. It serializes and deserializes your own classes, with custom converters and contract resolvers when you need them. There's also a Visual Studio Code extension for syntax highlighting and basic diagnostics.

Where it's going

XferLang is still experimental. The next step is a production-quality 1.0 of the .NET library. After that, I'd like to reimplement the core in Rust, expose it through a C interface, and build thin wrappers for C#, Python, JavaScript and anything else that wants one, so every language shares the same fast, memory-safe parser. If that sounds like fun to you, I'm looking for contributors.

Details

  • Reference implementation in C# for .NET, on NuGet as a prerelease.
  • A Visual Studio Code extension for .xfer files.
  • Licensed under MIT.

The code and the full language guide are on GitHub: github.com/paulmooreparks/Xfer.