Complete Guide to Setting Up ESP-IDF Development Environment on macOS with Visual Studio Code
This comprehensive guide will walk you through setting up the ESP-IDF (Espressif IoT Development Framework) on macOS using Visual Studio Code. By the end of this tutorial, you will have a fully functional development environment and will create your first "Blink" project to control an LED on an ESP32 device.
Before starting, ensure you have the following:
Visual Studio Code is a free, powerful code editor from Microsoft that will serve as your development environment.
Before installing ESP-IDF, you need to install some required system packages. Open Terminal (found in Applications > Utilities) and run the following commands one by one:
Install Homebrew (if not already installed):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Install required packages:
brew install cmake ninja dfu-util
The ESP-IDF Installation Manager will help you download and configure ESP-IDF and all necessary tools.
Choose your installation method:
For Express Installation:
~/.espressif/v5.5.4/esp-idf~/.espressif/tools/
After installation completes, verify everything is set up correctly:
~/esp32-projects/)/dev/tty.usbmodem**** or
/dev/tty.usbserial-****/dev/tty.usbmodem1101)Alternative Method:
Tell ESP-IDF which ESP32 chip you're using:
Alternative Method:
Press F1 → Type: ESP-IDF: Set Espressif Device Target
The blink example uses a default LED pin. You may need to change it based on your board:
| Board Type | Default LED Pin |
|---|---|
| ESP32-DevKitC | GPIO 2 |
| ESP32-S3-DevKitC | GPIO 48 (RGB LED) |
| ESP32-C3-DevKitM | GPIO 8 |
Compile your project to create the firmware binary:
Method 1: Using Status Bar Icon
Method 2: Using Command Palette
Method 3: Using Command Line
idf.py build
Project build complete. To flash, run: idf.py flash
idf.py fullclean
Then rebuild the project.
Upload the compiled firmware to your ESP32 board:
Method 1: Using Status Bar Icon
Method 2: Using Command Palette
Method 3: Using Terminal Command
idf.py -p /dev/tty.usbmodem1101 flash
View real-time serial output from your ESP32 device:
Method 1: Using Status Bar Icon
Method 2: Using Command Palette
Method 3: Combined Build, Flash, and Monitor
Method 4: Using Terminal Command
idf.py -p /dev/tty.usbmodem1101 monitor
I (318) example: Turning the LED OFF! I (1318) example: Turning the LED ON! I (2318) example: Turning the LED OFF! I (3318) example: Turning the LED ON!Your LED should blink on and off every second!
If your device gets stuck showing "waiting for download" after flashing:
Solution 1: Manual Reset
idf.py -p /dev/tty.usbmodem1101 monitorSolution 2: Reconnect USB
idf.py -p /dev/tty.usbmodem1101 monitorIntelliSense provides code completion, syntax highlighting, and error detection for ESP-IDF libraries. Proper configuration is essential for a smooth development experience.
The c_cpp_properties.json file configures the C/C++ extension's IntelliSense feature.
This file tells VS Code where to find ESP-IDF headers, which compiler to use, and what language
standards to apply.
.vscode/c_cpp_properties.json in your project folder
Before configuring IntelliSense, you need to generate the compile_commands.json file
which contains compilation information:
Method 1: Using Command Palette
Method 2: Using Terminal
idf.py reconfigure
This will create build/compile_commands.json which IntelliSense uses for accurate code
analysis.
To configure IntelliSense, you need to know where ESP-IDF is installed. Open the ESP-IDF Terminal and run:
echo $IDF_PATH
/Users/yourusername/.espressif/v5.5.4/esp-idf
Keep this path handy - you'll need it for the next step.
The compiler path depends on your ESP32 chip type. Run these commands to find the correct path:
For ESP32-S3 (and other chips):
find ~/.espressif/tools -name "xtensa-esp32s3-elf-gcc" -type f
For ESP32 (original):
find ~/.espressif/tools -name "xtensa-esp32-elf-gcc" -type f
For ESP32-C3 (RISC-V):
find ~/.espressif/tools -name "riscv32-esp-elf-gcc" -type f
/Users/yourusername/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc
Now create or edit the .vscode/c_cpp_properties.json file in your project. Here are
configurations for different ESP32 chips:
/Users/yourusername/ with your actual username$IDF_PATH)For a more portable configuration that works across different machines, use environment variables:
The ${env:HOME} variable automatically expands to your home directory, making the
configuration portable.
After saving the c_cpp_properties.json file:
Open your main/blink_example_main.c file and check:
#include "freertos/FreeRTOS.h"#include "driver/gpio.h"gpio_gpio_set_level() jumps to
definitionSolutions:
compile_commands.json exists:
ls build/compile_commands.json
idf.py reconfigure
Solution: Verify the compiler exists:
ls /Users/yourusername/.espressif/tools/xtensa-esp-elf/*/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc
If the path is different, update your c_cpp_properties.json with the correct path.
Solution: Verify ESP-IDF installation:
ls ~/.espressif/v5.5.4/esp-idf/components/
If the version number is different, check:
echo $IDF_PATH
And update your configuration with the correct path.
If ${config:...} variables cause errors, use absolute paths or ${env:HOME}
instead as shown in the examples above.
The ESP-IDF extension adds several convenient icons to the VS Code status bar for quick access to common commands:
Compiles your project. Click to build.
Uploads firmware to device. Click to flash.
Opens serial monitor. Click to view output.
Shows/changes ESP chip target (esp32, esp32s3, etc.).
Shows/selects serial port. Click to change port.
Opens configuration editor for project settings.
| Action | macOS Shortcut | Command |
|---|---|---|
| Open Command Palette | ⌘⇧P or F1 | Show all available commands |
| Build Project | ⌘IB | ESP-IDF: Build Your Project |
| Flash Device | ⌘IF | ESP-IDF: Flash Your Project |
| Monitor Device | ⌘IM | ESP-IDF: Monitor Device |
| Build + Flash + Monitor | ⌘ID | ESP-IDF: Build, Flash and Monitor |
| SDK Configuration | ⌘IG | ESP-IDF: SDK Configuration Editor |
| Select Port | ⌘IP | ESP-IDF: Select Port to Use |
| New Project | ⌘IN | ESP-IDF: New Project |
| Open Terminal | ⌘IT | ESP-IDF: Open ESP-IDF Terminal |
1. Write Code → Edit your C/C++ files in
main/ directory
↓
2. Configure → Adjust settings via SDK Configuration Editor
↓
3. Build → Compile code into binary firmware
↓
4. Flash → Upload firmware to ESP32 device
↓
5. Monitor → View serial output and test functionality
↓
6. Debug/Modify → Make changes and repeat cycle
idf.py build
Build the project
idf.py fullclean
Clean all build files and rebuild from scratch
idf.py reconfigure
Re-run CMake configuration (useful after changing CMakeLists.txt)
idf.py -p /dev/tty.usbmodem1101 flash
Flash the device on specified port
idf.py flash monitor
Flash and immediately start monitoring
idf.py erase-flash
Erase all data from flash memory
idf.py -p /dev/tty.usbmodem1101 monitor
Start serial monitor on specified port
idf.py -p /dev/tty.usbmodem1101 flash monitor
Flash and monitor in one command
idf.py menuconfig
Open terminal-based configuration menu
idf.py set-target esp32s3
Change the target chip (replace esp32s3 with your chip)
Error Message:
'/Users/username/.espressif/tools/python/v5.5.4/venv/bin/python' is currently active while project was configured with '/Users/username/.espressif/tools/python/v5.5.4/venv/bin/python3'
Solution:
idf.py fullclean
idf.py build
Problem: Serial port doesn't appear in the list
Solutions:
ls /dev/tty.*
Error Message:
Could not open /dev/tty.usbmodem1101, the port is busy or doesn't exist
Solutions:
Solution: Reinstall ESP-IDF and tools
Possible Causes and Solutions:
Problem: Red squiggly lines under ESP-IDF includes, no autocomplete
Solutions:
compile_commands.json exists:
ls build/compile_commands.json
idf.py reconfigure
c_cpp_properties.json are correctThe Doctor Command provides a comprehensive diagnostic report of your ESP-IDF setup. Use it whenever you encounter issues:
ESP-IDF includes many example projects to help you learn:
The ESP-IDF extension supports hardware debugging with JTAG:
Congratulations! You have successfully: