Open editor โ†’

Run workflows headlessly

The browser app is for designing and testing. Two zero-dependency sibling packages re-run the same saved graph from code โ€” same noodle-graph.json, same NanoGPT API, your own key.

Design a workflow in the editor, hit ๐Ÿ’พ to download noodle-graph.json, then load and re-run it from Node.js or Python. Both packages are named nanoodle, ship a library and a CLI, have zero runtime dependencies (Node โ‰ฅ 20 with built-in fetch; Python โ‰ฅ 3.9, stdlib only), and implement the same contract โ€” same graphs, same semantics.

Every run() spends real money from your NanoGPT balance โ€” NanoGPT bills per generation. Loading, validating and inspecting workflows never calls the API, and bad inputs (unknown node types, missing required inputs, missing API key) fail before anything is spent. No telemetry, no analytics; the key is never logged.

JavaScript (Node โ‰ฅ 20)

npm install nanoodle     # library + CLI
npx nanoodle --help      # or run the CLI without installing

Library

import { Workflow } from "nanoodle";

const wf = await Workflow.load("noodle-graph.json");           // key from NANOGPT_API_KEY
const result = await wf.run({ Text: "a cozy ramen shop on a rainy night" });
await result.get("Image").save("ramen.png");                   // media: MediaRef (url + bytes()/save())
console.log(result.costUsd, result.remainingBalance);

With the app's starter graph (text โ†’ LLM prompt-writer โ†’ image), that's the whole program.

CLI

Inspect first โ€” offline; shows inputs, outputs, and settings:

npx nanoodle inspect graph.json

Then run (calls NanoGPT and spends from your balance):

export NANOGPT_API_KEY=...   # or --key K, or --env-file .env
npx nanoodle run graph.json --input Text="a cozy ramen shop" --out ./out
npx nanoodle run graph.json --input n2.system=@style.txt --set n3.size=1k --json
  • --env-file path โ€” load NANOGPT_API_KEY from a .env-style file (--key wins if both are set)
  • --input k=@path โ€” read a file (media as media; .txt / .md / .json as text)
  • --out dir โ€” save media outputs to disk
  • --json โ€” machine-readable result

Python (โ‰ฅ 3.9, stdlib only)

pip install nanoodle
export NANOGPT_API_KEY=...   # nano-gpt.com API key (or OAuth access token)

Library

from nanoodle import Workflow

wf = Workflow.load("noodle-graph.json")
result = wf.run({"Text": "a cozy ramen shop on a rainy night"})
result["Image"].save("ramen.png")            # media: MediaRef (url + bytes()/save())
print(result.cost_usd, result.remaining_balance)

CLI

Installed as nanoodle-py (and python -m nanoodle always works):

nanoodle-py inspect graph.json
nanoodle-py run graph.json --input Text="a cozy ramen shop" --set n3.size=1k --out ./out
nanoodle-py run graph.json --input n2.system=@style.txt --json
nanoodle-py run graph.json --env-file .env --input Text="hello"

Inputs, outputs, settings

Both packages expose the workflow's interface before you run it โ€” wf.inputs, wf.outputs, wf.settings. Input keys are flexible (case-insensitive): the node's custom name ("Text"), nodeId.field ("n2.system"), or the input's label. A workflow with exactly one required input also accepts a bare value: wf.run("hello"). Settings use nodeId.field keys ("n3.model").

Media inputs take a local file (mediaFromFile / media_from_file), a hosted URL, or raw bytes (MIME sniffed). Media is sent inline as base64 (NanoGPT has no upload endpoint); files over ~4.4 MB (~3.5 MB for transcription) are refused locally with a clear error before any paid call.

What runs where

Pure-logic nodes (text, uploads, choice, join, comment) run locally; generation nodes (llm, image, draw, edit, inpaint, vision, video, lipsync, music, remix, tts, transcribe) call NanoGPT. Browser-only media-processing nodes (resize, vframes, combine, soundtrack, trim, extractaudio) are not supported headlessly: workflows containing them load with a warning and fail fast at run(), before any network call. The full table is on the format page.

No account: pay per run in Nano (x402)

Skip the API key entirely. With --pay (or a library payment callback), each paid call returns an HTTP 402 Nano (XNO) invoice โ€” scan/pay from a self-custody wallet; nanoodle waits for the deposit and continues. The library never holds funds or keys.

# JavaScript
npx nanoodle run graph.json --input Text="hello" --pay

# Python
python -m nanoodle run graph.json --input Text="hello" --pay

Worked examples (QR / print invoice, wallet stub, bare chat) live in both packages: nanoodle-js/examples/x402 ยท nanoodle-py/examples/x402.

Use a workflow as an agent skill

A saved workflow plus a short SKILL.md playbook is a skill any coding agent can run โ€” anything that reads markdown and runs shell. Recipe, template and a working example (idea โ†’ LLM prompt โ†’ poster image) ship in both repos: docs/agent-skills.md.