FrameOS
Guide

Editing scenes

Build scenes visually with the node-based editor - events, apps, data sources and state.

A scene is what a frame shows: a graph of connected nodes that runs on the device. Scenes are built in a visual editor, then deployed onto the frame, where it runs.

Self-hosted backend, FrameOS Cloud and standalone frames

The same editor ships in the self-hosted backend, in FrameOS Cloud, and on a standalone frame's own admin page. Everything here works in all three, except compiled scenes, which need the self-hosted backend.

Create a scene

Click + Add new scene, give it a name, and open the editor.

Creating a new scene

The four node colors

  • 🟥 Red - events. Entry points that trigger execution. The most important one is render, which fires at a set interval (every 60 seconds, every hour, whatever you choose). Others react to button presses, schedules, or custom events.
  • 🟦 Blue - render apps. Draw things: images, text, calendars, gradients, split layouts.
  • 🟩 Green - data apps. Fetch and transform data: download an image, query Home Assistant, parse an iCal feed, generate an image with OpenAI, take a screenshot of a web page.
  • 🟨 Yellow - state fields. User-editable values (text, numbers, options) that can be changed live from the control page without redeploying.

Drag from the render event's connector to add a blue Render image app:

Adding a render app

Then drag its image field out and pick a green data app to feed it - use FrameOS Gallery if unsure. Press deploy:

Adding a data app

Caching

Every data app has cache controls. A scene might re-render every minute while its data app only fetches a new image every 15 minutes - the cached value is reused in between. And if a re-render produces the same image as before, an e-ink display won't refresh at all: no unnecessary flashing.

Cache controls

State fields

Add a yellow state field under the scene's "State" tab, then drag it onto the canvas and wire it into any app input. Deploy once, and from then on you can change the value live - from the frame's control page, the backend, or the HTTP API.

Adding a state field

Editing state live

Fields are typed, and the type decides what the control page shows: text, long text, numbers, booleans, a colour picker, a date picker, a select box, raw JSON, a font picker, an image, a scene picker - or a path, which is a file and folder browser over the frame's own assets. "Which photo folder should this play?" becomes a picker instead of a typed-in string.

Code nodes

For quick data plumbing there are inline code nodes (green when not selected): single JavaScript or TypeScript expressions that combine or transform values mid-graph - string concatenation, math, formatting. (In an older compiled scene they are Nim expressions instead.)

Code nodes

How scenes run

Scenes are interpreted: the frame runs the graph as you drew it. New scenes are created that way, every scene FrameOS ships is built that way, and it's the only way ESP32 and Pico frames can work at all. What you get:

  • Deploys are near-instant - nothing is recompiled, so a change is on the frame in seconds.
  • Code nodes are JavaScript, TypeScript or JSX, and apps can be customised in JavaScript.
  • It costs a little more per render, which matters very little on a display that takes 20 seconds to refresh anyway.

There is a second, older mode - compiled - which turns the scene into native code inside the frame's binary. It's faster per render and it's the only mode that can run custom Nim app source and Nim code nodes, but every change needs a full rebuild and redeploy, and it only works on a Raspberry Pi deployed from a self-hosted backend - the cloud only pushes interpreted scenes.

Compiled scenes are on the way out

Scenes made before the switch may still be set to compiled, and you can still choose it under a scene's settings on a Pi frame. It is not where FrameOS is heading, though - build new scenes interpreted unless you specifically need Nim. If you switch an existing scene between modes, do a full deploy afterwards; the editor warns you when a scene still contains Nim source that interpreted mode can't run.

On the frame side there are two ways a binary gets built: precompiled (the release binary plus its driver libraries, scenes interpreted - the default) and static (everything compiled into one binary, which is what a compiled scene forces). Frames still configured with the retired shared or shared-scenes modes are moved to static automatically.

Preview before you deploy

Two ways to see a scene without committing to it:

  • Preview in browser runs the scene in your browser. The frame's renderer is compiled to WebAssembly, so you get the real thing - same apps, same layout engine, same resolution - without deploying to a device, or before you own one.
  • Preview on frame temporarily shows the scene on the actual frame without saving or deploying it. Good for checking how a colour dithers on real e-ink.

How to learn

FrameOS ships with many sample scenes. The fastest way to learn is to install them, open them in the editor, and poke around.

Sample scenes in the editor

When the visual editor isn't enough, write your own apps - in Nim or JavaScript. Editing apps is next.

On this page