Getting started
Install the runtime, start it, and open the Manager — the front door where every project on this installation lives. Pick the install path that fits where you are in the lifecycle.
Choose how to run it
All three paths run the same server against the same kind of project folder. Move between them freely.
- From source — For developing. Hot reload for both the runtime and your custom widgets.
- From Docker — For servers. One command brings up the server and the example project — pull the image, or download the offline installer zip from the release and run its
install.sh. - Portable zip — For panel PCs. Unzip a self-contained Mac, Windows or Linux build and start it.
# 1 · From source (dev, hot reload)
$ python start-dev.py
# 2 · From Docker (server)
$ docker run -d -p 8000:8000 -p 8443:8443 -v nexthmi-data:/data ghcr.io/mpnvdlee/next-hmi:latest
$ ./install.sh # or: the offline installer zip
# 3 · Portable build (macOS; nexthmi.exe on Windows, ./nexthmi on Linux)
$ ./nexthmi.command
→ NEXT HMI running on http://localhost:8000
First run, step by step
- Start the server — Run one of the commands above. On first launch it creates its runtime home — a per-installation folder (default
~/Documents/NextHMI/, or whereverNEXTHMI_DATA_DIRpoints) that holds the project manifest, logs, and the widget build cache. - Open the Manager — Browse to
http://localhost:8000. The Manager lists every project registered on this installation and lets you start, stop, open, transfer and remove them. - Set the device-admin password — On a fresh installation the Manager asks you to choose one, and asks for it on every later visit. The first time it also asks for the setup code the server printed when it started: in the terminal window, or with Docker in
docker logs nexthmi. This gate gets you into the dashboard; it is separate from the per-project operator accounts you define later. - The default project is already running — The install creates one for you, a blank project with a single page, and starts it during that same first launch, so its row shows Running rather than a Start button. It needs no credential of its own. Stop and Start are on the row whenever you want to take it down and bring it back.
- Open its editor — Press Open editor to land under
/editor/<project>/— or read Managing projects to create your own first.
Want something already built instead? Click + New project and pick the NEXT BREW example template — see the tour below.
Three URL areas to know. localhost:8000 is the Manager. A running project's operator runtime is under /runtime/<project>/, and its editor is under /editor/<project>/ — with one path per config area beneath it (/editor/<project>/datasources, /editor/<project>/theme, …).
Take the tour: NEXT BREW
The fastest way to see how the pieces fit is to read a project that already works. + New project → NEXT BREW example gives you a demo brewery — three pages plus a Dialogs folder (an about dialog, a sign-in dialog and a five-page guided brew wizard), a static datasource, alarms, recipes, two themes and two languages — with nothing to wire up first.
Open its runtime and try the things that are hard to picture from a description:
- Sign in. The header carries a Sign in button (how it is built). The sign-in dialog lists the project's users in a dropdown, and the demo accounts are printed on the dialog itself —
brewer/espresso(in theadmingroup) andbarista/latte(an operator). - Watch the Machine page change. Signing in as
breweris not cosmetic. The setpoint steppers become operable — they are Interactable gated on theadmingroup — and a Service card appears that was hidden entirely, gated on Visible. While you are a guest, a caption sits in the card's place naming what is missing and why, so the mechanism is legible before you unlock it. Sign in asbaristainstead and neither unlocks: an operator is not inadmin. - Sign out again with the sign-out button beside your name, and watch both go away.
That is the whole of users, groups and permissions in one screen. Then open the editor on the same project and look at how it was done — the gates are properties in the Visibility group, not code.
The example's onHmiLoaded global event writes starting values into its
datasource on load. If you repoint it at a real server, read that event
first — see Global events.
Build your first screen
Ten minutes, no PLC needed. A Static Variables datasource stands in for the machine: its variables start at zero and hold whatever the HMI writes to them, so buttons, bindings and actions behave exactly as they will against a real server. Swap in an OPC-UA connection later and the screen you built here keeps working.
Work through it in the editor you opened above.
1 · Create the stand-in data
- Open the Datasources area — Pick Datasources in the editor's left rail.
- Add the datasource — Click the
+on the Datasources row and choose Static Variables. Name itDemoand confirm. That name is the prefix of every binding you write next (Demo:…). - Add a variable — Right-click in the empty variable table and pick Variable. Fill the row in:
- Display Name
Speed - Data Type
Float - Access — writable
- Display Name
- Add a second one — Right-click again → Variable: Display Name
Running, Data TypeBoolean, writable. - Watch the values — Toggle ⚡ Live in the toolbar. A Value column appears, showing what each variable holds right now —
0andfalseuntil something writes to them.
2 · Make a page
- Open the Editor area — Pick Editor in the left rail. The page tree appears.
- Add a page — Click the
+on the Pages section row. - Name it — Set the page title to
Line overviewin the properties panel on the right.
3 · Show a live value
- Add a Label — Right-click the page in the tree → Add Widget/Component… → pick Label in the picker.
- Bind its text — With the Label selected, find Text in the properties panel and click its source pill (the small square left of the field). Choose Variable.
- Pick the tag — In the variable picker choose
Demo→Speed. The canvas immediately shows0— that is the subscription running.
4 · Write back with a button
- Add a Button — Right-click the page → Add Widget/Component… → pick Button. Set its Label to
Start. - Give it an action — In the Button's Actions field, add an action and pick Write Data Variable.
- Point the write at the tag — Pick the action's Variable with the variable picker:
Demo→Running. Set Value totrue. Add a second Button labelledStopwritingfalseto the same tag.
5 · React to the value
- Add a Status Pill — Right-click the page → Add Widget/Component… → pick Status Pill.
- Make its text conditional — Set Text's source to If Condition. For the condition pick Comparison: left side a Variable (
Demo:Running), operator===, right sidetrue. Fill the true value withRunningand the false value withStopped. - Do the same for the tone — Set Tone the same way:
okwhen true,neutralwhen false. (Those are the pill's tone values —accent,neutral,ok,warn,fault.)
6 · Try it, then save
- Switch the canvas to Test mode — In the preview toolbar, the Mode control has two buttons: the pencil is Config mode (clicks select widgets), the play button is Test mode (clicks run actions). Pick Test mode.
- Press Start — The pill flips to Running. Press Stop and it flips back. The write went through the server to the datasource and came back to every subscriber, exactly as a PLC write would.
- Save —
Ctrl/Cmd + S. The project files are written to disk. An open live view shows the change after a browser reload.
You now have the whole loop: data in, a screen that reads it, a control that writes it. Where to go next — Adding & arranging widgets for the rest of the catalog, Dynamic properties for what else a field can be bound to, and Connecting to data when you're ready to point at a real PLC.