Skip to content

Repository files navigation

Drop a star to support Nu ⭐Join the Nu Discord community
Nu

Nu – the interaction primitive

Build apps in one primitive that spans your whole stack — databases, UIs, AI agents, and services. No glue. 50x less code.

DiscordTwitter Follow

Platform SupportPyPI - Python VersionPyPI PackageLicensePyPI Downloads



AboutBuildQuickstartFabricsAppsSpecExamplesDocsCommunity


ℹ️ About

The primitive Nu is built on, in three words.

A tiny script keeps its values in memory and calls functions on them. Real apps don't stay there. Values live in a database, arrive from a browser form, render into a dashboard, get recomputed by a background job. Almost none of the code is about the values anymore — it's all interaction between systems.

Nu makes interaction the primitive.

  • Ref — a name for a value, wherever it lives: a KV slot, a UI text block, an LLM endpoint, a remote object.
  • Interaction — what you do with a Ref: read, write, branch, iterate, compose.
  • Fabric — binds Refs to a real system. Compose as many as you need; they all speak the same primitive.

Same primitive, different system. One Ref for any resource, one Interaction for any op. Setting a browser text block is the same interaction as setting a KV slot.

Nu is the reference implementation of the interaction model in Python.

🧱 Build with Nu

A few of Nu's fabrics — state, UIs, cluster, models. Same Python, same code shape.

Persistent state

Persistent state. Stores any Python type.

Reach any value by name; it survives restarts. Same code local or sharded across a cluster.

  • Serverless, scales to terabytes
  • Store any Python type
...
classDB(nu.Shape):
hits=nu.kv.IntRef.slot()
# +1 to a persistent counterop=DB.hits.set(DB.hits+1)
app=nu.With(
nu.kv.rocksdb_navigator(".db"),
body=nu.kv.auto_flow_atomic(op),
)
...

Powered by virtuals · rdbpy · RocksDB · LMDB.

Live browser UIs

Reactive UIs from Python. No JS, no build step, no websocket you had to write.

A text block, a chart, a form — set them like variables, they render. Update the value, the browser updates itself.

  • 50+ components out of the box
  • Live updates for free
...
classDashboard(nu.ui.Page):
hello=nu.ui.TextRef.slot()
# renders live in the browserop=Dashboard.hello.set("Hello, browser.")
app=nu.With(
nu.ui.server(op),
)
...

Powered by React · Zustand.

Distributed execution

Same code runs local or across the cluster. No worker pool to run.

Teleport any Nu tree to any worker; it runs there and returns the result. Where it runs is a binding, not a rewrite.

  • Same code, local or remote
  • Distribute with a single line
...
classDB(nu.Shape):
hits=nu.kv.IntRef.slot()
# any Nu opop=DB.hits.set(DB.hits+1)
# same op — teleport it to a workerremote=nu.cluster.Teleport(op, target="gpu-0")
app=nu.With(
nu.cluster.RayCluster(),
body=remote,
)
...

Powered by Ray.

LLM calls

One wire, N providers. Ollama, OpenAI, OpenRouter, Groq, xAI — same call.

LLM chat as a Ref. Swap the model string, keep the code. Local models and hosted APIs meet at the same interface.

  • Add intelligence to any Nu app
  • 7 providers out of the box
...
classBot(nu.Service):
chat=nu.llm.ChatRef.method(temperature=0.7)
# ask the modelop=Bot.chat(prompt="one-line haiku about rust")
app=nu.With(
nu.llm.ollama(Bot, host="localhost", model="qwen2.5:7b"),
body=op,
)
...

And more

Nu is batteries-included and covers the common cases. In-memory state, proxy, HTTP, Python objects, Claude Code, local parallelism — same model, same shape, same primitive as the four above.

Explore all fabrics

🏁 Quickstart

Install, run a demo, start hacking.

01 · Install

Python 3.10+ · everything ships in the wheel.

pip install "nustack-py[all]"

02 · Run a demo

Each one boots a live browser dashboard and picks up where it left off on restart. nu demo lists them all.

countersampled
counter demo A live counter, persistent across restarts.
nu demo counter
sampled demo An infinite series, live-sampled into a line-chart.
nu demo sampled
movies
movies demo A movie tracker: form, filterable table, detail pages.
nu demo movies

03 · Start hacking

  • Read the docs — tutorials, how-tos, and the fabric reference.
  • Browse examples — full source for every demo, plus more programs to steal from.

🧵 Fabrics

Each fabric gives your Nu app a new capability. These are the ones Nu ships with today.

FabricWhatPrimary interaction
nu.kvPersistent state.State.movies.append(m)
nu.uiReactive web UI.Dashboard.count.set_value(n)
nu.clusterCluster compute.Teleport(Add(1,2), "gpu")
nu.llmOpenAI-compatible chat.Bot.chat(prompt="…")
nu.memIn-memory state.users.age.set(12)
nu.proxyFabrics over the network.Proxy(Nav, "10.0.0.1")
nu.httpNu meets the web.Solana.get_slot()
nu.servicePython objects as Refs.Calc.add(a=2, b=3)
nu.ccClaude Code as a Ref.Agent.ask(prompt="…")
nu.mpLocal parallel execution.Teleport(Add(1,2), "worker")

📦 Apps built on Nu

End-user tools written as Nu programs.

RepoWhat
nustackdev/nulogPure-Python, serverless logger and metrics store. Log and observe metrics from any Python code; entries persist to an embedded KV store and scale to billions, in-process. One line boots a live viewer.

📐 Spec

Nu is a reference implementation of the interaction model — a language-agnostic specification of what an interaction is, how Refs name locations, and how Interactions compose into programs.

nustackdev/interaction-model

🛣️ Roadmap

nu.agents fabric — LLM authors Nu programs.

No tool-calling loop. The model's reply is a Nu tree, evaluated in the Context the agent runs in. The Refs bound in scope are the agent's surface — bind different Refs, get a different agent.

  • Safe by construction. Nu's laws validate the tree before any effect fires; With / Provide scoping bounds what the model can touch.
  • Inspectable, replayable, diffable. A Nu program is a data structure.

👥 Community

Nu README badge

Add a Nu badge to your README if you're building on Nu:

Nu

[![Nu](https://img.shields.io/badge/built%20with-Nu-%237A4CE0)](https://github.com/nustackdev/nu)

Contributing to Nu

Considering contributing to Nu? Start by opening an issue or a PR — the codebase is small and readable, and the model is stable enough to build on.

More questions?

  1. Read the docs
  2. Open a feature request or report a bug
  3. Join the Discord community

License

Apache-2.0