SDKs and languages

The repository has two optional helpers in sdk/, one file each with no dependencies. Copy the file next to your program.

Python

sdk/python/nook.py works with Python 3.8 and later.

python
import nook

app = nook.Plugin()
tasks = app.load("tasks", [])              # JSON in NOOK_DATA_DIR

def draw():
    app.tile(nook.row([nook.ring(0.3, label=str(len(tasks))), nook.text("Tasks")], align="center"))
    app.page(nook.column([
        nook.text_input("new", hint="Add a task"),
        nook.list_view([nook.item(str(i), t) for i, t in enumerate(tasks)]),
    ], scroll=True))

@app.on("new")
def add(e):
    if e["kind"] == "submit":
        tasks.append(e["value"]); app.save("tasks", tasks); draw()

@app.every(60)
def tick(): draw()

draw()
app.run()

It has a builder for every component (column, row, text, ring, button, canvas, …), canvas shapes (rect, circle, arc, label, glyph), badge_ring, badge_glyph, badge_pulse, show, copy, open, load and save, plus poll_event() for poll mode.

Node.js

sdk/node/nook.js works with Node 18 and later.

js
const nook = require("./nook");
const app = new nook.Plugin();
let on = false;
const draw = () => app.setTile(nook.row([
  nook.icon("lightbulb", { fill: on, color: on ? "yellow" : "dim" }),
  nook.spacer(),
  nook.toggle("light", on),
], { align: "center" }));
app.on("light", (e) => { on = e.value; draw(); /* call your smart-home API here */ });
draw();

Any other language

There's nothing else to it. Read lines from stdin, write lines to stdout, and flush after each line.

  • Flush after every line. In C, Go, Rust or C#, flush stdout yourself.
  • Write UTF-8, one JSON object per line, with no newlines inside the object.
  • stderr goes to Nook's log, and its last lines appear on the tile if your plugin stops. Use it for debug prints.
  • A compiled plugin can include its binary: run = ["bin/my-plugin.exe"].
go
out := bufio.NewWriter(os.Stdout)
send := func(v any) { b, _ := json.Marshal(v); out.Write(append(b, '\n')); out.Flush() }
send(map[string]any{"type": "tile", "view": map[string]any{"type": "text", "text": "Hi from Go"}})
sc := bufio.NewScanner(os.Stdin)
for sc.Scan() { /* json.Unmarshal(sc.Bytes(), &msg) … */ }