Discover

Discover

walkthrough · core concepts

Krill is a platform where you chain functional nodes together.

It starts with a server and the app of your choice. From there you add nodes — one at a time — and wire them up. By the end of this page you'll understand data points, cron timers, calculations, and the one idea that ties them all together: nodes only react to the things they're told to observe.

01 · getting started

Run the Krill server. Open the app. They find each other.

Download the Krill server and run it on any machine on your local network. Then open the Krill app on your phone, tablet, laptop, or desktop — it broadcasts on the LAN and the server answers back.

No cloud, no accounts, no port forwarding. Everything stays on your network and everything connects automatically.

concept · the swarm

A server + the apps connected to it. Servers can also find each other and pair, but that comes later — start with one server.

your network mDNS · LAN
krill server · home.local
phone
desktop
tablet
laptop
02 · add a node

Add a data point to the server.

A data point is the simplest kind of node. It holds a single typed value — a number, a boolean, a string — and remembers it. Anyone connected to the server can read it; anyone with permission can change it.

Right now this is just a number sitting on the server. It doesn't know about anything else, and nothing knows about it. That's fine — every krill graph starts like this.

concept · data point

Every reading, toggle, counter, label and reading in krill is a data point. They are the nouns of the system.

project · home › nodes 1 node
data point · int
myDataPoint
0
created · just now
03 · add a timer

Add a cron timer next to it.

A cron timer is a node that fires on a schedule. "Every 5 seconds", "every weekday at 6am", "the first of every month" — anything you can write as a cron expression.

Drop one into your project alongside the data point. You now have two nodes, sitting next to each other in the same project.

Here's the catch: they don't know about each other. The data point doesn't watch the timer. The timer doesn't write to the data point. They're just two nodes living in the same room.

concept · cron timer

A scheduler node. Fires an event whenever its schedule says it should — independent of everything else.

project · home › nodes 2 nodes · 0 connections
cron timer
every5s
⏲ 5s
schedule · */5 * * * * *
data point · int
myDataPoint
0
value · unchanged
not connected · two strangers in the same room
04 · add a calculation

Add a calculation node. Rename the data point to Counter.

A calculation node runs a small expression and produces a value. The expression can reference other nodes — for example, Counter + 1. Calc nodes are how krill does arithmetic, math, and small bits of logic without needing real code.

We'll also rename myDataPoint to Counter — because that's what it's about to become.

Same situation as before, though: three nodes, zero connections. The calc node knows its formula but hasn't been told when to run. The cron is ticking away, but nothing listens. The counter sits at 0.

concept · calculation

A formula node. Re-runs its expression whenever a node it observes changes — and writes the result somewhere you tell it to.

project · home › nodes 3 nodes · 0 connections
cron timer
every5s
⏲ 5s
*/5 * * * * *
calculation
bumpCounter
Counter + 1
sources · none
data point · int
Counter
0
value · still 0
still no connections · nothing is watching anything yet
05 · the cron ticks

The cron fires every 5 seconds. Nobody is watching.

Here's what the cron node looks like in the Krill app — schedule, next fire time, last fire time. It's been running this whole time. Every 5 seconds it emits a "tick" event.

And every 5 seconds… nothing happens. The tick fires into empty air. The counter stays at 0. Other systems would call this a missed signal. In krill, it's just the default state: no node reacts to anything until it explicitly says it wants to.

The key idea: nodes pull, they don't push.

The cron doesn't push to anyone. It just announces "I ticked". Other nodes have to opt in to hearing about it. This is the observer model — and it's what makes large krill graphs predictable.

cron · every5s live
cron timer node project · home
every5s
*/5 * * * * *
every 1s every 5s every minute hourly cron…
past 30s · marks = fires
fires: 0 · events delivered: 0
06 · the calc starts listening

Tell the calc: watch the cron.

Open the calc node and add every5s as one of its sources. That's it. Now the calc cares about the cron — when the cron fires, the calc wakes up, evaluates its formula, and produces a result.

Counter + 1 evaluates to 1. The calc has a fresh output value.

But notice what didn't happen: the Counter still shows 0. The calc has produced a result, but nothing is writing it anywhere. The calc can read from the Counter to evaluate its formula — that's just a reference. It doesn't mean the Counter is listening back.

concept · sources

Every node has a list of nodes it's subscribed to. When one of them changes or fires, the node re-evaluates. The list is explicit — you add things to it on purpose.

project · home › nodes 1 connection
cron timer
every5s
⏲ 5s
fired · 0 times
calculation
bumpCounter
= 1
sources · every5s
data point · int
Counter
0
value · still 0 · no writer
calc runs · but counter still doesn't observe the calc
07 · the counter starts listening

Tell the counter: watch the calc.

Last connection. Open Counter and add bumpCounter as one of its sources. Now the Counter cares when the calc produces a value — and ingests it.

Watch what happens. Every 5 seconds the cron fires. The calc wakes up, reads Counter, evaluates Counter + 1. The Counter is now listening, so it absorbs the result — and becomes that new value. Then 5 seconds later the cron fires again, the calc reads the new Counter, adds 1, writes back. The Counter increments.

That's krill. Three nodes, two wires, a self-incrementing counter — and a mental model that scales to rooms full of sensors, actuators, and logic.

You now understand node observers.

Reading from a node is free. Reacting to a node is opt-in. To make A respond to B, you add B as a source of A. Always. That's the whole rule.

project · home › nodes 2 connections · live
cron timer
every5s
⏲ 5s
fired · 0 times
calculation
bumpCounter
= 0
sources · every5s
data point · int
Counter
0
sources · bumpCounter
wired · cron → calc → counter · ticks once every 5s
recap · the whole graph

Three nodes. Two wires. One rule you now know.

Every krill graph — from a single counter to a greenhouse full of sensors — is built the same way. Add nodes. Tell each one what to listen to. Let the swarm do the rest.

cron timer
every5s
fires · independently
calculation
bumpCounter
observes · every5s
data point · int
Counter
observes · bumpCounter
cron timer · scheduler calculation · expression data point · value arrows show "watches", not data flow

The vocabulary you just picked up

You now know the four words that show up in every krill discussion:

node — anything in the swarm. Data points, cron timers, calcs, sensors, GPIO pins, alerts — all nodes.
source — a node that another node has opted into listening to. The directed edges of the graph.
fire / change — when a source emits, its dependents re-evaluate. Cron fires; data points change.
graph — the picture above. Your whole project is one. Composing it is the whole job.