EmbedIO-Neo
1.0.1
dotnet add package EmbedIO-Neo --version 1.0.1
NuGet\Install-Package EmbedIO-Neo -Version 1.0.1
<PackageReference Include="EmbedIO-Neo" Version="1.0.1" />
<PackageVersion Include="EmbedIO-Neo" Version="1.0.1" />
<PackageReference Include="EmbedIO-Neo" />
paket add EmbedIO-Neo --version 1.0.1
#r "nuget: EmbedIO-Neo, 1.0.1"
#:package EmbedIO-Neo@1.0.1
#addin nuget:?package=EmbedIO-Neo&version=1.0.1
#tool nuget:?package=EmbedIO-Neo&version=1.0.1
EmbedIO-Neo

A small, cross-platform, modular web server for .NET, maintained by William Smith.
New to EmbedIO-Neo? Start with a working JSON endpoint, then add static files or controllers.
For MAUI apps on Mac Catalyst, see the local server startup guide, including upstream issue #601 and sandbox entitlements. This is an independent fork of EmbedIO. Original copyright and third-party notices are preserved in LICENSE.
Development focuses on compatible enhancements, simpler internals, bug fixes, and measured performance improvements. Breaking changes require William's explicit approval before implementation, with documented migration steps. See Contributing for the compatibility policy and build commands.
Report issues and contribute at WilliamSmithEdward/embedio-neo. The API examples below use the existing EmbedIO 3.x namespaces.
Overview
A small, modular, MIT-licensed web server targeting .NET 10 and .NET Standard 2.0.
- Written entirely in C#, using built-in .NET APIs on .NET 10
- Network operations use the async/await pattern: Responses are handled asynchronously
- Multiple implementations support: EmbedIO can use Microsoft
HttpListeneror internal Http Listener based on Mono/websocket-sharp projects - The Neo regression suite passes on Windows, Linux and macOS with .NET 10. The .NET Standard 2.0 target is retained for legacy consumers; older runtimes, including .NET Framework and Mono, have not been validated for Neo.
- Extensible: write your own modules, or use the JsonServer module included in this repository.
- Small memory footprint
- Create REST APIs quickly with the out-of-the-box Web API module
- Serve static or embedded files with 1 line of code (also out-of-the-box)
- Handle sessions with the built-in LocalSessionManager
- WebSockets support
- CORS support. Origin, Header and Method validation with OPTIONS preflight
- HTTP 206 Partial Content support
- And many more options in the same package
EmbedIO 3.0 - What's new
The major version 3.0 includes a lot of changes in how the webserver process the incoming request and the pipeline of the Web Modules. You can check a complete list of changes and a upgrade guide for v2 users here.
Some usage scenarios:
Write a cross-platform GUI entirely using React/AngularJS/Vue.js or any Javascript framework
Write a game using Babylon.js and make EmbedIO your serve your code and assets
Create GUIs for Windows services or Linux daemons
Write client applications with real-time communication between them using WebSockets
Installation:
Use the commands below to install EmbedIO-Neo, or build the source
and add a project reference to src/EmbedIO/EmbedIO.csproj.
The archived EmbedIO package is a separate upstream distribution. Neo's package
ID changes, while the library's assembly name and namespaces remain EmbedIO.
Package Manager
PM> Install-Package EmbedIO-Neo
.NET CLI
> dotnet add package EmbedIO-Neo
Usage
Working with EmbedIO is pretty simple, check the follow sections to start coding right away. You can find more useful recipes and implementation details in the upstream Cookbook.
WebServer Setup
This complete example serves a directory and waits for shutdown. Create wwwroot
with the files you intend to expose before running it. Press Ctrl+C to stop.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using EmbedIO;
using var shutdown = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true;
shutdown.Cancel();
};
using var server = new WebServer(o => o
.WithUrlPrefix("http://localhost:9696/")
.WithMode(HttpListenerMode.EmbedIO))
.WithLocalSessionManager()
.WithStaticFolder("/", Path.GetFullPath("wwwroot"), true);
server.StateChanged += (_, e) => Console.WriteLine($"Server state: {e.NewState}");
try
{
await server.RunAsync(shutdown.Token);
}
catch (OperationCanceledException) when (shutdown.IsCancellationRequested)
{
}
The controller methods below are excerpts for a WebApiController subclass.
Supply your application's SaveData method and request types, and register the
controller through WithWebApi as shown in CLI.md.
Reading from a POST body as a dictionary (application/x-www-form-urlencoded)
For reading a dictionary from an HTTP Request body inside a WebAPI method you can add an argument to your method with the attribute FormData.
[Route(HttpVerbs.Post, "/data")]
public async Task PostData([FormData] NameValueCollection data)
{
// Perform an operation with the data
await SaveData(data);
}
Reading from a POST body as a JSON payload (application/json)
For reading a JSON payload and deserialize it to an object from an HTTP Request body you can use GetRequestDataAsync<T>. This method works directly from IHttpContext and returns an object of the type specified in the generic type.
[Route(HttpVerbs.Post, "/data")]
public async Task PostJsonData()
{
var data = await HttpContext.GetRequestDataAsync<MyData>();
// Perform an operation with the data
await SaveData(data);
}
Reading from a POST body as a FormData (multipart/form-data)
EmbedIO doesn't provide the functionality to read from a Multipart FormData stream. But you can check the HttpMultipartParser Nuget and connect the Request input directly to the HttpMultipartParser, very helpful and small library.
A sample code using the previous library:
[Route(HttpVerbs.Post, "/upload")]
public async Task UploadFile()
{
var parser = await MultipartFormDataParser.ParseAsync(Request.InputStream);
// Now you can access parser.Files
}
There is another solution but it requires this Microsoft Nuget.
Writing a binary stream
You can open the Response Output Stream with the extension OpenResponseStream.
[Route(HttpVerbs.Get, "/binary")]
public async Task GetBinary()
{
// Call a fictional external source
using (var stream = HttpContext.OpenResponseStream())
await stream.WriteAsync(dataBuffer, 0, dataBuffer.Length);
}
WebSockets Example
Working with WebSocket is pretty simple, you just need to implement the abstract class WebSocketModule and register the module to your Web server as follow:
server.WithModule(new WebSocketsChatServer("/chat"));
And our web sockets server class looks like:
namespace EmbedIONeoExample
{
using System.Text;
using System.Threading.Tasks;
using EmbedIO.WebSockets;
/// <summary>
/// Defines a very simple chat server.
/// </summary>
public class WebSocketsChatServer : WebSocketModule
{
public WebSocketsChatServer(string urlPath)
: base(urlPath, true)
{
// placeholder
}
/// <inheritdoc />
protected override Task OnMessageReceivedAsync(
IWebSocketContext context,
byte[] rxBuffer,
IWebSocketReceiveResult rxResult)
=> SendToOthersAsync(context, Encoding.GetString(rxBuffer));
/// <inheritdoc />
protected override Task OnClientConnectedAsync(IWebSocketContext context)
=> Task.WhenAll(
SendAsync(context, "Welcome to the chat room!"),
SendToOthersAsync(context, "Someone joined the chat room."));
/// <inheritdoc />
protected override Task OnClientDisconnectedAsync(IWebSocketContext context)
=> SendToOthersAsync(context, "Someone left the chat room.");
private Task SendToOthersAsync(IWebSocketContext context, string payload)
=> BroadcastAsync(payload, c => c != context);
}
}
Support for SSL
The EmbedIO listener uses the runtime's TLS provider with an application-supplied
private-key certificate. Select HttpListenerMode.EmbedIO and WithCertificate
for hosting independently of Windows certificate registration. See the
HTTPS guide for desktop and .NET MAUI configuration,
client trust requirements, and platform validation limits. The Windows-only
restriction applies to the automatic certificate-store/netsh helpers below.
On Windows, Network Shell (netsh) maps an IP-port to a certificate. EmbedIO can
read or register certificates in the default store (My/LocalMachine) and use a
netsh sslcert binding for the first registered https prefix.
These inherited certificate-configuration examples are not a statement of tested support for older Windows versions or Mono. Validate HTTPS and certificate setup on the intended deployment platform.
Using a PFX file and AutoRegister option
The more practical case to use EmbedIO with SSL is the AutoRegister option. You need to create a WebServerOptions instance with the path to a PFX file and the AutoRegister flag on. This options will try to get or register the certificate to the default certificate store. Then it will use the certificate thumbprint to register with netsh the FIRST https prefix registered on the options.
Using AutoLoad option
If you already have a certificate on the default certificate store and the binding is also registered in netsh, you can use Autoload flag and optionally provide a certificate thumbprint. If the certificate thumbprint is not provided, EmbedIO will read the data from netsh. After getting successfully the certificate from the store, the raw data is passed to the WebServer.
Included modules
The solution contains the core server, test helpers, and
EmbedIO.JsonServer. JsonServer serves a JSON file as
REST collections without adding a runtime dependency beyond the core library.
using EmbedIO;
using EmbedIO.JsonServer;
using var server = new WebServer("http://localhost:9696/")
.WithModule(new JsonServerModule("/api/", "database.json"));
await server.RunAsync();
For a file containing {"posts":[{"id":1,"title":"Hello"}]}, use
GET /api/posts, GET /api/posts/1, POST /api/posts, PUT /api/posts/1, or
DELETE /api/posts/1. Authenticate access before exposing mutable data.
See Contributing for provenance, persistence
limits, and the disposition of the other archived Extras modules.
Build with the .NET 10 SDK specified in global.json. Libraries retain
.NET Standard 2.0 for existing consumers and also target .NET 10. Tests run on .NET 10. SWAN has been removed. The .NET 10 core has no external runtime packages; .NET Standard 2.0 uses Microsoft System.Text.Json. See the migration guide for the approved API and JSON changes.
Command-line server
The integrated CLI serves local folders and Web API/WebSocket plugins.
It shares this repository's core library and versioning and requires .NET 10.
Run dotnet run --project src/EmbedIO.Cli -- --help to get started.
Browse the documentation index for usage, platform, and migration guides.
See Neo baseline and direction for the initial changes, validation, acknowledgments, and planned work.
For configurable cycle handling in JSON responses, see the circular-reference guide.
For multiple static folders, see the mount order and fallback guide.
For asynchronous outbound requests from controllers, see the async response guide.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 10.0.12)
-
net10.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on EmbedIO-Neo:
| Package | Downloads |
|---|---|
|
EmbedIO-Neo.Testing
In-process HTTP testing helpers, mock file providers, and test resources for EmbedIO-Neo web servers. |
|
|
EmbedIO-Neo.DependencyInjection
Optional dependency injection and Generic Host integration for EmbedIO-Neo. |
|
|
EmbedIO-Neo.JsonServer
JSON file-backed REST module for EmbedIO-Neo. |
GitHub repositories
This package is not used by any popular GitHub repositories.