Skip to content

dev-formata-io/stof

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation



A smart, declarative runtime for data workflows

What is Stof?

Stof works with other data formats to bridge the gap between static data and programmable documents. It is a lightweight, embeddable, and portable data logic format & platform for AI, infra-as-code, and config-heavy workflows. It's built to support:

  • Data-Mesh, Integration, & Orchestration glue-layer
  • Universal LLM & AI workflows, tools, & intersystem data
  • Smart configs with logic, types, units, schemas, & self-validation
  • Asynchronous validation & transformation

Think of Stof as a foundation for building robust and declarative data flows, config systems, or backend models.

When to use Stof?

Modern software (especially AI/ML, infra, cloud, CI/CD, and workflows) increasingly relies on structured data that needs to be:

  • Human-readable
  • Machine-validatable
  • Extendable with logic
  • Executable safely
  • Translatable between formats
  • Transported between systems
  • Versioned and inspectable

But the tools we have for this are primitive and fragmented:

  • JSON/YAML/TOML carry structure, but rely on other tools for behavior, units, schemas, or validations.
  • External tools create complexity between systems and often require additional configuration & maintenence.
  • Configs drift and break across environments.
  • Runtime logic is scattered across codebases, devops scripts, and data definitions.

Stof unifies structure + validation + behavior into one coherent, inspectable, portable artifact.

Note: if you're doing simple config loading or small and static data modeling, learning Stof might feel like overkill. You can replicate most of what Stof does using JSON + code + libraries; it just takes more effort and lacks formality, organization, single-file simplicity, unification, etc. (also a big pain for cross-boundary systems, like APIs, teams, and services).

Example/Tour

Located in examples/readme for you to try yourself.

/*
 * True data interop!
 * Import/export any format - our goal is to work seamlessly WITH other formats.
 * Organize data, APIs, configs, connectors, pipelines, AI, etc. with objects & paths, as a graph.
 */
import "old_crusty_config.toml" as OldCrusty; // Creates a new root object named "OldCrusty"
import "norse.png" as self.NorseImage;        // Creates a child object with path "root.NorseImage"


/*
 * Define objects and fields in a JSON-like way.
 */
{
    "json-like": "json objects & fields can be parsed by Stof natively",
    str "just stof": "it's all Stof, so use types, etc."
}

field: 42              // Optionally end field declarations with a comma or semi-colon
str typed: "types!"    // Field types for consistency, readability, and reliability
const bool cool: true; // Constant fields for immutable data (with or without type)

MiB unit-types: OldCrusty.server.RAM; // Unit types for conversions on casts, operations, etc.
cm height: 6ft + 1in;                 // Expressions and a full runtime always available


/*
 * Functions & logic as data. Manipulate this document from within.
 *
 * - Sandboxed (host defines system access, if any)
 * - Portable (send and execute over a network)
 * - Simple (familiar, approachable, and intuative, without looking like a blob of JSON)
 */
fn hello_world() -> str {
    "hello, world"
}


/*
 * Use objects to organize every type of data, including logic & APIs.
 * Keyword "self" always refers to the current object.
 * Keyword "super" always refers to the parent object (if any).
 * Navigate the graph of data via dot separated paths (both down and up, including other roots).
 * Use "?" in front of function calls to return null if the function doesn't exist.
 */
Api: {
    import "api"; // default ".stof" extension if not provided
    str config-name: ?self.modular_apis(OldCrusty); // "Old Crusty"
}


/*
 * Attributes for metadata & control (both fields & functions).
 *
 * - Used for main, test, and async functions
 * - Reference objects, functions, and data (validation, access control, schemas, etc.)
 * - Always available programmatically for metadata access
 */
#[my_attribute]
#[attribute_with_val(42days)]
#[metadata_map({"config": true})]
#[metadata_obj(new { stof_object: true })]
#[validation((value: unknown): bool => true)]
metadata_field: "we have attributes"


/*
 * Foundational async behavior for modern networking and concurrency.
 * No threads by default, but host system can implement async as single or multi-threaded.
 *
 * Note: "async fn" just adds #[async] as a function attribute.
 *
 * - HTTP requests & APIs
 * - Database connections
 * - Event driven systems
 * - Declarative UI + logic
 */
async fn doing_something_concurrently() {
    // "Std" library, an extensible & complete standard library
    pln("Hello, Stof!");

    // Turn any expression into an async expression
    const handle = async 42;
    assert_eq(await handle, 42);

    // Async block expressions (and regular block expressions)
    const result = await async {
        let a = 5;
        let b = 5;
        return a + b;
    };
    assert_eq(result, 10);
}


/*
 * Prototypes for modern, complex data models & interfaces.
 * See docs for details.
 *
 * - Schemas
 * - Modular APIs applied to static data
 * - Pipelines & workflows
 * - Inheritance via #[extends(obj | str)]
 */
#[type]
Config: {
    /**
     * Example use with imported OldCrusty TOML data.
     * ```
     * const config = OldCrusty as Config;
     * assert_eq(config.description(), "Left to drift & die, but is required somehow");
     * ```
     */
    fn description() -> str {
        self.description ?? "no description"
    }
}



#[main]
/**
 * Stof CLI uses #[main] attributes by default to tell which functions to run with `stof run`.
 * Change this with the -a option, allowing you to use attributes instead of multiple scripts.
 *
 * Run with CLI via `stof run readme.stof` - you'll see `Hello, Stof!` printed to your console.
 * Run with `stof -d run readme.stof` - you'll now see YAML output in addition.
 *
 * Logging (log_debug, log_trace, log_info, log_warn, log_error) built in:
 * - `stof run readme.stof` - only log_warn & log_error
 * - `stof -d run readme.stof` - log_info in addition to warn & error
 * - `stof -dd run readme.stof` - all logs available
 * - uses "log" Rust crate for flexibility
 */
fn main() {
    self.doing_something_concurrently();

    const yaml = stringify("yaml", self);
    log_info(yaml);
}
> cd examples/readme
> stof run readme.stof
Hello, Stof!

Installation

Add Stof to your Cargo.toml:

[dependencies]
stof = "0.8.*"

See installation docs for CLI instructions and more information.

Documentation

Status

Stof is currently in early development, we welcome feedback and contributions. The core is stable for experimentation, and is actively being used in production at Formata.

New features are being added weekly, so hop into the Discord and get involved!

License

Apache 2.0. See LICENSE for details.

Feedback & Community

  • Open issues or discussions on GitHub
  • Chat with us on Discord
  • Star the project to support future development!

Reach out to [email protected] to contact us directly

Releases

No releases published

Sponsor this project

 

Packages

No packages published