ESP-IDF Setup Guide for macOS

Complete Guide to Setting Up ESP-IDF Development Environment on macOS with Visual Studio Code

Introduction

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.

What You'll Learn:
  • Installing Visual Studio Code and ESP-IDF extension
  • Setting up ESP-IDF framework and tools
  • Creating your first ESP32 project
  • Building, flashing, and monitoring your device
  • Configuring IntelliSense for ESP-IDF code completion

Prerequisites

Before starting, ensure you have the following:

Important Note:
For ESP-IDF versions below 5.0, spaces are not supported in configured paths. Ensure all installation directories have no spaces in their names.

Step-by-Step Installation Guide

1Install Visual Studio Code

Visual Studio Code is a free, powerful code editor from Microsoft that will serve as your development environment.

  1. Visit the official Visual Studio Code website: https://code.visualstudio.com
  2. Click the "Download for macOS" button
  3. Once downloaded, open the .zip file
  4. Drag "Visual Studio Code.app" to your Applications folder
  5. Launch Visual Studio Code from your Applications folder

2Install ESP-IDF Prerequisites for macOS

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
What These Tools Do:
  • cmake: Build system generator required by ESP-IDF
  • ninja: Fast build system used by ESP-IDF
  • dfu-util: Tool for flashing devices via USB DFU mode

3Install ESP-IDF Extension in VS Code

  1. Open Visual Studio Code
  2. Click on the Extensions icon in the Activity Bar (left sidebar) or press ⇧⌘X
  3. In the search box, type: ESP-IDF
  4. Find "ESP-IDF" by Espressif in the results
  5. Click the Install button
  6. After installation, you'll see an Espressif icon appear in the Activity Bar
Verification:
Look for the Espressif icon (flame logo) in the left sidebar of VS Code. This confirms the extension is installed successfully.

4Run ESP-IDF Installation Manager

The ESP-IDF Installation Manager will help you download and configure ESP-IDF and all necessary tools.

  1. Press F1 to open the Command Palette
  2. Type: ESP-IDF: Open ESP-IDF Installation Manager
  3. Select the command from the dropdown list
  4. The ESP-IDF Installation Manager window will open

Installation Manager Options:

Choose your installation method:

  • EXPRESS: Recommended for most users - downloads ESP-IDF v5.5.4 (latest stable)
  • ADVANCED: For custom installations - choose specific ESP-IDF version and installation path

For Express Installation:

  1. Select EXPRESS
  2. Choose download server:
    • Github: Standard option (recommended)
    • Espressif: Faster for users in China
  3. Click Install
  4. Wait for the installation to complete (this may take 10-30 minutes depending on your internet speed)
Installation Location:
ESP-IDF will be installed to: ~/.espressif/v5.5.4/esp-idf
Tools will be installed to: ~/.espressif/tools/

5Verify Installation with Doctor Command

After installation completes, verify everything is set up correctly:

  1. Press F1
  2. Type: ESP-IDF: Doctor Command
  3. Select the command
  4. Review the diagnostic report in the output window
Expected Output:
You should see green checkmarks (✓) for all configuration items. If you see any red marks (✗), review the error messages and reinstall if necessary.

Creating Your First "Blink" Project

Project Creation Workflow

Create Project
Select Port
Set Target
Build
Flash
Monitor

6Create a New Project from Template

  1. Press F1 or ⌘⇧P
  2. Type: ESP-IDF: New Project
  3. Select the command
  4. In the project wizard:
    • Project Name: Enter "blink" (or your preferred name)
    • Choose Template: Select ESP-IDF
    • Sample Project: Navigate to get-startedblink
    • Project Directory: Choose where to save your project (e.g., ~/esp32-projects/)
  5. Click Create Project
  6. VS Code will open your new project folder
Project Structure:
Your project will contain:
  • main/ - Main source code directory containing blink_example_main.c
  • CMakeLists.txt - Build configuration file
  • sdkconfig - Project configuration file (generated after first build)
  • .vscode/ - VS Code configuration files

7Connect Your ESP32 Device

  1. Connect your ESP32 board to your Mac using a USB cable
  2. Wait a moment for macOS to recognize the device
  3. The device should appear as /dev/tty.usbmodem**** or /dev/tty.usbserial-****
USB Driver Note:
Most ESP32 boards work automatically on macOS. However, some boards using CH340 or CP210x chips may require additional drivers. If your device is not detected, check your board's documentation for driver requirements.

8Select Serial Port

  1. In the VS Code status bar (blue bar at the bottom), look for the port icon
  2. Click on the serial port button (shows current port or "Select Port")
  3. Select your ESP32 device from the list (e.g., /dev/tty.usbmodem1101)

Alternative Method:

  1. Press F1
  2. Type: ESP-IDF: Select Port to Use
  3. Press ⌘IP (keyboard shortcut)
  4. Choose your device from the list

