You're three days into a new project. You have a rough schematic, a vague BOM, and a growing sense of dread because you still haven't picked the MCU. You've read fourteen forum threads, watched six YouTube videos, and you're now less certain than when you started.
This is the STM32 vs ESP32 debate, and it has consumed more engineering hours than any peripheral configuration bug in history.
Let me save you the remaining eleven days: both are excellent, neither is universally better, and the answer almost always becomes obvious once you write down your actual requirements instead of arguing about clock speeds on Reddit.
The tribal war
There are two camps, and they're both insufferable.
Camp ESP32 says: "Why would you use STM32 when ESP32 has WiFi, Bluetooth, costs $2, and Arduino works out of the box? ST's HAL is a war crime."
Camp STM32 says: "ESP32 is a toy. Try running a real-time control loop on it. The documentation is a fever dream and good luck getting anything certified."
They're both right. They're also both wrong. An ESP32-S3 running a motor control loop through FreeRTOS while bit-banging a custom protocol is going to have a bad time. An STM32F103 running a WiFi-connected sensor network is going to have a bad time and a bigger BOM.
The "right" MCU is a function of your project, not your preferences.
The 30-second decision tree
Before you read another word, run through this:
-
Does the product need WiFi or Bluetooth?
- Yes, WiFi required → ESP32. Stop reading.
- Yes, BLE only, battery-powered → nRF52. Seriously, stop reading.
- No wireless → STM32 is probably the better default. Keep reading to confirm.
-
Is hard real-time control critical (motor control, high-speed ADC sampling, precise timing)?
- Yes → STM32. The deterministic peripheral architecture is worth the steeper learning curve.
- No → Either works. Keep reading.
-
Is this a prototype or a product?
- Prototype / maker project → ESP32. The ecosystem gets you to a working demo faster.
- Production product → Keep reading, because the answer depends on volume, certification, and supply chain.
If you're still here, your project is in the uncomfortable middle ground. That's where the interesting engineering decisions live.
When ESP32 wins decisively
WiFi and BLE projects. This is the obvious one, but it's worth stating plainly: if your product connects to WiFi, the ESP32 family is the default choice. An STM32 plus an external WiFi module (ATWINC1500, ESP32 used as a coprocessor, or worse, a discrete WiFi SoC) adds cost, board space, a second firmware to maintain, and an integration headache. The ESP32 just... does it.
Cost-sensitive consumer products. An ESP32-C3 (single-core RISC-V, WiFi + BLE) is available for under $1 in volume. The closest STM32 with comparable memory is around $2-3, and that's without wireless. For a smart home sensor shipping 50k units, that dollar adds up fast.
Rapid prototyping. The Arduino ecosystem, PlatformIO support, and the sheer volume of ESP32 example code means you can get something blinking, reading sensors, and posting to MQTT in an afternoon. The ESP-IDF is also surprisingly capable once you get past the menuconfig labyrinth.
When the RF stack is the product. ESP-NOW, ESP-MESH, Matter support, and Bluetooth mesh are all first-party. If your product's value proposition is "connects to things," the ESP32 ecosystem has done most of the heavy lifting.
When STM32 wins decisively
Industrial and automotive-adjacent applications. STM32 parts are available with extended temperature ranges (-40 to 125C), automotive qualifications (AEC-Q100 on automotive-qualified STM32 variants), and safety certifications (SIL/ASIL on STM32G4). Espressif is getting there, but ST has decades of qualification data.
Low power without wireless. An STM32L4 in Stop 2 mode draws around 1.0 uA with RTC running. An ESP32-S3 in deep sleep with the ULP coprocessor active draws around 8 uA — decent, but the STM32L-series was engineered from the ground up for microamp-level operation. If you're running a battery-powered sensor that wakes up once a minute to take a reading and goes back to sleep — no wireless — the STM32L series will get you years of battery life.
Complex peripheral requirements. This is where STM32 quietly dominates. Need three independent ADCs sampling simultaneously? STM32F446. Need a hardware quadrature encoder interface? Most STM32 timers support it natively. Need DMA-driven SPI transfers that chain automatically? STM32's DMA architecture is a masterclass. The ESP32's peripherals are capable, but the STM32 family offers a depth and flexibility that matters when your application pushes the hardware.
Debugging experience. SWD with a $15 ST-Link gives you full breakpoints, watch variables, live memory view, ITM trace, and fault analysis. The ESP32's USB-JTAG (on S3/C3) has improved dramatically, but the STM32 debug toolchain — especially with Ozone or even STM32CubeIDE — is still in a different league for tracking down hard faults and timing issues.
The uncomfortable middle ground
Some projects genuinely could go either way. A data logger with an SD card and a display. A motor controller that also needs to report telemetry. A sensor node that could use either WiFi or a wired bus.
When both could work, here's what breaks the tie:
Team expertise. If your team has three years of STM32 experience and zero ESP-IDF experience, that's a real engineering cost. The reverse is equally true. Don't underestimate the "we already know how to debug this" factor.
RTOS requirements. Both run FreeRTOS. But ESP-IDF is built on FreeRTOS — it's the default, and the WiFi/BLE stacks require it. STM32 gives you the choice: bare metal, FreeRTOS, Zephyr, ThreadX (now Eclipse ThreadX), or any other RTOS. If you need Zephyr specifically (and there are good reasons you might), STM32 has first-class support.
Analog performance. The ESP32-S3's ADC is 12-bit with a DNL that'll make you cry. It's adequate for reading a thermistor. It's not adequate for precision measurement. The STM32F446's ADC is also 12-bit, but with significantly better linearity, a proper sample-and-hold, and hardware oversampling on newer parts (STM32G4, STM32H5). If analog matters, STM32 wins this one convincingly.
Long-term availability. ST commits to 10-year longevity on most STM32 parts. Espressif's track record is shorter (the company is younger), though the ESP32 original has been in production since 2016 and shows no signs of EOL. For a product with a 15-year lifecycle, ST's longevity commitments carry weight.
Real spec comparison that matters
Forget MHz and "who has more RAM." Here are the specs that actually affect your design:
| Parameter | STM32F103C8T6 | STM32F446RET6 | ESP32-S3 (N16R8) | ESP32-C3 |
|---|---|---|---|---|
| Core | Cortex-M3 72 MHz | Cortex-M4F 180 MHz | Xtensa LX7 dual 240 MHz | RISC-V single 160 MHz |
| Flash / RAM | 64 KB / 20 KB | 512 KB / 128 KB | 16 MB (ext) / 512 KB + 8 MB PSRAM | 4 MB (ext) / 400 KB |
| ADC resolution | 12-bit, 1 us | 12-bit, dual/triple | 12-bit, poor DNL | 12-bit, poor DNL |
| DMA channels | 7 | 16 (dual controller) | 5 (GDMA) | 3 (GDMA) |
| Hardware timers | 4 (16-bit) | 14 (mixed 16/32-bit) | 4 general-purpose | 2 general-purpose |
| Sleep current (RTC) | 2.0 uA (Standby) | 2.4 uA (Standby) | ~8 uA (deep sleep + ULP) | ~5 uA (deep sleep) |
| WiFi / BLE | No | No | WiFi 4 + BLE 5.0 | WiFi 4 + BLE 5.0 |
| Debug interface | SWD | SWD | USB-JTAG / UART | USB-JTAG / UART |
| Unit cost (qty 1) | ~$1.50 | ~$4.50 | ~$2.80 (module) | ~$1.20 (module) |
| JLCPCB basic part | Yes (C8734) | No (extended) | No (extended) | Yes (C2838502) |
| Package | LQFP-48 | LQFP-64 | Module (18x25 mm) | Module (18x20 mm) / QFN-32 |
A few things jump out from this table:
The STM32F103 is still everywhere. It's a JLCPCB basic part, which means free SMT assembly. For simple projects without wireless, it's almost impossible to beat on cost. Yes, it's a Cortex-M3 from 2007. It still works fine.
The ESP32-C3 is the price/performance king for wireless. RISC-V core, WiFi + BLE, and it's a JLCPCB basic part. For IoT sensors, it's the default.
DMA channel count matters more than you think. If you're doing SPI to a display, UART to a GPS, I2C to sensors, and ADC sampling — all at once — you need DMA channels. The STM32F446's 16 channels with flexible mapping give you headroom. The ESP32-C3's 3 channels will have you implementing software workarounds.
Peripheral initialization: a taste of each world
The toolchain difference is real. Here's a simple GPIO toggle on each platform to give you a feel.
STM32 (HAL):
// Enable GPIOA clock
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef gpio = {0};
gpio.Pin = GPIO_PIN_5;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &gpio);
// Toggle
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);STM32 (bare register access, for the purists):
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
GPIOA->MODER &= ~(3U << (5 * 2));
GPIOA->MODER |= (1U << (5 * 2)); // Output mode
GPIOA->ODR ^= (1U << 5); // ToggleESP32 (ESP-IDF):
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << GPIO_NUM_2),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
// Toggle
static int level = 0;
gpio_set_level(GPIO_NUM_2, level ^= 1);Both are fine. The STM32 HAL is more verbose and has a reputation for bloat, but it's also more explicit about what's happening at the hardware level. ESP-IDF is cleaner for simple cases but the abstraction gets in the way when you need to do something the API didn't anticipate. Pick your poison.
Supply chain reality check
The best MCU for your design is the one you can actually buy.
STM32 supply has stabilized since the 2021-2023 shortage, but some parts (particularly STM32H7 and STM32G4 in specific packages) still have lead times of 20+ weeks through official distribution. The upside: the STM32 lineup is enormous, and pin-compatible alternatives usually exist within the same subfamily. Designed with an STM32F446RE and can't get stock? The STM32F446RC (less flash) or STM32F446VE (more pins) probably works with minor changes.
ESP32 supply is generally more stable because Espressif has fewer SKUs and modules are commodity items with multiple authorized manufacturers (Espressif's own, along with Ai-Thinker, and others). But the flip side is fewer second-source options if the specific module you designed in goes EOL.
JLCPCB stock is a real consideration for prototyping runs. Check the LCSC catalog before committing. Having your MCU as a basic part (free assembly) versus extended (extra per part) can meaningfully change your prototype costs, especially on small runs.
The actual decision framework
When someone asks me "STM32 or ESP32?", I run through this checklist. It takes about five minutes and has never failed me:
- Does the product need WiFi? Yes → ESP32. No → Continue.
- Does the product need BLE only, and is battery life critical? Yes → Consider nRF52 first. No → Continue.
- Are there hard real-time requirements (motor control, precision timing, high-speed ADC)? Yes → STM32. No → Continue.
- Is analog performance critical (measurement, not just "read a potentiometer")? Yes → STM32. No → Continue.
- Is this going into production? No (prototype/hobby) → ESP32 for faster iteration. Yes → Continue.
- What does the team know? Heavy ESP-IDF experience → ESP32. Heavy STM32/Cube experience → STM32. Neither → ESP32 for lower entry barrier.
- Volume and cost target? High volume, cost-critical → ESP32-C3 or STM32F103 depending on wireless needs. Low volume → Pick based on features, cost doesn't matter enough to drive the decision.
- Certification requirements (automotive, medical, industrial safety)? Yes → STM32. Espressif's certification story is improving but ST's is proven.
- Still can't decide? Pick whichever one you can buy from JLCPCB as a basic part today.
That's it. Nine questions. Five minutes. No Reddit required.
The real answer
The STM32 vs ESP32 debate persists because both are genuinely good, and for a surprisingly large set of projects, either would work. The engineering sin isn't picking the "wrong" one — it's spending two weeks deciding instead of two hours.
Define your requirements. Run the checklist. Pick one. Start routing the PCB.
The MCU you ship with beats the MCU you're still debating about.