Shenora.iOS 0.25.0

dotnet add package Shenora.iOS --version 0.25.0
                    
NuGet\Install-Package Shenora.iOS -Version 0.25.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.iOS" Version="0.25.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shenora.iOS" Version="0.25.0" />
                    
Directory.Packages.props
<PackageReference Include="Shenora.iOS" />
                    
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.iOS --version 0.25.0
                    
#r "nuget: Shenora.iOS, 0.25.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.iOS@0.25.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.iOS&version=0.25.0
                    
Install as a Cake Addin
#tool nuget:?package=Shenora.iOS&version=0.25.0
                    
Install as a Cake Tool

logo 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.

Contents: Why Shenora · Quickstart · What's in the box · Packages · Status · Documentation · For AI coding agents · Contributing · License

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.25.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.25.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-ios26.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.25.0 0 11/4/2026
0.24.0 109 10/23/2026
0.23.2 103 10/21/2026
0.23.1 106 10/21/2026
0.23.0 95 10/21/2026
0.22.0 101 10/19/2026
0.21.1 102 10/12/2026
0.21.0 98 10/8/2026
0.20.0 103 10/7/2026
0.19.1 99 10/1/2026
0.19.0 98 9/30/2026
0.18.0 98 9/29/2026
0.17.1 92 9/29/2026
0.17.0 101 9/29/2026
0.16.0 129 8/23/2026
0.15.0 121 8/23/2026
0.14.0 125 8/22/2026
0.13.0 125 8/21/2026
0.12.0 126 8/20/2026
0.11.0 158 8/17/2026
Loading failed