9Set Espressif Device Target

Tell ESP-IDF which ESP32 chip you're using:

  1. Click the device target button in the status bar
  2. Select your chip type:
    • esp32 - Original ESP32
    • esp32s2 - ESP32-S2
    • esp32s3 - ESP32-S3
    • esp32c3 - ESP32-C3
    • And other variants...

Alternative Method:

Press F1 → Type: ESP-IDF: Set Espressif Device Target
How to Identify Your Chip:
Check your development board's label or documentation. Common boards:
  • ESP32-DevKitC → esp32
  • ESP32-S3-DevKitC → esp32s3
  • ESP32-C3-DevKitM → esp32c3

10Configure LED Pin (Optional)

The blink example uses a default LED pin. You may need to change it based on your board:

  1. Press F1
  2. Type: ESP-IDF: SDK Configuration Editor
  3. Press ⌘IG (keyboard shortcut)
  4. In the configuration editor, search for "blink"
  5. Find Example ConfigurationBlink GPIO number
  6. Change the GPIO number if needed (common values: 2, 5, 8, 18, 19)
  7. Click Save at the top
  8. Close the configuration editor
Board Type Default LED Pin
ESP32-DevKitC GPIO 2
ESP32-S3-DevKitC GPIO 48 (RGB LED)
ESP32-C3-DevKitM GPIO 8

11Build Your Project

Compile your project to create the firmware binary:

Method 1: Using Status Bar Icon

  1. Click the Build icon (hammer symbol) in the status bar
  2. Wait for the build process to complete
  3. View build output in the Terminal panel

Method 2: Using Command Palette

  1. Press F1
  2. Type: ESP-IDF: Build Your Project
  3. Press ⌘IB (keyboard shortcut)

Method 3: Using Command Line

  1. Press F1
  2. Type: ESP-IDF: Open ESP-IDF Terminal
  3. In the terminal, run:
idf.py build
Build Success:
When the build completes successfully, you'll see:
Project build complete. To flash, run: idf.py flash
Common Build Issues:
If build fails with Python path conflicts, run: idf.py fullclean Then rebuild the project.

12Flash Your Device

Upload the compiled firmware to your ESP32 board:

Method 1: Using Status Bar Icon

  1. Click the Flash icon (lightning bolt) in the status bar
  2. The extension will automatically flash using UART
  3. Wait for flashing to complete

Method 2: Using Command Palette

  1. Press F1
  2. Type: ESP-IDF: Flash Your Project
  3. Press ⌘IF (keyboard shortcut)

Method 3: Using Terminal Command

idf.py -p /dev/tty.usbmodem1101 flash
Flash Methods:
The extension supports three flashing methods:
  • UART: Standard serial flashing (default, most common)
  • JTAG: For advanced debugging with JTAG adapter
  • DFU: USB Device Firmware Update (ESP32-S2/S3 only)
Select flash method via status bar or command: ESP-IDF: Select Flash Method
Flash Success:
You'll see progress output showing:
  • Connecting to device...
  • Writing at 0x00010000... (percentage)
  • Hash of data verified
  • Leaving... Hard resetting via RTS pin...

13Monitor Device Output

View real-time serial output from your ESP32 device:

Method 1: Using Status Bar Icon

  1. Click the Monitor icon (computer screen) in the status bar
  2. A terminal window will open showing device output

Method 2: Using Command Palette

  1. Press F1
  2. Type: ESP-IDF: Monitor Device
  3. Press ⌘IM (keyboard shortcut)

Method 3: Combined Build, Flash, and Monitor

  1. Press F1
  2. Type: ESP-IDF: Build, Flash and Start a Monitor
  3. Press ⌘ID (keyboard shortcut)

Method 4: Using Terminal Command

idf.py -p /dev/tty.usbmodem1101 monitor
Expected Monitor Output:
You should see repeating messages like:
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!
Monitor Controls:
While monitoring:
  • Press Ctrl+] to exit monitor
  • Press Ctrl+T for menu options
  • Press Ctrl+T then Ctrl+H for help

14Troubleshooting Device Stuck in Download Mode

If your device gets stuck showing "waiting for download" after flashing:

Solution 1: Manual Reset

  1. Press Ctrl+] to exit monitor
  2. Press the RESET button on your ESP32 board
  3. Run monitor again: idf.py -p /dev/tty.usbmodem1101 monitor

Solution 2: Reconnect USB

  1. Exit monitor with Ctrl+]
  2. Unplug the USB cable from your Mac
  3. Wait 2-3 seconds
  4. Plug the USB cable back in
  5. Run monitor: idf.py -p /dev/tty.usbmodem1101 monitor

Configuring IntelliSense for ESP-IDF

IntelliSense provides code completion, syntax highlighting, and error detection for ESP-IDF libraries. Proper configuration is essential for a smooth development experience.

