Shenora 0.24.0

dotnet add package Shenora --version 0.24.0
                    
NuGet\Install-Package Shenora -Version 0.24.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Shenora" Version="0.24.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shenora" Version="0.24.0" />
                    
Directory.Packages.props
<PackageReference Include="Shenora" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Shenora --version 0.24.0
                    
#r "nuget: Shenora, 0.24.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Shenora@0.24.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Shenora&version=0.24.0
                    
Install as a Cake Addin
#tool nuget:?package=Shenora&version=0.24.0
                    
Install as a Cake Tool

Shenora

Shenora (神阙)

NuGet npm .NET 10 License: MIT

A hybrid app framework for .NET + React, on Windows, macOS, Linux, Android and iOS. Your interface is a React page and your app's logic is .NET. Shenora is everything between them: the shell that hosts the page, typed IPC across the seam, windows, native services and the modules that reach the platform. An app ships its domain logic and its screens, and nothing else.

神阙 (shénquè), "the spirit's gate": the classical Chinese name for the navel, where the body was first joined to what fed it.

.NET does the platform work, React does the interface, and the kit owns the seam between them. It is a framework, not a media library or a file library: those are capabilities it carries. Its sibling Lyntai (灵台) is the AI brain, and the two never depend on each other.

Why Shenora

  • Native .NET, not a JavaScript bridge. Capacitor and Electron give you a webview and a bridge, so their ceiling is the web platform plus plugins. Here it is .NET's: real threads, real handles, the platform SDKs, background execution. The kit's job is the translation layer, which is to say what .NET can do and React cannot.
  • One typed IPC on every shell. Correlated requests, batched events and structured errors, in the same envelope over WebView2, the kit's Chromium shell and MAUI's HybridWebView. The host tells the page what it offers in the handshake, so one web bundle serves every shell.
  • Your choice of engine on the desktop. WebView2 in a WinForms shell for a small Windows app, or the kit's own Chromium shell (CEF) for one engine on Windows, macOS and Linux, with frameless windows, a native splash, a tray, file dialogs and one instance per install.
  • Media the webview cannot play. Probe, plan, remux, or convert while it plays. On a phone the shell can draw the picture itself, under a transparent region the page leaves, so a film the webview refuses plays with no transcode and the page keeps every control; when the app goes to the background, a native player carries on.
  • The desktop services an app needs. Window state that survives a DPI change, single instance that hands a later launch's arguments to the running app, secondary windows, drag and drop with real paths, the clipboard, and extra browsers: off-screen, interactive and streamed.
  • Safe file changes and updates. A journalled file-update queue with path locks, a self-updater that applies only a release whose every file matched its hash, and a native launcher that applies it before your app starts and can show a startup screen until your first window.
  • Logic that stays portable. App logic references only Shenora (net10.0) and injects the contracts it needs; a sample project turns red the moment a Windows type reaches it.
  • Headless. No UI component library and no design system: you bring your own React.

Quickstart

The kit's Chromium shell, which is one project on Windows, macOS and Linux. On Windows alone, Shenora.Windows and UseWindows give you the same window in WinForms and WebView2 (getting started, step 2).

<PropertyGroup>
  <OutputType>WinExe</OutputType>
  <TargetFramework>net10.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <AssemblyName>MyApp.App</AssemblyName>
  <RootNamespace>MyApp</RootNamespace>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Shenora.Chromium" Version="0.24.0" />
  <EmbeddedResource Include="wwwroot\**" WithCulture="false" />
</ItemGroup>

The build lays the app out as MyApp, which starts MyApp.App; the runtime identifier is the OS you build for (osx-arm64, osx-x64, linux-x64, linux-arm64, win-x64, win-arm64); wwwroot is your built React page.

using Shenora;
using Shenora.Chromium;
using Shenora.Core.Ipc;
using Shenora.Core.WebView;

static class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var builder = ShenoraApplication.CreateBuilder(new ShenoraApplicationOptions { Args = args, ApplicationName = "My App" });
        builder.UseChromium(new ChromiumHostOptions
        {
            ResourceProvider = new EmbeddedResourceProvider(new EmbeddedResourceProviderOptions
            {
                Assembly = typeof(Program).Assembly,
                ResourcePrefix = "MyApp.wwwroot",
            }),
            Window = new ChromiumWindowOptions
            {
                Title = "My App", Width = 1000, Height = 760, Path = "index.html",
                FramelessChrome = false,   // the OS's title bar; frameless, the default, has the page draw its own
            },
        });
        builder.Services.AddIpcModule<GreetingModule>();

        using var app = builder.Build();
        app.Run();
    }
}

sealed class GreetingModule : ModuleBase
{
    public override string ModuleName => "GREETING";

    protected override Task<object?> RouteMessageAsync(IpcRequest request, IModuleContext context, CancellationToken ct) =>
        request.Type switch
        {
            "HELLO" => Task.FromResult<object?>($"Hello from .NET {Environment.Version}"),
            _ => throw UnknownType(request),
        };
}
// npm i @shenora/react
import { getBridge } from '@shenora/react';

await getBridge().notifyReady();                                   // the host's events flow from here
const greeting = await getBridge().invoke<string>('GREETING', 'HELLO');

The first build fetches the pinned CEF build once per machine and lays the app out. A failed call rejects with a ShenoraError: a ShenoraException's own code, parameters and message, or for any other exception UNKNOWN_ERROR and its type name, never its text. Getting started goes on to the dev server, a splash, window state, and onto a phone.

What's in the box

You want Reach for Read
A window around a React page, on Windows Shenora.Windows, UseWindows (WinForms + WebView2) getting started, 2
One desktop app for Windows, macOS and Linux Shenora.Chromium, UseChromium getting started, 2b
The same app on a phone Shenora.Android, Shenora.iOS over MAUI's HybridWebView mobile
Typed calls and events between page and host ModuleBase, AddIpcModule<T>(), getBridge(), useShenoraEvent the IPC stack
Progress and cancellation for long work context.Report(…), useShenoraRequests() the IPC stack
Windows, tray, dialogs, clipboard, single instance WindowsHostOptions, ChromiumHostOptions, IFileDialogs, IClipboardService the Windows shell, the Chromium shell
Local files in <video>, <audio> and <img> IWebViewInterceptor, UseFiles(…) serving files
A file the webview cannot decode Shenora.Modules.Media, useMediaSurface, useMediaTransport media
Background work with claims, lanes and a durable queue IMissionScheduler missions
Safe file changes and self-update Shenora.Engine.Files, UpdateStage, Shenora.Launcher file updates
Extra browsers: off-screen, interactive, streamed RenderSessionPool, InteractiveSession, StreamingSession sessions
A build onto a simulator, an iPhone or an Android device npx shenora ios deploy, npx shenora android deploy @shenora/cli

Packages

Versioned in lockstep. Reference one shell for the platform you build for and it brings Shenora; the packages, one by one has how the set is shaped and enough of each to get it working.

Package Registry Target framework In one line
Shenora NuGet net10.0 The application host and the platform-neutral contracts your logic compiles against, plus the capabilities that are shell work rather than extras: media (Shenora.Modules.Media), file operations and the self-updater (Shenora.Engine.Files, Shenora.Engine.Update), archive extraction (Shenora.Engine.Compression), the mission scheduler (Shenora.Engine.Missions) and the extra browsers (Shenora.Core.Sessions).
Shenora.Windows NuGet net10.0-windows or net10.0-windows10.0.17763.0 The Windows shell: bootstrap, windows, tray, dialogs, single instance, WebView2 hosting and its IPC bridge, and the extra browsers in WebView2. The versioned TFM adds Windows' media controls and a Media Foundation player.
Shenora.Chromium NuGet net10.0 (Windows, macOS and Linux, x64 and arm64) Chromium through CEF: a complete shell of its own (UseChromium) on every desktop OS, and the ChromiumView control Shenora.Windows hosts. CEF is not in the package: your app's build fetches the pinned CEF build, so reference it from the app's own project.
Shenora.Android NuGet net10.0-android The Android shell: the same IPC envelope over MAUI's HybridWebView.
Shenora.iOS NuGet net10.0-ios The iOS shell, sharing its MAUI half with Shenora.Android, plus AVPlayer, Now Playing and Live Activities.
Shenora.Launcher NuGet native (win-x64, linux-x64) The native launcher that applies a staged update before your app starts, for a framework-dependent app, and can show a startup screen until its first window. A self-contained app needs none of it.
@shenora/react npm ES2022 / ESM · React ≥ 18 The page half: bridge, event bus, stores and hooks.
@shenora/cli npm Node 20+ Build-time only, a devDependency. The shenora binary that takes a built app onto a simulator, an iPhone or an Android device, with no Xcode project of your own.

