Skip to main content

Run AI-generated logic safely, inside your app.

Stof is JSON with functions. One document holds data and the logic that works on it, and your app runs it in a sandbox, in-process, in Rust, JavaScript, or Python.

npm i @formata/stofcargo add stofpip install stof

price: 20
discount: (p: float): float => p * 0.8
fn total() -> float {
self.discount(self.price)
}
// your app calls itdoc.call('total');
16

The discount is a function stored in a field, so new logic goes in the same way new data does.

It starts as JSON

Any JSON document is already valid Stof. Add types and functions where you need them, and export back to JSON, YAML, or TOML any time.

Animation showing that a JSON object is already a valid Stof document: the outer braces and key quotes are removed, types are added to each field, and a greet function is added alongside the data.

Valid JSON is already valid Stof.

Everything is data

Stof has functions, but it isn't a language for writing apps. It's a document, and every part of it is data, functions included.

root
├── ticket                          object
│   ├── text: 'Where is my refund?'     field
│   └── priority: 1                     field
└── route()                         function, data on the object like a field

Anything you can do with data, you can do with logic.

Merge two documents, pull one object out with its functions, diff two versions, store it in a database, or send it over the wire as compact binary.

A document can change while it runs.

It can parse new fields and functions into itself, or drop them, with no build step.

It grows to fit your domain.

Your app adds its own functions, types and schemas live in the document, and in Rust you can add your own formats and kinds of data. Instead of designing a rules language or DSL for your product, describe your domain in Stof.

There's very little to learn.

If you can read JSON and a bit of JavaScript, you can read Stof, and so can a model.

Models write logic. Where do you run it?

Models are good at writing small pieces of logic: a routing rule, a validation check, a transform, a tool. Running code your team didn't write is the hard part.

Containers or microVMs
Heavy, slow to start, and more infrastructure to run and secure.
eval in your app
The code can reach everything your app can.
Function calling
The model can only call functions you already wrote. It can't add new logic.
Rule DSLs in JSON
Limited, and awkward to read and write, for people and models alike.
WebAssembly
Needs a compiler toolchain, binaries are large to send, and the logic lives apart from its data.
Stof
A document the model writes and your app runs like any other data: in-process, in under a millisecond, with access to nothing but itself and the functions you give it.

Reach for Stof when

  • A model, a user, or a customer gives you logic you need to run: rules, filters, transforms, scoring, tool behavior.
  • You're about to invent a config format, rules engine, or DSL for your product.
  • The same logic has to run in the browser, on a server, and in a worker, and give the same answer.
  • You want to change behavior by sending a new document, not by shipping a deploy.
  • Logic should travel with the data it belongs to, through APIs, queues, and databases.
Use something else for your own application code, heavy compute, or long-running services. Write those in your main language and give them to Stof documents as functions.
Stof is the policy engine behind Limitr, where pricing documents are pushed to running apps and evaluated in-process on every call.

Start with the data you have

A library inside your app. No server, container, or extra process.

JavaScript and TypeScript
npm i @formata/stof
Rust
cargo add stof
Python
pip install stof
Command line
cargo install stof-cli

Editor support comes with the CLI: the VS Code extension gives you errors as you type, go to definition, completion, and rename. To teach an AI model Stof, give it the Stof skill.