15Understanding c_cpp_properties.json

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.

File Location:
.vscode/c_cpp_properties.json in your project folder

16Generate compile_commands.json

Before configuring IntelliSense, you need to generate the compile_commands.json file which contains compilation information:

Method 1: Using Command Palette

  1. Press F1
  2. Type: ESP-IDF: Run idf.py reconfigure Task
  3. Wait for the task to complete

Method 2: Using Terminal

idf.py reconfigure

This will create build/compile_commands.json which IntelliSense uses for accurate code analysis.

17Find Your ESP-IDF Installation Path

To configure IntelliSense, you need to know where ESP-IDF is installed. Open the ESP-IDF Terminal and run:

echo $IDF_PATH
Typical Output:
/Users/yourusername/.espressif/v5.5.4/esp-idf

Keep this path handy - you'll need it for the next step.

18Find Your Toolchain Compiler Path

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
Example Output for ESP32-S3:
/Users/yourusername/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc

19Configure c_cpp_properties.json

Now create or edit the .vscode/c_cpp_properties.json file in your project. Here are configurations for different ESP32 chips:

For ESP32-S3:

{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/**", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components/**", "${workspaceFolder}/build/config" ], "browse": { "path": [ "${workspaceFolder}", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components" ], "limitSymbolsToIncludedHeaders": false }, "defines": [ "ESP_PLATFORM", "CONFIG_IDF_TARGET_ESP32S3=1" ], "compilerPath": "/Users/yourusername/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc", "cStandard": "c11", "cppStandard": "c++20", "intelliSenseMode": "gcc-x64", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], "version": 4 }

For ESP32 (Original):

{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/**", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components/**", "${workspaceFolder}/build/config" ], "browse": { "path": [ "${workspaceFolder}", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components" ], "limitSymbolsToIncludedHeaders": false }, "defines": [ "ESP_PLATFORM", "CONFIG_IDF_TARGET_ESP32=1" ], "compilerPath": "/Users/yourusername/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc", "cStandard": "c11", "cppStandard": "c++20", "intelliSenseMode": "gcc-x64", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], "version": 4 }

For ESP32-C3 (RISC-V):

{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/**", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components/**", "${workspaceFolder}/build/config" ], "browse": { "path": [ "${workspaceFolder}", "/Users/yourusername/.espressif/v5.5.4/esp-idf/components" ], "limitSymbolsToIncludedHeaders": false }, "defines": [ "ESP_PLATFORM", "CONFIG_IDF_TARGET_ESP32C3=1" ], "compilerPath": "/Users/yourusername/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", "cStandard": "c11", "cppStandard": "c++20", "intelliSenseMode": "gcc-x64", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], "version": 4 }
Important:
  • Replace /Users/yourusername/ with your actual username
  • Replace the ESP-IDF version path if different (check your $IDF_PATH)
  • Replace the toolchain version if different (check the output from the find commands)
  • Use the correct configuration for your specific ESP32 chip

20Using Environment Variables (Portable Method)

For a more portable configuration that works across different machines, use environment variables:

{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/**", "${env:HOME}/.espressif/v5.5.4/esp-idf/components/**", "${workspaceFolder}/build/config" ], "browse": { "path": [ "${workspaceFolder}", "${env:HOME}/.espressif/v5.5.4/esp-idf/components" ], "limitSymbolsToIncludedHeaders": false }, "defines": [ "ESP_PLATFORM", "CONFIG_IDF_TARGET_ESP32S3=1" ], "compilerPath": "${env:HOME}/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc", "cStandard": "c11", "cppStandard": "c++20", "intelliSenseMode": "gcc-x64", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], "version": 4 }

The ${env:HOME} variable automatically expands to your home directory, making the configuration portable.

21Reload VS Code and Verify IntelliSense

After saving the c_cpp_properties.json file:

  1. Press ⌘⇧P
  2. Type: Developer: Reload Window
  3. Wait for VS Code to reload
Verify IntelliSense is Working:

Open your main/blink_example_main.c file and check:

  • ✓ No red squiggly lines under #include "freertos/FreeRTOS.h"
  • ✓ No red squiggly lines under #include "driver/gpio.h"
  • ✓ Autocomplete works when typing gpio_
  • ⌘+Click on gpio_set_level() jumps to definition
  • ✓ Hovering over ESP-IDF functions shows documentation tooltips

22Troubleshooting IntelliSense Issues

Issue: Red Squiggly Lines Still Appear

Solutions:

  1. Ensure compile_commands.json exists: ls build/compile_commands.json
  2. If missing, regenerate it: idf.py reconfigure
  3. Reset IntelliSense database:
    • Press ⌘⇧P
    • Type: C/C++: Reset IntelliSense Database
  4. Reload VS Code window

Issue: Cannot Find Compiler Path

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.

Issue: ESP-IDF Path Not Found

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.

Issue: Configuration Variables Not Working

If ${config:...} variables cause errors, use absolute paths or ${env:HOME} instead as shown in the examples above.

Understanding the VS Code Status Bar Icons

The ESP-IDF extension adds several convenient icons to the VS Code status bar for quick access to common commands:

🔧 Build

Compiles your project. Click to build.

⚡ Flash

Uploads firmware to device. Click to flash.

📺 Monitor

Opens serial monitor. Click to view output.

🎯 Target

Shows/changes ESP chip target (esp32, esp32s3, etc.).

🔌 Port

Shows/selects serial port. Click to change port.

⚙️ SDK Config

Opens configuration editor for project settings.

Useful Keyboard Shortcuts

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

Complete Workflow Diagram

ESP32 Development Cycle

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

Common Commands Reference

Build Commands

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)

Flash Commands

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

Monitor Commands

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

Configuration Commands

idf.py menuconfig

Open terminal-based configuration menu

idf.py set-target esp32s3

Change the target chip (replace esp32s3 with your chip)

Troubleshooting Common Issues

Issue 1: Python Path Conflict

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

Issue 2: Device Not Detected

Problem: Serial port doesn't appear in the list

Solutions:

  1. Check USB cable connection (try a different cable if available)
  2. Try a different USB port on your Mac
  3. Check if driver is needed for your board's USB chip (CH340, CP210x)
  4. Run in Terminal to list all ports:
ls /dev/tty.*

Issue 3: Permission Denied Error

Error Message:

Could not open /dev/tty.usbmodem1101, the port is busy or doesn't exist

Solutions:

  1. Close any other programs using the serial port (Arduino IDE, serial monitor, etc.)
  2. Exit VS Code monitor with Ctrl+]
  3. Unplug and replug the USB cable
  4. Restart VS Code

Issue 4: Build Fails with Missing Dependencies

Solution: Reinstall ESP-IDF and tools

  1. Press F1
  2. Type: ESP-IDF: Open ESP-IDF Installation Manager
  3. Select your installation
  4. Click Reinstall or Repair

Issue 5: LED Not Blinking

Possible Causes and Solutions:

  • Wrong GPIO pin: Check your board's documentation for the correct LED pin and update in SDK Configuration Editor
  • External LED needed: Some boards don't have a built-in LED. Connect an external LED with a 220Ω resistor to the configured GPIO pin
  • Code not uploaded: Verify flash completed successfully with "Hash of data verified" message
  • Device stuck in boot mode: Press RESET button or reconnect USB

Issue 6: IntelliSense Not Working

Problem: Red squiggly lines under ESP-IDF includes, no autocomplete

Solutions:

  1. Verify compile_commands.json exists: ls build/compile_commands.json
  2. Regenerate if missing: idf.py reconfigure
  3. Check paths in c_cpp_properties.json are correct
  4. Reset IntelliSense: Press ⌘⇧PC/C++: Reset IntelliSense Database
  5. Reload VS Code: Press ⌘⇧PDeveloper: Reload Window

Using the Doctor Command

The Doctor Command provides a comprehensive diagnostic report of your ESP-IDF setup. Use it whenever you encounter issues:

  1. Press F1
  2. Type: ESP-IDF: Doctor Command
  3. Wait for analysis to complete
  4. Review the report for any configuration issues
  5. The report is automatically copied to your clipboard
What the Doctor Command Checks:
  • ESP-IDF installation path and version
  • Python environment and packages
  • Required tools (CMake, Ninja, OpenOCD, etc.)
  • VS Code extension configuration
  • Environment variables
  • Current project settings

Next Steps and Additional Resources

Explore More ESP-IDF Examples

ESP-IDF includes many example projects to help you learn:

  1. Press F1
  2. Type: ESP-IDF: New Project
  3. Browse categories:
    • peripherals: GPIO, I2C, SPI, UART, ADC, etc.
    • wifi: WiFi connectivity examples
    • bluetooth: BLE and Classic Bluetooth
    • protocols: HTTP, MQTT, WebSocket
    • storage: NVS, SPIFFS, SD card

Debugging Your Application

The ESP-IDF extension supports hardware debugging with JTAG:

  1. Connect a JTAG adapter (ESP-Prog, J-Link, etc.)
  2. Press F1 → Type: ESP-IDF: Select OpenOCD Board Configuration
  3. Press F5 to start debugging
  4. Set breakpoints, inspect variables, step through code

Official Documentation

Community Resources

Summary

Congratulations! You have successfully:

You're Ready to Build!
You now have a fully functional ESP-IDF development environment on macOS with proper IntelliSense support. You can start creating IoT projects, explore WiFi connectivity, Bluetooth communication, sensor integration, and much more with your ESP32 device!