DEV Community

ben
ben

Posted on

C# ESP32/STM32 Lightweight Web Capability Library: PicoServer.Nano

nanoframework-esp32

Today's .NET is fully open-source and cross-platform. As a .NET developer, you're probably already used to developing Windows applications, Linux Web APIs, and even building mobile or cross-platform apps with MAUI or Avalonia using C#.

In addition, there's another project under the .NET Foundation—.NET nanoFramework, designed specifically to run C# on microcontrollers like ESP32 and STM32. It strips the full .NET runtime down to a few hundred KB, enabling MCUs to execute C# code. You can develop projects using Visual Studio and deploy them to your board with a single click.

PicoServer is a lightweight .NET web capability aggregate library—single DLL, zero dependencies, AOT-compatible, and only a few tens of KB. PicoServer.Nano is my humble attempt to bring that experience to nanoFramework—letting embedded devices build lightweight web services using C#. It stays true to PicoServer's philosophy of being "simple, straightforward, non-architecturally intrusive," while adapting to the constraints of MCUs by making deliberate trade-offs: prioritizing routing, static file hosting, token authentication, custom middleware, SSE, and other commonly used features.

Unlike the official WebServer library, PicoServer.Nano avoids reflection, resulting in lower memory and CPU usage, leaving more resources for your application logic.

Key Features at a Glance

  • Routing, custom middleware, token authentication, static file hosting, SSE persistent connections, file upload/download

For detailed usage, see the official documentation


I. ESP32 and STM32 Use Cases

A quick overview of the two chip families: ESP32 integrates Wi-Fi/Bluetooth, offers fast development, and is cost-effective—making it a popular choice for smart home and IoT projects. STM32, on the other hand, is known for its rich peripherals, strong real-time responsiveness, and industrial-grade stability—dominating fields like industrial control and automotive electronics. While each has different strengths, both can quickly provide web capabilities using PicoServer.Nano.


II. Quick Start: Running a Web API on ESP32

1. Flash nanoFramework Firmware

nanoff --target ESP32_S3_ALL --serialport COM5 --update --masserase
Enter fullscreen mode Exit fullscreen mode

2. Add NuGet Package

dotnet add package PicoServer.Nano
Enter fullscreen mode Exit fullscreen mode

3. Write Code

using PicoServer.Nano;
using System.Net;

var server = new WebAPIServer();
server.AddRoute("/hello", (req, res) => res.Write("Hello from MCU!"), "GET");
server.StartServer();
Console.WriteLine($"Server started: http://{server.GetIPAddress()}/");
Enter fullscreen mode Exit fullscreen mode

Build, deploy/run, and visit http://<device IP>/hello in your browser to see the response.


III. Static File Hosting

Host an entire folder with a single line of code:

server.AddStaticFiles("/web", "I:\\www", maxAge: 3600);
Enter fullscreen mode Exit fullscreen mode

Visit http://device IP/web/index.html to see the webpage.


IV. Performance Benchmark

Test Platform: ESP32-S3 N16R8, LAN Wi-Fi

# 6 concurrent short-duration stress test command
hey -n 50 -c 6 http://192.168.2.67
Enter fullscreen mode Exit fullscreen mode
Configuration Stable Concurrency QPS Avg Latency Success Rate
Without PSRAM 6 ~8 ~220ms 100%
With PSRAM 6 ~26 ~210ms 100%

Enabling PSRAM significantly improves QPS. STM32 with Ethernet or hardware protocol stacks is expected to achieve even higher performance. Concurrency should be kept within 6; exceeding this may cause packet loss at the underlying lwIP stack.


V. Consistent C# Development Experience

PicoServer on Windows/Linux/macOS/iOS/Android:

server.AddRoute("/hello", async (req, res) => await res.WriteAsync("Hello"));
Enter fullscreen mode Exit fullscreen mode

PicoServer.Nano on ESP32/STM32:

server.AddRoute("/hello", (req, res) => res.Write("Hello"));
Enter fullscreen mode Exit fullscreen mode

Virtually the same API, delivering a consistent web development experience across desktop, cloud, and embedded microcontrollers.


VI. Important Notes

  1. Path Format: Use backslashes \ in nanoFramework, e.g., "I:\\www"
  2. Static File Hosting: Files must be deployed to the device (set Build Action to "Content"). Middlewares execute sequentially—add static file hosting first.
  3. Whitelist: Static file routes must be added to the whitelist to bypass authentication.
  4. Persistent Connections: After pushing with WriteChunk, you must call res.Close().

VII. Resources

Top comments (0)