VS Code extension to run Arduino CLI from the command palette, status bar, and an Explorer view. It streams colored logs to a pseudo terminal, supports sketch.yaml profiles, and updates IntelliSense includePath during builds.
The Explorer view keeps sketches, profiles, and common actions together so you can launch tasks with a click.
This extension brings the Arduino CLI—normally invoked under the hood of the Arduino IDE—into VS Code so you can reach feature parity (and more) without leaving your editor. By leaning on Arduino CLI profiles, you can pin different versions of platforms and libraries per project through sketch.yaml, something that is hard to maintain inside the IDE alone. The helper UIs guide you through editing those profiles and even compare them with the latest releases to suggest upgrades.
Because you are already working inside VS Code, the extension connects build results with the Microsoft C/C++ extension: include paths, IntelliSense, diagnostics, and the generated compile_commands.json all stay in sync with each compile. You also get a workspace-focused warnings mode that filters out noise from third-party cores (addressing the IDE’s none default), plus exclusive utilities such as the ESP32 data uploader and the Inspector for analysing map and artifact files.
The goal is to make Arduino CLI approachable for beginners while unlocking the advanced workflows—multiple dependency versions, rich IntelliSense, and build automation—that seasoned users expect.
- Install Arduino CLI
- Put it in
PATHor set a full path in the settingarduino-cli-wrapper.path. - Confirm with "Arduino CLI: Check CLI Version" (a guide appears if not configured).
- Windows: installer https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.msi or
winget install ArduinoSA.CLI - Linux:
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh - macOS:
brew update && brew install arduino-cli- See the official installation guide for additional options: https://arduino.github.io/arduino-cli/latest/installation/
- Windows: installer https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.msi or
This extension declares an extensionPack so you can pull in the supporting tooling with one click. Install the extensions that match your workflow:
- C/C++ (ms-vscode.cpptools) – Delivers IntelliSense, navigation, and the default
cppdbgdebugger. It is part of a standard C/C++ environment, so we strongly encourage having it installed alongside this wrapper. - Cortex-Debug (marus25.cortex-debug) – Adds advanced hardware-debug tooling such as register, peripheral, and memory views. Recommended when you rely on the debugger; optional if you only need lightweight or no debugging.
- Open a sketch folder
- When a folder contains
.ino, the status bar shows Compile/Upload/Monitor plus FQBN/Port/Baud/Warn.
- Compile / Upload / Monitor
- Build: run "Arduino CLI: Compile Sketch" or click Compile.
- Upload: run "Arduino CLI: Upload Sketch" or click Upload. Select the serial port first; the extension passes
-pexplicitly even when using profiles. - Monitor: run "Arduino CLI: Monitor Serial" or click Monitor. Baudrate defaults to 115200 and can be changed from the status bar.
- Need a serial plotter? Install a VS Code extension such as Teleplot or any preferred tool.
Tips:
- If multiple
.inofiles exist, a picker appears to choose one. If an.inoeditor is active, it is preferred. - If the FQBN cannot be inferred, you can enter one manually.
When an .ino file contains #include "arduino_secrets.h" the editor now shows an inline action directly above the include. Click it to open the secrets header if it already exists, or generate it on the spot when missing. The generator copies any fallback #define lines from the sketch's #else block so the new header starts with the same defaults, helping you move Wi-Fi credentials into an untracked file with a single click.
If Arduino CLI builds feel slow on Windows, you can offload compilation to a Linux environment by using WSL (Windows Subsystem for Linux). This extension automatically detects that you are running inside WSL, uses the Linux arduino-cli for compile tasks, and still relies on arduino-cli.exe on Windows for upload/monitor so you do not have to configure serial ports twice. Follow the steps below.
-
Install WSL and a Linux distribution
# PowerShell (Admin) wsl --update wsl --install -d Ubuntu-24.04 wsl --set-default-version 2
Complete the first boot prompt by setting your Linux username and password. Skip this step if you already have WSL installed.
-
Set up Arduino CLI inside WSL
# Inside your WSL terminal (Ubuntu) sudo apt update curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh arduino-cli config init arduino-cli update
Verify with
arduino-cli version. -
Connect VS Code to WSL
- From the command palette select Remote-WSL: New Window, choose Ubuntu, and let VS Code reopen in WSL mode.
- Install this extension in the WSL environment when prompted.
- Leave
arduino-cli-wrapper.pathempty to auto-detect/usr/local/bin/arduino-cli, or set the full path explicitly if you prefer.
-
Compile on Linux
- Open your sketch folder while connected to WSL and run Arduino CLI: Compile Sketch. Linux-side build outputs (e.g. under
/home/<user>/.arduino15/) are created automatically.
- Open your sketch folder while connected to WSL and run Arduino CLI: Compile Sketch. Linux-side build outputs (e.g. under
-
Upload / Monitor stay on Windows
- When you trigger Upload or Monitor, the extension switches to
arduino-cli.exeon Windows, connecting toCOMports directly. No extra serial configuration inside WSL is required.
- When you trigger Upload or Monitor, the extension switches to
-
Upload Data and Debug notes
- Upload Data now bridges both sides automatically: the filesystem image is built inside WSL, yet when a Windows
COMport is selected the extension rerunsarduino-cli.exe --show-propertiesplusesptool.exeon Windows to program the board—nousbipdforwarding is required as long asarduino-cli.exeis on the Windows PATH. Arduino CLI: Debugstill cannot access Windows-hosted serial ports from WSL. Either forward the USB device into WSL withusbipd-win(so it appears under/dev/tty*) or run Debug from Windows instead.
- Upload Data now bridges both sides automatically: the filesystem image is built inside WSL, yet when a Windows
-
Troubleshooting tips
- Seeing
Latest arduino-cli: (unknown)usually means the GitHub API rate limit was exceeded. SetGITHUB_TOKENin your environment or retry later. - If a
COMport does not appear, confirm that Windows detects the board in Device Manager and reinstall drivers when necessary.
- Seeing
With this hybrid setup you get the best of both worlds: fast Linux-based builds and seamless serial access through Windows.
If you must inject extra build.extra_flags on every compile, you can place an .arduino-cli-flags file next to the sketch. This feature is unique to Arduino CLI Wrapper and other IDEs or extensions will ignore it, so we recommend managing secrets and overrides via arduino_secrets.h or standard configuration first. Treat it as an advanced escape hatch for experienced users who already understand the build pipeline.
- Write one flag per line, for example
-DWIFI_SSID="MySSID". - Lines starting with
#or//, as well as blank lines, are ignored. - The remaining flags are joined with spaces and passed as a single
--build-property build.extra_flags=...argument. - If you already provide
build.extra_flagsvia settings, tasks, or the command palette, that configuration takes precedence and the file is skipped.
Because the filename starts with a dot it stays hidden by default. Add it to source control ignore lists (the extension’s .gitignore already contains an entry) so credentials never leak into commits.
In addition, the extension injects the following preprocessor macros by default so sketches can consume the build host’s timezone without touching .arduino-cli-flags. Disable Arduino CLI Wrapper › Inject Timezone Macros if you prefer to manage these flags yourself.
CLI_BUILD_TZ_IANA– IANA timezone identifier such asAsia/Tokyo.CLI_BUILD_TZ_POSIX– POSIX expression suitable for newlib’sTZ(e.g.JST-9orPST8PDT,M3.2.0/2,M11.1.0/2).CLI_BUILD_TZ_OFFSET_SEC– Current UTC offset in seconds.CLI_BUILD_TZ_OFFSET_ISO– ISO-style offset string such as+09:00.CLI_BUILD_TZ_ABBR– Short label for UI surfaces, for exampleJSTorPST/PDT.
Press Ctrl+Shift+P (or Cmd+Shift+P on macOS) and type “Arduino CLI:” to see the most common commands. Highlights:
- Open Command Center – Launches the dedicated webview with three tabs: a command overview, a configuration view for
arduino-cli config, and management panels for cores and libraries (complete with install/update/uninstall buttons and filters). This is the fastest way to explore everything the extension exposes. - Check CLI Version – Confirms that
arduino-cliis installed and reachable. If it is missing, the extension shows a friendly setup guide. - Update Index – Runs
arduino-cli updateto refresh board and library metadata. The command also runs automatically the first time you check the CLI version during a VS Code session. - Upgrade Cores/Libraries – Executes
arduino-cli upgradeso installed platforms and libraries pick up the latest releases from the refreshed index. - Board Details – Shows the technical info for the currently selected profile/FQBN, making it easy to verify you picked the right board package.
- Compile Sketch / Clean Compile / Upload Sketch – Everyday build and upload automation. Clean Compile rebuilds with
--clean, refreshing IntelliSense include paths so swapped libraries or platforms are reflected immediately. - Build Check – Runs through every profile declared in
sketch.yaml, compiling each with full warnings and presenting a consolidated summary of errors and warnings. - Debug Sketch – Generates profile-aware debug assets; see “Debug your sketch (advanced)” for the full walkthrough before running it the first time.
$(tools) Compile: compiles the.inoin the current workspace folder$(cloud-upload) Upload: uploads the.inoin the current workspace folder$(pulse) Monitor: opens the serial monitor$(circuit-board) <FQBN/Profile>:- Shows the profile you last selected via "Arduino CLI: Set Profile" or the Arduino CLI tree. If no profile is recorded but any
sketch.yamlexists, it displaysProfile: Not setand opens the profile picker. When no profile-enabled sketches are found, it falls back to the current FQBN and lets you change it via "Arduino CLI: Set FQBN".
- Shows the profile you last selected via "Arduino CLI: Set Profile" or the Arduino CLI tree. If no profile is recorded but any
$(plug) <Port>: shows current serial port (click to change). Pick External programmer (JTAG/SWD/ISP) when you flash through a dedicated programmer so uploads skip passing-p.$(watch) <Baud>: shows current baudrate (click to change)$(megaphone) <Warnings>: shows compile warnings/verbose badge (click to pick combinations)
Status bar items are hidden when the workspace has no .ino files. FQBN/Port/Baud are stored per workspace and persist across restarts.
- Adds an "Arduino CLI" view under Explorer.
- Lists detected sketch folders; shows profiles from
sketch.yamlwhen available. - Per project/profile actions: Compile, Upload, Debug, Upload Data, Monitor, Sketch.yaml Helper, Open Examples.
- Debug appears on profile nodes only so you can launch the generated debug configuration for the selected profile in one click.
- Global actions at the top: Command Center, CLI Version, Sketch.yaml Helper, Open Inspector, Sketch.yaml Versions, Build Check, Refresh View, New Sketch.
- Sketch items display workspace-relative paths, and nodes are expanded by default.
- Compile Sketch – Builds the selected sketch. If the folder contains several
.inofiles, a picker helps you choose the right one. Profiles fromsketch.yamlare applied automatically; otherwise the saved FQBN is used. - Clean Compile – Runs the same build with
--clean, resets IntelliSense include paths, and is handy when switching libraries or boards. - Local Build Path (setting) – Turn on Arduino CLI Wrapper › Local Build Path to pass
--build-pathautomatically and store build outputs in.build/<profile>under each sketch, keeping artifacts local for Compile, Upload, Inspector, and more. - Upload Sketch – Compiles and uploads in one go. You will be prompted for a serial port if one is not already selected, and the monitor is closed/reopened as needed so the port stays free.
- OTA uploads (network ports) – If the selected port looks like an IP address, the extension assumes an OTA transfer and injects
--upload-field password=$ARDUINO_CLI_OTA_PASSWORD. The actual CLI call expands the environment variable (leave it empty when no password is required) while the Arduino Logs channel keeps the literal$ARDUINO_CLI_OTA_PASSWORDstring so credentials never appear in clear text. - Build Check – Compiles every profile defined in
sketch.yamlwith full warnings (--warnings all), then shows a summary of warnings and errors so you can spot regressions quickly. - Run in Wokwi – When a
sketch.yamlprofile setswokwi: true, compiling that profile exports.wokwi/<profile>/wokwi.elf, scaffolds board-aware defaults fordiagram.json/wokwi.toml, and adds a "Run in Wokwi" action that opens the diagram in the official simulator extension.
- Sketch.yaml Helper – Opens a helper view where you can review or update board packages, platforms, and libraries without editing YAML by hand.
- Check Sketch.yaml Versions – Audits every profile against the official indexes and offers inline upgrades when newer versions are available.
- New Sketch – Creates a fresh sketch folder, opens the generated
.ino, and launches the helper so you can configure profiles immediately.
Use the Sketch.yaml Helper to edit profiles without touching raw YAML.
See which platforms and libraries have updates pending and apply them in place.
- Browse Examples – Opens a tree of every example sketch exposed by your installed cores and libraries. Unlike the Arduino IDE, you can preview the source before opening it in the editor, switch between the
.ino, README, and other files via tabs above the viewer, and copy the entire example folder into your project with a click. - Filter by name or folder – Use the quick filter box to narrow the list by file or directory names when you already know what you are looking for.
- Search inside sketches – Switch to the built-in grep mode to filter examples by the text they contain (for instance, type
rgbto find examples that manipulate RGB LEDs or look for a specific function call). - Open with one click – Once the preview matches what you need, open it directly in the editor and start adapting it to your project.
Browse, filter, and preview Arduino examples without leaving VS Code.
- Monitor Serial – Opens a serial terminal with selectable port and baudrate (default 115200). Helpful tips appear if the port is busy.
- Configure IntelliSense – Regenerates
.vscode/c_cpp_properties.jsonusing the latest compiler flags without running a build. - Run Command – Lets you pass custom arguments straight to
arduino-cliwhen you need an advanced flag that the UI does not expose. - Inspector – Examines the generated map file, ELF sections, and other build artifacts so you can understand memory usage at a glance. Use the Clean build (--clean) toggle when you need a fresh compile; it defaults to off so quick inspections reuse the existing build.
- Status controls in the status bar – Toggle warning levels (
none,workspace,default,more,all) and the--verboseswitch. The badge (for exampleall+V) updates instantly. - Include Order Lint – Watches
.inofiles and warns if filesystem headers appear before M5GFX headers, catching a common runtime pitfall. - Local Port Rules – Open the wizard from Command Center, the Arduino CLI explorer header, or the command palette entry “Local Port Rules” to edit
.vscode/arduino-cli-wrapper.json. Define ordered glob rules (workspace-relativesketchandprofileglobs) with a requiredportand optionalbaud; rules are matched top-down, and empty fields are omitted on save. Local rules override anyport/baudinsketch.yaml, keeping per-developer port choices out of version control.{ "ports": [ { "sketch": "temp/assetsTest/**", "profile": "*", "port": "COM7", "baud": 921600 }, { "profile": "esp32-*", "port": "/dev/ttyACM0", "baud": 921600 }, { "sketch": "temp/test/**", "port": "/dev/ttyUSB0" } ], "defaultBaud": 115200 }
Run the Inspector after a build to review memory usage and section breakdowns.
All command logs are unified in a dedicated pseudo terminal with ANSI colors so you can follow the exact CLI invocation.
- Requires a
data/folder under your sketch directory and an ESP32 filesystem include in the sketch (#include <LittleFS.h>or#include <SPIFFS.h>). - Builds an image via
mklittlefsormkspiffsand flashes it withesptoolto the SPIFFS partition. - Reads tool paths and upload speed from
arduino-cli compile --show-propertiesand parsespartitions.csvin the build output to find offset/size. - Closes an open serial monitor before flashing and reopens it after.
- When running inside WSL, the extension automatically captures
arduino-cli.exe --show-propertieson Windows and launchesesptool.exethere whenever the selected port is a WindowsCOM, so you can keep building under Linux while flashing over the native driver stack.
Arduino CLI: Embed Assets is the quickest option: open the Arduino CLI explorer, use the Embed Assets action in the profile section (it appears above Upload Data), drop files under assets/ or any sketch-root folder whose name starts with assets_ (for example assets_wifi/ or assets_ui/), and the extension regenerates <folder>_embed.h with a PROGMEM byte array and length constant for each file. Each header reuses the folder name for the exported arrays and symbols (assets_wifi_file_names, etc.) so multiple asset bundles can coexist. If neither the base assets/ nor any assets_* folder exists yet, the manual action bootstraps assets/ for you; compile-time auto-regeneration continues to skip headers when their source folder doesn't exist so builds no longer recreate them unexpectedly. Add a .assetsignore file inside each assets folder to skip files or directories with gitignore-style rules (e.g., use # comment, foo/, *.psd, **/tmp/**, !important.bin), and the generator will only embed the files you keep. Unicode or symbol-heavy filenames are still embedded; the extension now hashes those paths to create valid, unique C++ identifiers automatically.
Need more control? Drop an .assetsconfig file next to .assetsignore and describe how the folder should be processed using the INI-style sections shown below:
[general]
# Relative directory (from assets/) where the generated header is written
dir = ../
# Filename for the generated header (directory comes from dir)
header_name = assets_generated.h
# Optional symbol prefix; defaults to the folder name
prefix = assets_wifi
[minify]
enable = true ; master switch
html = true ; html/css/js toggles
css = true
js = true
keep_comments = false
write_output_file = false
output_dir = .assets_minified
[gzip]
enable = true
patterns = **/*.html, **/*.css, **/*.js
min_size = 256
suffix = .gz
[stamp]
format = iso, unix
[hash]
algorithms = sha256, md5
dir is resolved relative to the assets folder (blank entries fall back to ../, which targets the sketch root), while header_name only controls the filename. The minifier is lightweight and regex-based—great for trimming whitespace/comments from small bundles, but not a full parser—so keep keep_comments = true if you rely on tricky constructs. If you enable write_output_file, remember to add the specified output_dir to .assetsignore so those intermediate files don’t get embedded on the next run. When gzip is enabled, files that match patterns (glob, comma separated) and exceed min_size bytes are minified first and then compressed; the generated filename appends suffix. Both .assetsconfig and .assetsignore are excluded from the embed output automatically.
The optional [stamp] section emits file timestamps next to every asset: specify format = iso, format = unix, or combine them with commas (e.g., format = iso, unix) to output both arrays. Each format produces a dedicated array (for example assets_wifi_stamp_iso[...]) that matches the existing assets_wifi_file_count length, so you can line up entries with the base assets_wifi_file_names[...] array. Every file also declares individual constants such as assets_wifi_index_html_stamp_iso or assets_wifi_index_html_stamp_unix, and the arrays reference those symbols directly so you can choose whichever style is more convenient. Use [hash] when you need content digests; list any combination of sha256, sha1, or md5 in algorithms and the generator will produce both per-file constants (assets_wifi_index_html_hash_sha256, …) and one assets_<bundle>_hash_<algo>[...] array per algorithm, again aligned with the file list.
The trade-off is size: every embedded byte becomes part of the sketch binary. Large media files make the firmware heavier, so each upload or OTA update takes longer, and you can run into partition limits.
Arduino CLI: Upload Data takes the opposite approach. You upload a filesystem image from data/ once, but afterward the sketch can be rebuilt or flashed without re-sending those files, keeping OTA and serial uploads small. For large or frequently changing assets—especially with OTA workflows—prefer the data image so the firmware stays lean. Reserve Embed Assets for lightweight bundles where the convenience outweighs the extra firmware size.
- Opt-in via a
.sourcebackupconfigfile placed next to the sketch.ino. - Use the
Source Backupaction in the Arduino CLI tree to create.sourcebackupconfigautomatically when the sketch does not have one yet. - Auto-generate
sourcebackup_embed.handsourcebackup_embed.cppbefore compile, similar to the current assets regeneration flow. - Store the backup payload as a compressed
ziparchive in firmware; do not store it as base64. - Emit a single retained blob (
sourcebackup::blob/sourcebackup::blob_len) rather than several unrelated globals, so post-build extraction tools can find it reliably from the binary image. - When
retain = true, the generated.cppalso emits an internal auto-reference object that callssourcebackup::isValid()during static initialization and stores the result in a volatile flag, so link-time garbage collection is less likely to discard the blob even if your sketch never references it directly. - Keep helper functions separate from the retained blob so unused helpers can still be removed by the linker.
- Record only context that the extension already knows at generation time (for example profile, FQBN, port, baud, timestamps, file hashes); it does not launch extra
arduino-clicommands just to enrich the manifest. - Default to a broad include set and let users trim it through exclude rules when firmware size becomes a concern.
- Markdown documents (
*.md) are not included by default because they usually do not affect firmware reproducibility; add them explicitly toinclude.patternswhen you want project notes or READMEs preserved in the backup.
The generated API looks like this:
namespace sourcebackup {
extern const uint8_t blob[];
extern const size_t blob_len;
struct View {
const uint8_t* manifest;
uint32_t manifest_len;
const uint8_t* archive;
uint32_t archive_len;
uint16_t version;
uint16_t flags;
bool valid;
};
bool parse(View& out);
bool isValid();
const uint8_t* manifestPtr();
uint32_t manifestLength();
const uint8_t* archivePtr();
uint32_t archiveLength();
bool writeRawTo(Print& out);
bool writeBlobBase64To(Print& out);
bool writeArchiveBase64To(Print& out);
bool printRestoreUrl(Print& out);
bool writeArchiveBase64WithInfoTo(Print& out);
} // namespace sourcebackupFor field recovery, a startup-time GPIO trigger is often more practical than always printing the archive. For example, you can only emit the backup when a specific pin is held low during boot:
pinMode(kBackupTriggerPin, INPUT_PULLUP);
delay(10);
if (digitalRead(kBackupTriggerPin) == LOW) {
sourcebackup::writeArchiveBase64WithInfoTo(Serial);
}See the companion example project for a full usage sample: https://github.com/tanakamasayuki/vscode-arduino-cli-wrapper-examples/tree/main/03_source-backup
The generated blob uses one fixed header followed by the manifest JSON and the zip payload:
[magic "SRCBAK1\\0" 8B]
[schema_version u16]
[flags u16]
[manifest_len u32]
[archive_len u32]
[header_crc32 u32]
[manifest bytes]
[zip bytes]
[payload_crc32 u32]
Use .sourcebackupconfig to tune the generated files:
dir = ./
header_name = sourcebackup_embed.h
source_name = sourcebackup_embed.cpp
prefix = sourcebackup
[include]
patterns = *.ino, *.pde, *.c, *.cc, *.cpp, *.cxx, *.h, *.hh, *.hpp, *.hxx, *.ipp, *.tpp, *.S, *.asm, sketch.yaml, arduino-cli.yaml, .sourcebackupconfig, .vscode/extensions.json, .vscode/settings.json, data/**, assets/**, assets_*/**
[exclude]
patterns = .git/**, .github/**, .vscode/launch.json, .vscode/tasks.json, build/**, .build/**, dist/**, .sourcebackup/**, sourcebackup_embed.h, sourcebackup_embed.cpp, *_embed.h, *.bin, *.hex, *.elf, *.map, *.o, *.a, *.so, *.d, *.tmp, *.log, .DS_Store, Thumbs.db
[archive]
format = zip
compression = deflate
[embed]
retain = true
progmem = true
align = 4
section = .rodata.sourcebackup
[manifest]
enable = true
include_profile = true
include_fqbn = true
include_port = true
include_baud = true
include_generated_at = false
hash = sha256
[helpers]
emit_parse = true
emit_base64 = true
emit_raw = true- When
sketch.yamlexists, compile/upload use profiles; otherwise FQBN is used.- To bootstrap a
sketch.yaml, use the Helper view to generate a template for your board and libraries, then copy it into a newsketch.yamlin your sketch folder.
- To bootstrap a
- The status bar FQBN indicator switches to a profile name if profiles exist. Use "Arduino CLI: Set Profile" to change it.
- "Sketch.yaml Helper" shows a helper UI to inspect/apply FQBN, libraries, and platform info for a selected profile.
- Profiles with
wokwi: trueautomatically maintain.wokwi/<profile>/wokwi.elf,diagram.json, andwokwi.tomlafter each compile so the Wokwi extension can simulate the latest firmware. The generateddiagram.jsonseeds board-specific layouts (UNO, MEGA, Nano, ESP32 S3 Box, M5Stack CoreS3, Seeed XIAO ESP32 families, and generic ESP32).
- Debug Sketch – Generates matching tasks and launch configurations for each profile by reusing the board’s debugger metadata discovered through Arduino CLI. If Cortex-Debug is installed it launches a
cortex-debugsession; otherwise it falls back to the Microsoft C/C++ debugger withrequest: "launch"already set so the old “select a process to attach” prompt no longer appears.
- Pick the profile and environment. Set the profile you want to debug as the default in
sketch.yaml(or be ready to pick it when prompted) and double-check related settings such as the serial port or Local Build Path so the generated tasks line up with your hardware. - Run “Arduino CLI: Debug Sketch”. Choose the sketch and target profile when prompted. The command produces two artefacts under
.vscode/:
tasks.jsongains Arduino: Debug Build & Upload … so you can flash the firmware with the probe attached. The task honours the Local Build Path setting and the profile’s CLI arguments.launch.jsongains a Cortex-Debug entry (if the extension is installed) and a Microsoft C/C++ fallback. The extension lifts the necessary OpenOCD and GDB settings straight from Arduino CLI output, and the cppdbg variant always sets"request": "launch"to skip the old “select process” prompt. Run this command at least once per profile—the generated files are required before any debug session can start. Re-run it whenever cores, board packages, or tool versions change so the tasks stay in sync with the data discovered from Arduino CLI. While generating these files the extension parsesarduino-cli compile --show-propertiesand related board metadata so the launch settings mirror your CLI environment. Once the files are refreshed the extension immediately runs the Arduino CLI debug build task and launches the matching configuration, dropping you into a halted session without extra clicks—the first breakpoint is Arduino’sthb setup, so you start paused atsetup(). The first run rebuilds every translation unit with debug options, so expect a noticeably longer compile. VS Code might show a dialog such as “Waiting for preLaunchTask 'Arduino: Debug Build & Upload MyProject (debugProfile)'…” (sketch/project and profile names vary); ignore the Debug Anyway button and just wait—once the pre-launch task finishes, the upload completes and the debugger starts automatically.
- Keep configurations fresh. Rerun Arduino CLI: Debug Sketch whenever you change hardware, switch profiles, or update Arduino CLI/tooling—the command regenerates tasks, rewrites launch settings, and starts a new debug session so everything stays aligned.
- Reuse the generated setup. When nothing has changed since the last run, you can start debugging from the Run and Debug view or by pressing F5; both paths reuse the configuration and build output created by the command.
- Customise if needed. You can edit the generated
launch.json—for example to changeoverrideAttachCommands, add semihosting commands, or point to a different SVD file. The wrapper will merge the next regeneration, keeping manual tweaks where possible. If you replace toolchains, rerun the command so it captures the new paths directly from Arduino CLI.
Tips:
- The extension owns the debugger configuration. Each run of Arduino CLI: Debug Sketch parses
arduino-cli compile --show-propertiesand related board metadata, so you never have to maintain debugger arguments manually. - The extension keeps the Arduino Logs terminal in focus during the debug build so you can see OpenOCD output.
- Leaving the probe connected while running Compile Sketch or Upload Sketch is safe; they now use the same build path as the debug task, so the ELF selected in
launch.jsonalways matches the latest upload.
- During builds, the extension parses compiler lines (
-I,-isystem,-iprefix) and updates.vscode/c_cpp_properties.json(configurationArduino). While the build runs, it only appends newly discovered paths to minimize churn; when the build finishes, it prunes unused and non-existent entries. - Clean builds reset
includePathfirst, then add only discovered paths. - For ESP32 family (esp32/xtensa-esp32/riscv32-esp-elf), it prefers
c17/c++23. - "Configure IntelliSense" computes include paths and writes
c_cpp_properties.jsonwithout triggering a build.
If you use tools such as clangd, CMake Tools, or the VS Code C/C++ extension in "use compile commands" mode, you can point them at the file generated by this extension.
- Run Arduino CLI: Compile Sketch at least once so the build output is available.
- The wrapper writes
.vscode/compile_commands.jsonnext to your workspace root. Each time you build, the file is refreshed automatically. - Every command from the Arduino CLI build and from your workspace sources is included—headers in the sketch folder, generated sources under the build directory, and more.
- Entries produced from temporary
.ino.cppfiles are rewritten to the original.inofilename, and thefilecolumn only keeps the file name (no absolute paths). This keeps diffs stable when the workspace lives in different locations.
Point clangd or other tools to <workspace>/.vscode/compile_commands.json and they will pick up the same flags the Arduino CLI used, without extra configuration.
arduino-cli-wrapper.path: Path to thearduino-cliexecutablearduino-cli-wrapper.additionalArgs: Extra arguments appended to every invocation (array)arduino-cli-wrapper.localBuildPath: Forces--build-pathto.build/<profile>inside the sketch so build artifacts stay alongside the projectarduino-cli-wrapper.verbose: Adds--verboseto compile/upload (mirrors the status bar toggle)arduino-cli-wrapper.compileWarnings: Warning level passed toarduino-cli compile(--warnings, mirrors the status bar toggle)arduino-cli-wrapper.lint.m5gfxIncludes: Header list treated as M5GFX family for include-order lintingarduino-cli-wrapper.lint.fsIncludes: Header list treated as filesystem-related for include-order linting
- Applies to
.inofiles in the workspace. - When an M5GFX header (from
arduino-cli-wrapper.lint.m5gfxIncludes) appears before a filesystem header (fromarduino-cli-wrapper.lint.fsIncludes) in the same translation unit, the extension emits an error diagnostic. - The default header lists cover the common M5GFX and filesystem headers; customize them per project via the settings above.
- Diagnostics refresh automatically as documents change or when the settings are updated.
- VS Code 1.84.0+
- Arduino CLI installed locally
- Executable not found: set a full path in
arduino-cli-wrapper.path. - Board not detected: check cable/driver/port, and run "Arduino CLI: List Connected Boards".
- Upload Data: ensure
data/exists and the sketch includesSPIFFS.horLittleFS.h.
- Highlight.js (core, cpp grammar, VS2015 theme) (c) 2006-2023 the highlight.js authors, BSD-3-Clause. License
CC0 1.0 Universal (Public Domain Dedication). See LICENSE.




