The FDK — the Flux Development Kit
The FDK is everything you program against: the standard prelude, the pinned routines, the pillar APIs, and the capability catalogue. It is the difference between “a language” and “a platform you can build a product on”. This page is the map — the namespaces that make up the prelude, the pillars that each carry their own reference page, and the capability model that gates every effect. The detail lives on the pillar pages linked throughout; what lives here is the shape of the whole kit and the two properties that give it that shape.
New here? Start with Guide §3 — Your first session →
Two properties run through all of it, and they are the reason the FDK looks the way it does:
- Domain-complete, not a general-purpose standard library. There is no
filterthat shrinks a list, no regular-expression engine, no unbounded queue, no ambient I/O. Every one of those was left out because it would break totality, determinism, or the sandbox — and for every one of them there is a bounded replacement that does the job the domain actually needs. - Everything is pinned. Where an implementation could differ between two engines — a transcendental, a decimal division, a Unicode case fold, a calendar addition, a random draw, a sort with absent values — the FDK carries one routine, shared by the interpreter, the compiled module and the server. Not “the same algorithm”. The same code, so every machine computes the same numbers.
The prelude
In v1 the prelude is flat — every function is in scope, and the method-style chain does the rest:
plot close.ema(20).rsi(14) // ≡ plot rsi(ema(close, 20), 14)After you type close., the editor offers only the functions whose first parameter accepts a
price. The type system is the discovery mechanism, which is what makes a flat namespace of a
few hundred functions navigable rather than overwhelming.
Modules and qualified names (mod.f) exist, and they extend to packages — see
Packages & distribution.
The namespaces
One line per family — a map, shared with the pillar pages rather than drifting from them. The
scalar families (math, stat, vec, decimal, time, ta, enc/crypto/id/bits) are
catalogued in full in compute; the other rows name their pillar.
| Namespace | What it covers |
|---|---|
math.* |
Dimensional arithmetic: abs sign min max clamp floor ceil round preserve the dimension; sqrt halves the exponents; pow(x, n:lit) scales them; log exp sin cos tan atan atan2 demand dimensionless input. Every transcendental routes through the pinned library — never the platform’s. |
stat.* |
mean stdev variance skew kurtosis median percentile rank correl covar zscore linreg + the exponentially-weighted family. Bounded window reducers; order statistics through the pinned na-ordering. |
vec.* |
map fold scan zip sum avg product min max reverse take drop window · fill · range · setAt · where / mask (length-preserving) · sortBy / topK · count any all. No filter, no flatMap — a data-dependent length would break totality. |
decimal.* |
Exact fixed-point: div round (division names its target scale, half-even; round quantizes to a scale), with bare toDecimal / toFloat as the f64 bridge. long ≡ decimal(18,0), long128 ≡ decimal(38,0). |
time.* |
The calendar: years months weeks days (the only producers of a period), the accessors, epoch conversions, in_session, barsPerYear. now() is a presentation symbol — reading it from analysis is [ErrFirewall]. |
str.* / fmt.* |
Bounded text: len slice startsWith endsWith contains indexOf split trim pad rep upper lower; string interpolation; fmt.num/price/pct/time through one canonical formatter. No regular expressions — see text for what replaces them. |
ta.* |
The indicator catalogue — over eighty kernels, each with a kind signature. |
anim.* / sig.* |
The CANVAS signal generators and combinators (tween, spring, wave, noise, stagger, hold…). Presentation-only, by the firewall. |
enc.* / crypto.* |
base64 base32 hex codecs; pinned hashes (sha256, blake3, …), a keyed MAC, and signature verification — a sandbox verifies, it never signs. |
id.* |
Deterministic identifiers: uuidV4(seed), uuidV7(t, seed), nanoid, slug. Seeded, never ambient entropy. |
bits.* |
Bitwise work as named functions (band bor bxor bnot shl shr sar · popcount clz ctz rotl rotr) on the machine word, plus a bounded byte buffer — the substrate for binary codecs. Named, never infix: and/or/not stay the sealed signal logic, and no new token enters the grammar. |
geom.* |
2-D geometry for drawing tools and custom layout — screen-space by design. |
coll.* |
Ordering and collation combinators; see collections and i18n. |
viz.* |
Data → marks: scales, axes, legends, facets, statistical transforms. See display. |
The pillars
Each pillar is a full API with its own page:
| Pillar | One line |
|---|---|
| compute | The columnar dataframe algebra, the numeric layer, and the domain libraries. |
| collections | Vec / Deque / Map / Set / Tree — bounded, ordered, value-semantic. |
| color | The color kind, its constructors, perceptual interpolation, and the output channels. |
| text | Structured text, the editing protocol, segmentation, diff, search, validators. |
| i18n | Locales as values, message catalogues, plural and gender selection, collation, RTL. |
| units | meas[u] — general quantities, affine scales, exact conversions. |
| net | The network as a stream: five verbs, typed payloads, declared backpressure. |
| display | Scenes as values, the two strata, panes and windows, viz.*. |
| host services | Files, clipboard, notifications, auth, payments, media, print, fonts, embedding. |
| server | Headless applications, shared storage with tiered access, prerender. |
| asset & currency | The instrument tag (B, Q [, @v]), fx, money, venues. |
The capability model
Nothing in the FDK reaches the outside world on its own. An effect is inert data the script emits; the host — the only holder of the resource — executes it, and only if the capability was declared in the manifest and granted by the user.
app reader {
capabilities: [ net:fetch, storage:own, notify:send ]
init(p) = { unread: 0 }
update(m, msg) = match msg {
Got(item) -> { model: m with { unread: m.unread + 1 },
cmds: [ Persist("inbox", item), Notify("new-item", item, Open) ] }
Open(hit) -> { model: m with { unread: 0 }, cmds: [] }
}
view(m) = col { text("unread: {m.unread}") }
subs(m) = [ OnFeed(Got) ]
}Every effect in that body is a request, and each one is answerable to a line of the manifest:
OnFeed to net:fetch, Persist to storage:own, Notify to notify:send. Delete a line from
capabilities: and the corresponding cmds entry stops compiling.
Figure — an effect leaves the script as inert data, and the host executes it only against a granted manifest line.
Three properties make this more than a permission list:
- A request for an ungranted capability is a compile error (
[ErrCapDenied]), not a runtime exception to be caught and retried. - A capability is never a value. The script cannot hold one, store one, pass one, or re-delegate one. It holds a request.
- A manifest aggregates transitively, with zero escalation. If a package you depend on wants the network, that surfaces in your manifest, visible to whoever installs your app, before they install it — and it is still capped by what the user granted.
This is the property that makes an untrusted author safe to run: the guarantees hold whoever wrote the script, so machine-generated code is covered on exactly the same terms as hand-written code. The full capability catalogue and the resource-handle doctrine live in host services; how a request becomes a command and a subscription is specified in The App plane.
Doc-as-data
Every function, kind, keyword and operator carries a structured documentation record — its signature, its kinds, its parameters, its summary, its examples. One source, many renderings:
- the editor’s hover card and its completion list,
- these pages,
- the error messages,
- the snippets.
They cannot drift apart, because they are the same data. And a completeness lint enforces the rule that makes it stick: every construct in the language has a documentation record and at least one runnable example — and every example is a golden. A documented function whose example stops working turns a test red.
Implementation status
The language core and its analysis-plane surface are implemented; the pillars are sealed designs being built in a frozen order, collections first. Each pillar page describes its surface in the present tense and explains, in prose, anything the design holds back — a rollout that follows v1, a seam kept open and inert, an alternative weighed and set aside. The consolidated matrix of what is built versus specified is in Implementation status.
See also
- Guide §3 — Your first session — the FDK as you first meet it.
- Kinds — the dimensional type system every namespace is built on.
- The App plane — capabilities, commands, subscriptions.
- Guide §13 — Cookbook — the FDK in working recipes.
- Packages & distribution — modules, imports, and third-party libraries.
- Working in the editor — where doc-as-data is actually experienced.