Extended INO is a format that allows Arduino sketch files (.ino) to embed build configuration metadata directly within the source code, similar to Astral UV's inlined script dependencies. This enables self-contained sketches that carry their own build requirements, making them more portable and easier to share.
Traditional Arduino development requires external configuration files (platformio.ini, arduino-cli.yaml) or IDE-specific settings to specify build parameters. Extended INO embeds this configuration directly in the sketch file, providing:
- Portability: Sketches carry their build requirements
- Self-Documentation: Build configuration is visible alongside code
- Reproducibility: Consistent builds across different environments
- Simplicity: Single file contains both code and configuration
Extended INO files use a comment block with TOML configuration embedded between delimiter markers:
// /// extended-ino
// [build]
// board = "arduino:avr:uno"
//
// [flags]
// build = ["-DDEBUG=1", "-O2"]
// link = ["-Wl,--gc-sections"]
//
// [defines]
// DEBUG = "1"
// VERSION = "\"1.0.0\""
// ///
#include <FastLED.h>
void setup() {
// Your Arduino code here
}
void loop() {
// Your Arduino code here
}- Start delimiter:
// /// extended-ino - End delimiter:
// /// - All configuration lines must be prefixed with
//(comment prefix + space) - The content between delimiters must be valid TOML
- All relative paths in configuration are resolved relative to the sketch file's directory
board(string): Board Fully Qualified Name (FQBN)- Format:
package:architecture:board_id - Example:
"arduino:avr:uno","esp32:esp32:esp32"
- Format:
build(array of strings): Compiler flags passed during compilationlink(array of strings): Linker flags passed during linkingupload(array of strings): Upload-specific flags
Key-value pairs of preprocessor definitions:
- Keys become
#definenames - Values become
#definevalues - String values should be quoted appropriately for C/C++
libraries(array of strings): Library dependencies with optional version constraintsadditional_urls(array of strings): Board Manager package index URLs for custom boardscores(array of strings): Core dependenciestools(array of strings): Tool dependencies
cpu_frequency(string): CPU frequency settingflash_frequency(string): Flash frequency settingupload_speed(integer): Upload baud ratepartition_scheme(string): Flash partition scheme
Required for Build Process:
directories_user(string): Arduino sketchbook directory for libraries and hardwaredirectories_data(string): Arduino CLI data directory for core installationsexport_binaries(boolean): Always save compiled binaries to sketch folder
Required for Custom Boards:
board_manager_additional_urls(array of strings): URLs for additional board package indexesenable_unsafe_library_install(boolean): Allow installation from git URLs or zip files
Build Performance:
build_cache_path(string): Custom location for build cache filesbuild_cache_extra_paths(array of strings): Additional directories to include in build cachebuild_cache_ttl(string): Time-to-live for cached compilation units (e.g., "720h")
Development Experience:
logging_level(string): Log verbosity level ("trace", "debug", "info", "warn", "error", "fatal")logging_file(string): Log file path for persistent loggingoutput_no_color(boolean): Disable colored output for terminals that don't support itlocale(string): Language setting for Arduino CLI messages
Network Configuration:
network_proxy(string): HTTP/HTTPS proxy server URLconnection_timeout(string): Network timeout duration (e.g., "10s")
Advanced Features:
daemon_port(string): gRPC port for Arduino CLI daemon modemetrics_enabled(boolean): Enable telemetry collectionupdater_enable_notification(boolean): Check for Arduino CLI updates
Extended INO supports multiple board configurations using TOML table arrays:
// /// extended-ino
// [[board]]
// fqbn = "arduino:avr:uno"
//
// [board.flags]
// build = ["-DARDUINO_UNO=1"]
//
// [board.defines]
// BOARD_TYPE = "\"UNO\""
//
// [[board]]
// fqbn = "esp32:esp32:esp32"
//
// [board.flags]
// build = ["-DARDUINO_ESP32=1"]
//
// [board.defines]
// BOARD_TYPE = "\"ESP32\""
// ///// /// extended-ino
// [build]
// board = "arduino:avr:uno"
//
// [defines]
// LED_PIN = "13"
// BAUD_RATE = "9600"
// ///
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(BAUD_RATE);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}// /// extended-ino
// [build]
// board = "esp32:esp32:esp32"
//
// [flags]
// build = [
// "-DCORE_DEBUG_LEVEL=4",
// "-DARDUINO_RUNNING_CORE=1",
// "-DARDUINO_EVENT_RUNNING_CORE=1"
// ]
// link = ["-Wl,--gc-sections"]
//
// [defines]
// WIFI_SSID = "\"MyNetwork\""
// WIFI_PASSWORD = "\"MyPassword\""
// DEBUG_ENABLED = "1"
//
// [dependencies]
// libraries = ["WiFi", "WebServer", "ArduinoJson@>=6.0.0"]
// additional_urls = ["https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json"]
//
// [settings]
// cpu_frequency = "240MHz"
// flash_frequency = "80MHz"
// upload_speed = 921600
// partition_scheme = "default"
//
// [cli]
// directories_user = "/home/user/Arduino"
// export_binaries = true
// board_manager_additional_urls = ["https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"]
//
// [cli_optional]
// build_cache_ttl = "720h"
// logging_level = "info"
// output_no_color = false
// ///
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoJson.h>
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
// Application code
}// /// extended-ino
// [build]
// board = "esp32:esp32:esp32dev"
//
// [dependencies]
// libraries = ["FastLED@>=3.6.0", "WiFiManager", "ArduinoJson@^6.21.0"]
// additional_urls = [
// "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json",
// "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"
// ]
//
// [defines]
// FASTLED_INTERNAL = "1"
// LED_COUNT = "100"
//
// [cli]
// directories_user = "./libraries" # Relative to sketch directory
// directories_data = "./arduino-data" # Relative to sketch directory
// export_binaries = true
// enable_unsafe_library_install = true
//
// [cli_optional]
// build_cache_path = "./build-cache" # Relative to sketch directory
// build_cache_ttl = "168h"
// logging_level = "debug"
// logging_file = "./arduino-cli.log" # Relative to sketch directory
// ///
#include <FastLED.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
CRGB leds[LED_COUNT];
void setup() {
FastLED.addLeds<WS2812B, 2, GRB>(leds, LED_COUNT);
WiFiManager wifiManager;
wifiManager.autoConnect("FastLED_Setup");
}
void loop() {
// LED effects and WiFi communication
}// /// extended-ino
// [[board]]
// fqbn = "arduino:avr:uno"
//
// [board.defines]
// LED_COUNT = "50"
// DATA_PIN = "6"
//
// [board.flags]
// build = ["-DAVR_BOARD=1"]
//
// [[board]]
// fqbn = "esp32:esp32:esp32"
//
// [board.defines]
// LED_COUNT = "100"
// DATA_PIN = "2"
//
// [board.flags]
// build = ["-DESP32_BOARD=1"]
//
// [board.settings]
// cpu_frequency = "240MHz"
// ///
#include <FastLED.h>
CRGB leds[LED_COUNT];
void setup() {
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, LED_COUNT);
}
void loop() {
// LED animation code
}- Automatic Discovery: Detect Extended INO configuration in any
.inofile being processed (no path argument required) - Comment Extraction: Parse comment blocks between delimiters within the sketch file
- TOML Validation: Validate embedded TOML syntax
- Field Validation: Ensure required fields are present
- Board Resolution: Validate FQBN format and availability
- Path Resolution: Use sketch file directory as base path for all relative paths and generated files
Extended INO can integrate with:
- Arduino CLI: Generate temporary
arduino-cli.yamlconfiguration files from[cli]and[cli_optional]sections - PlatformIO: Convert to
platformio.iniformat using board, flags, and dependencies - Arduino IDE 2.x: Plugin/extension support for parsing and applying Extended INO configuration
- VS Code: Language server extensions with Arduino CLI integration
Extended INO tools can generate Arduino CLI configuration files from embedded metadata:
# Generated arduino-cli.yaml from Extended INO [cli] section
board_manager:
additional_urls:
- "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"
directories:
user: "./libraries"
data: "./arduino-data"
sketch:
always_export_binaries: true
library:
enable_unsafe_install: true
build_cache:
path: "./build-cache"
ttl: "168h"
logging:
level: "debug"
file: "./arduino-cli.log"- Invalid TOML: Clear syntax error messages with line numbers
- Missing Required Fields: Specify which fields are missing
- Invalid FQBN: Validate board availability
- Conflicting Configurations: Handle multi-board conflicts
- Files without Extended INO blocks remain valid Arduino sketches
- Existing build systems can ignore the comment blocks
- Gradual adoption possible
- Variable Substitution: Environment variable and computed value support
- Conditional Configuration: Platform-specific sections
- Include Support: Reference external configuration fragments
- Version Constraints: Semantic versioning for dependencies
- Custom Build Steps: Pre/post-build actions
// /// extended-ino
// [build]
// board = "${BOARD_FQBN:-arduino:avr:uno}"
//
// [conditional.esp32]
// condition = "platform == 'esp32'"
//
// [conditional.esp32.defines]
// WIFI_ENABLED = "1"
//
// [includes]
// common = "./common-config.toml"
// ///Extended INO tools operate directly on sketch files without requiring explicit path arguments:
# Tool discovers configuration from the sketch file automatically
extended-ino-build MySketch.ino
# Working directory becomes the sketch's directory
extended-ino-compile MyProject/MySketch.ino
# All generated files appear in the sketch's directory
extended-ino-upload ./examples/Blink/Blink.inoKey Behaviors:
- Implicit Path Discovery: Tools automatically detect Extended INO configuration in the specified
.inofile - Working Directory: The sketch file's directory becomes the base path for all operations
- Generated Files: All temporary files (
arduino-cli.yaml,platformio.ini, build cache) are created relative to the sketch location - No Path Arguments: Tools never require separate path or directory arguments beyond the sketch file itself
- TOML Parser: For configuration extraction and validation from sketch files
- Board Database: FQBN validation and resolution
- Build System Integration: Convert to native build formats using sketch file location as working directory
- Parse: Extract and validate Extended INO configuration from comment block in the sketch file
- Resolve: Validate board FQBN and check dependency availability
- Configure: Generate temporary
arduino-cli.yamlfrom[cli]and[cli_optional]sections in the sketch directory - Dependencies: Install libraries and board packages as specified
- Generate: Create appropriate build system files (platformio.ini, compile_commands.json) in the sketch directory
- Build: Execute Arduino CLI build process with generated configuration using the sketch file path
- Export: Save binaries to sketch directory if
export_binariesis enabled - Clean: Remove temporary configuration files and build artifacts from sketch directory
Extended INO provides a self-contained format for Arduino sketches that embeds build configuration alongside source code. This improves portability, reproducibility, and ease of sharing while maintaining backward compatibility with existing Arduino development workflows.
The format integrates comprehensive Arduino CLI configuration options, enabling complete control over the build environment, dependency management, and development experience through embedded TOML metadata.
The format is designed to be:
- Human-readable: TOML syntax is clear and well-documented
- Tool-friendly: Structured format enables automated processing and Arduino CLI integration
- Extensible: Future features can be added without breaking changes
- Compatible: Works with existing Arduino ecosystems and CLI tools
- Comprehensive: Covers essential build settings and optional developer experience enhancements