A workflow language lives or dies on its tools, and the industry default is a marketplace: search, install, and trust someone's package with your filesystem. We shipped a standard library instead.
25 builtins ride the binary, across five families: files, data, web, media, flow. Read, write, fetch, jq and their siblings. They are reached the same way as everything else callable, with invoke:, they are versioned with the engine, and there is nothing to install. Nothing to install also means nothing to typosquat, no postinstall script, no supply chain roulette on a Tuesday.
One builtin, 9 honest shapes. nika:fetch turns a page into typed output nine ways: article, markdown, text, links, metadata, selector, sitemap, feed, jq. Read-only by design. The point is not the feature count. The point is that a fetch inside a reviewed file has a declared, typed result, so the step after it knows exactly what it is holding.
nika: v1workflow: headlinestasks: - id: page invoke: tool: "nika:fetch" args: url: "https://nika.sh" - id: save depends_on: [page] invoke: tool: "nika:write" args: path: "./page.md" content: "${{ tasks.page.output }}"Everything beyond the library arrives through MCP: name a mcp: tool id and any server you already run is reachable, but only if the file allow-lists it. Growth belongs in the toolbelt, not in the grammar.
The library grows. The language holds still. That trade is the design.