There are no optional feature packages. Media, files, missions, updates and archives are namespaces inside Shenora, so a reference to Shenora plus your platform's shell is all of it.

Status

v0.24.0 — pre-release, stabilising toward 1.0. Every public and protected member is documented and gated by API-surface baselines. The WinForms shell, WebView2 hosting, the IPC stack, the native desktop services and the extra browsers are extracted from in-house applications that had already shipped them; the Chromium shell, the mobile shells and the segment media tier were built in this repository.

Where it has run: Windows; macOS (x64) and Linux (x64, under WSL and Xvfb) through the Chromium shell; an Android device (IPC, events, the file picker, the mission scheduler); and an iPhone 17 Pro (also media playback, the save picker, audio conversion and Live Activities). What has not yet run (the arm64 desktop builds, the published package's Linux helper, a real GNOME or KDE session) is listed in TASKS.md.

This page describes the working tree, not only the newest package: anything that has not shipped yet is under ## Unreleased in CHANGELOG.md, so check there before assuming a member is in the version you installed.

Versioning. Every public change is SemVer surface, and until 1.0 a minor release may break one: it is always listed under that release's ### Breaking heading in CHANGELOG.md, with what to change. 1.0 is a deliberate freeze, not yet cut.

The segment (streaming) media tier had no application to prove it before it shipped. It is checked against a corpus of sources muxed by other tools (MP4Box, Bento4, mkvmerge, Apple), by a decoder, a real browser MediaSource and a real iPhone. On Android it has run on the emulator, not yet on a phone.

Documentation

For AI coding agents

Shenora publishes llms.txt, an index of these docs written for language models, and a context7.json telling the Context7 documentation index what to serve. The rules a coding agent most often gets wrong when it writes an app on Shenora:

  • Reference ONE shell package and it brings Shenora: Shenora.Windows (WinForms + WebView2, Windows only), Shenora.Chromium (UseChromium, on Windows, macOS and Linux), Shenora.Android or Shenora.iOS. The page imports @shenora/react.
  • Media, files, missions, updates and archives are namespaces inside Shenora (Shenora.Modules.Media, Shenora.Engine.Files, .Missions, .Update, .Compression), never packages of their own.
  • Retired package ids, never to reference: Shenora.Core, Shenora.Ipc, Shenora.Media, Shenora.IO, Shenora.IO.Compression, Shenora.WinForms, Shenora.WebView2, Shenora.WebView2.Sessions. The IPC types are in namespace Shenora.Core.Ipc.
  • Compose with ShenoraApplication.CreateBuilder(…), one shell call (UseWindows, UseChromium, UseAndroid or UseIOS), then Build(). A desktop app calls Run() from an [STAThread] Main; a phone app calls Start()/Stop() from its lifecycle.
  • Build() registers the framework itself (the dispatcher, the event bus, the kit's modules, the mission scheduler); an engine Use… call such as UseMissions changes what it registers rather than enabling it.
  • A host route is a class derived from ModuleBase that names its ModuleName and switches on request.Type, registered with services.AddIpcModule<T>().
  • The page calls a route with getBridge().invoke(module, type, { payload }): the payload goes in the options object, and the module and type strings must match the host's exactly.
  • For an error the page should show, throw ShenoraException: its code, parameters and message cross verbatim, so never build one from ex.Message. Any other arrives as UNKNOWN_ERROR with only its type name, a cancellation as OPERATION_CANCELLED.
  • Keep invoke for quick calls: a route's synchronous part runs on the shell's UI thread. Start slow work with post, report with context.Report(…) and context.Publish(…), and read it with useShenoraEvent or useShenoraRequests().
  • Call getBridge().notifyReady() once at page start: the host holds its events until then. It resolves to the ShellInfo the app declared (the Shell option of its shell or IPC bridge), or undefined when it declared none.
  • Show a feature when ShellInfo.capabilities names it, never by sniffing the OS or the user agent.
  • App logic for every shell goes in a plain net10.0 project that references only Shenora and injects the contracts (IUiDispatcher, IFileDialogs, IClipboardService, IUrlLauncher); a WinForms, WebView2 or MAUI type there breaks the other shells.

Contributing

Issues and pull requests are welcome. The working conventions are CLAUDE.md, the documentation map is docs/README.md, and node devtools/dev.mjs verify is the "am I done?" check every change passes (build, tests, type checks and the doc gates). Running node devtools/dev.mjs with no argument prints every verb. Requirements: the .NET 10 SDK, Node 22+, and a JDK for the Android head. Outside the maintainer's machine, set SHENORA_ALLOW_BUILTIN_PATTERNS_ONLY=1: the leak scan fails closed without the private pattern list.

License

MIT © Jiarong Gu.

Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Shenora:

Package Downloads
Shenora.Windows

The Windows shell of Shenora, the hybrid app framework for .NET + React: application bootstrapper with global exception handling, DPI-correct window-state persistence, one instance per install, a later launch handing the running app its arguments, secondary windows on their own STA threads, tray icon, frameless-chrome form, the main form's system animations on or off, a native launcher's startup screen closed once the main form shows, and the Windows implementations of the Shenora shell contracts (STA file dialogs, clipboard, UI-thread dispatcher). Hosts WebView2: environment prewarm, dev-server vs packaged-frontend loading, navigation/new-window/download/permission/process-failure handling, a page of the app's own for a page load that finds nothing, drag-drop zones, the app's colour scheme set on the profile of each WebView given it, and the postMessage IPC bridge with batched event push. Hosts Chromium the same way, through Shenora.Chromium: a ChromiumView control, with UseChromiumEngine running CEF beside the WinForms loop; reference Shenora.Chromium from the app itself, since CEF arrives only through that package's build. Hosts the auxiliary browser sessions (Shenora.Core.Sessions) in WebView2: WebView2SessionHost makes their off-screen browsers and an interactive session's modal window.

Shenora.Android

The Android shell of Shenora, the hybrid app framework for .NET + React: the MAUI HybridWebView IPC transport (the same envelope the desktop shell speaks, over SendRawMessage/RawMessageReceived), the resource interceptor that answers a page's byte ranges, a UI-thread dispatcher, safe-area insets, the SYSTEM BACK GESTURE offered to the page before the platform finishes the activity under it, foreground transitions carrying how long the app was away, holding the window portrait or landscape (which a page can only do in fullscreen), and the Android implementations of the Shenora shell contracts — native file dialogs, a MediaCodec-backed audio and video conversion pipeline with device capability probing, a MediaPlayer-backed media player that can draw its picture into a native surface the page positions, and a MediaSession playback session for headphone and system media controls (the shade and lock screen show it through a MediaStyle notification, which is the app's). The platform owns the loop, so the app drives ShenoraApplication.Start/Stop from its own lifecycle rather than calling Run. Shares its source with Shenora.iOS.

Shenora.iOS

The iOS shell of Shenora, the hybrid app framework for .NET + React: the MAUI HybridWebView IPC transport (the same envelope the desktop shell speaks, over SendRawMessage/RawMessageReceived), the resource interceptor that answers a page's byte ranges, a UI-thread dispatcher, safe-area insets, foreground transitions carrying how long the app was away, holding the window portrait or landscape (which a page can only do in fullscreen — one line in your app delegate makes it a real lock rather than a request the next rotation undoes), and the iOS implementations of the Shenora shell contracts — native file dialogs, an AudioToolbox/VideoToolbox conversion pipeline with device capability probing, an AVPlayer media player that can draw its picture into a native surface the page positions, and a Now Playing playback session. The platform owns the loop, so the app drives ShenoraApplication.Start/Stop from its own lifecycle rather than calling Run. Shares its source with Shenora.Android. Also ships the Live Activity devkit: one MSBuild property turns on a generic widget the app describes from C#, and the package supplies the ActivityKit shim, the state mirror and the build step that produces and signs the widget extension; an app may supply its own SwiftUI views instead.

Shenora.Chromium

Chromium for Shenora, the hybrid app framework for .NET + React, through CEF, for an app that ships its own browser engine instead of WebView2. UseChromium is a shell of the kit's own, and a complete one: an app on Windows, macOS or Linux needs no other shell package. A splash the app composes in C#, drawn natively in the main window's render area while Chromium starts, with the window's own frame live around it (and, optionally, a card before the window exists), lifted once the page is ready. Its page comes from a folder or from resources embedded in the app's assembly, with a page of the app's own for a page load that finds nothing. The app's colour scheme, light, dark or the OS's, set on Chromium itself, so the page's prefers-color-scheme and Chrome's own UI follow it. CEF's windows with frameless chrome (real caption buttons and Snap Layouts on Windows), file drops with real paths, native file dialogs, the clipboard, a tray, one instance per install that hands a later launch's arguments to the running app (on macOS the files and links it is opened with too), a main window that opens where it was left (with WindowState set), a window's system animations on or off, a native launcher's startup screen closed once the app's first window is on screen, secondary windows, revealing files and launching processes, naming who holds a file open, the app's unhandled exceptions, the main window's input taken while something modal runs, crash reload and dev-server hot reload, with IPC over a transport that needs no code in the renderer. It hosts the auxiliary browser sessions too: windowless browsers for the pool and streaming, and a window of its own for an interactive session. ChromiumEngine and ChromiumChildBrowser embed a page in a window the host owns, which is how Shenora.Windows hosts one beside its WebView2 control. ChromiumBrowserProcess runs Chromium as a browser of its own, in a second process of the app's executable: Chromium's own windows and a debugging port for an agent's tools, with no app page in reach of it. CEF itself is not in the package: the app's build fetches the pinned CEF build, checks its SHA-1, and lays the app out, on Windows beside CEF's launcher with the kit's shim, which is what gives Chromium its sandbox (a Windows publish can instead keep three files at its root, with CEF in engine\ and the app in lib\: ShenoraChromiumPublishFolders), and on macOS as an app bundle whose helpers sandbox each subprocess. Reference it from the app's own project, with a RuntimeIdentifier and an assembly named <App>.App. Windows (x64, arm64), macOS (x64, arm64), where the build makes an app bundle, and Linux (x64, arm64), where it lays the app out beside the kit's helper, which every Chromium subprocess runs.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.24.0 121 10/23/2026
0.23.2 121 10/21/2026
0.23.1 105 10/21/2026
0.23.0 107 10/21/2026
0.22.0 112 10/19/2026
0.21.1 118 10/12/2026
0.21.0 112 10/8/2026
0.20.0 114 10/7/2026
0.19.1 117 10/1/2026
0.19.0 123 9/30/2026
0.18.0 125 9/29/2026
0.17.1 130 9/29/2026
0.17.0 133 9/29/2026
0.16.0 179 8/23/2026
0.15.0 144 8/23/2026
0.14.0 170 8/22/2026
0.13.0 134 8/21/2026
0.12.0 148 8/20/2026
0.11.0 170 8/17/2026