Arduino App Studio for VS CodeRun the Arduino UNO Q apps you build with blocks — in plain VS Code.
Design an Arduino App Lab app with drag-and-drop blocks in Blocks Editor, then build, launch and monitor it here, without leaving the editor. This extension is the run half of that workflow: Blocks Editor writes the app, Arduino App Studio puts it on the board and shows you what it's doing. Hand-written apps work exactly the same way — blocks are optional.
It's "just another Arduino CLI" by design. Arduino ships official command-line
tools — The UNO Q is a dual-brain board: a Linux CPU that runs Python apps (in Docker) and an Arduino MCU that runs C++ sketches. An app bundles both halves plus reusable bricks and optional AI models — and your files stay plain files on disk, edited with VS Code's native editor. Why you'll like it
Getting startedStep 1 — Set up
|
| Area | What you get |
|---|---|
| Apps | New / Run / Stop / Restart / Delete, Console (logs), Export / Import, Copy & Edit (examples), Set Default, Open Exposed Port |
| Bricks | Browse the catalog, add to an app, configure variables, rename, remove |
| Models | List, import an Edge Impulse project, delete, view details |
| Sketch (MCU) C++ libraries | Search the Arduino catalog and add/remove per-app libraries |
| Serial monitor & plotter | A terminal over the daemon WebSocket with line-ending control and log save, plus a live data plotter (fed by the serial monitor or the Python output) |
| IntelliSense | One Configure IntelliSense command sets up both halves (see below) |
| System | Version, configuration, properties, system update, cleanup, network mode, keyboard, board name |
| AI assistant | One command installs a Claude/Copilot skill describing the CLI |
The Run / Stop / Console / Serial Monitor controls are app-scoped: they act
on whichever app owns the file you're editing (resolved by the nearest app.yaml),
and also appear on each app in the tree, in the editor toolbar, and the status bar.
Plotting data
Open data plotter charts live numbers streaming from your app. When you open it, you choose the source — Serial Monitor (the MCU's serial output) or Python output (the app's CPU-side logs) — so the same telemetry format works whichever half of the board is producing the numbers.
It speaks a subset of the Teleplot serial
protocol, so the same Serial.print lines that work with the Teleplot tool work
here too.
The rule: a line is plotted only if it starts with a > marker. Every other
line is treated as ordinary log text and ignored by the plotter (so you can keep
printing human-readable messages alongside your data). A trailing newline ends
each message.
Formats
The general shape of a telemetry line is >name[:timestamp]:value[§unit][|flags]:
| Line | Meaning |
|---|---|
>name:value |
One point on series name, timestamped on arrival |
>name:timestamp:value |
One point with an explicit millisecond timestamp |
>name:value§unit |
A point carrying a unit (shown in the legend) |
>name:t1:v1;t2:v2;t3:v3 |
Several points for one series in a single line |
>name:x:y\|xy |
One XY scatter point (plot x against y) |
>name:x:y:timestamp\|xy |
An XY point with an explicit millisecond timestamp |
>name:text\|t |
A text/log value — shown as a labelled card, not plotted |
nameis the series label — points sharing a name are drawn together.value,x,ymust parse as numbers (integer, decimal, negative, or scientific, e.g.42,23.5,-33.8,1.2e3). A non-numeric value is dropped — unless the|tflag marks it as text.timestampis milliseconds (e.g. frommillis()); when omitted, the point is stamped with the time it arrives in VS Code.§unit(a§after the value) labels the series with a unit, e.g.°C.;separates several points for the same series in one line — handy for batching or replaying buffered samples.- The
|xyflag marks a scatter point; the|tflag marks a text value.
This is a subset of Teleplot: 3D shapes (3D|…) and remote function calls are
not supported.
Examples
From the MCU (C++) side, plot a single time series:
void loop() {
float temp = readTemperature();
Serial.print(">temp:");
Serial.println(temp); // → >temp:23.5
delay(100);
}
From the Python side, the same line plots when you point the plotter at the Python output:
print(f">temp:{temp}") # → >temp:23.5
Attach a unit (appears in the legend), plot an XY point, or show a text status:
Serial.println(">temp:23.5§°C"); // unit
Serial.println(">pos:12:8|xy"); // XY scatter point
Serial.println(">state:Running|t");// text card, not plotted
Tip: mix freely. Lines without a leading
>still show up in the Serial Monitor (or the Console) but are skipped by the plotter, so a single app can log status text and stream plottable data on the same stream.
IntelliSense (code completion)
One Configure IntelliSense command sets up both halves of an app:
- C++ (MCU): writes
.vscode/c_cpp_properties.jsonfrom the sketch's last build (the compilation database under<app>/.cache/sketch/), so Microsoft's C/C++ extension resolves the Arduino core, board defines, and libraries. - Python (CPU): writes
.vscode/typings/arduino/**stubs and pointspython.analysis.stubPathat them, so Pylance resolvesarduino.app_utils/arduino.app_bricks.*— which otherwise live only in the app image.
Both refresh automatically after each successful run
(appLab.intellisense.autoConfigure, on by default).
Settings
You can leave everything at its defaults. To tweak, open Settings and search for "Arduino App Studio" (or App Lab):
| Key | Default | Description |
|---|---|---|
appLab.daemon.host |
127.0.0.1 |
Daemon host. |
appLab.daemon.port |
8800 |
Daemon port (on-board systemd service). |
appLab.cliPath |
arduino-app-cli |
CLI binary, used for CLI-only commands (clean-cache, system init/cleanup/…). |
appLab.apiKey |
"" |
Optional X-API-Key header. |
appLab.monitor.lineEnding |
lf |
Serial monitor line ending. |
appLab.logs.tail |
200 |
Lines requested when opening a console. |
appLab.intellisense.autoConfigure |
true |
Refresh IntelliSense (C++ config + Python stubs) automatically after each successful run. |
Works great with Blocks Editor
Blocks Editor
(linucs.blocks-editor) is the other half of the story. It's a visual,
Scratch-like editor that lets you build programs by dragging blocks instead of
typing — and for an Arduino App Lab app (app.yaml) it generates real Python
under the hood.
But generated code is just a file until something runs it — and that's where this extension comes in. Blocks Editor writes the app; this extension's Run button builds it, flashes the MCU sketch, starts the Python side, and streams the output back. Together they're a complete loop: drag blocks → run → watch the console and plotter. Drawn as a picture:
Blocks Editor Arduino App Studio Arduino UNO Q
drag blocks ──► generates the app ──► run (build + ──► MCU + Python
flash + start) run together
console / plotter ◄── logs & data
Each one is fully standalone, so you can use either alone — but they're designed to be two halves of one workflow: Blocks Editor builds, this extension runs. The same pairing exists for plain sketches via Arduino Sketch Studio.
Requirements
- VS Code 1.120+.
- An Arduino UNO Q running the
arduino-app-clidaemon. - Reaching the board over Remote-SSH (recommended) or a tunnel to its daemon.
- For C++ IntelliSense: Microsoft's C/C++ extension. For Python: Pylance.
Good to know
- It stays out of your way. This is a thin wrapper: it drives the same
arduino-app-clidaemon the Arduino App Lab GUI uses, rather than reimplementing the build/run logic. What runs here is what runs there. - Your files are the source of truth. Apps are plain folders on disk
(
app.yaml,python/main.py,sketch/sketch.ino, bricks, models) — edit them with VS Code's native editors, version them with git, no proprietary project format. - Built to run alongside Remote-SSH. Because it talks to a local daemon, the extension is happiest running on the board next to the daemon and your apps.
For developers
yarn install
yarn compile # type-check + lint + l10n gate + bundle
yarn test # SSE parser + mock-daemon transport tests
yarn vsix # build a .vsix
The transport core (src/appLabClient.ts, src/sseParser.ts, src/daemon.ts)
has no VS Code dependency and is unit-tested against a mock daemon. See
PUBLISHING.md for the release process.
Community
Questions, ideas, or just want to show what you built? Join the GitHub Discussions.
Contributing
Contributions and bug reports are welcome — open an issue or pull request on the repository.
