Table of Contents

Use WebScene with Avalonia

WebSceneComponentHost is the recommended Avalonia integration. It accepts a versioned component package, validates its manifest and assets, performs compatibility preflight, creates the native view, mounts the JavaScript lifecycle, and cleans it up with the Avalonia visual tree.

For the complete package format and host-bridge contract, see Package and host a component.

1. Add the packages

Declare one supported RID and reference the component host plus the matching native runtime. Replace VERSION with the same component-host-capable version for every WebScene package:

<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
  <RuntimeIdentifier>osx-arm64</RuntimeIdentifier>
  <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="Avalonia.Desktop" Version="11.3.4" />
  <PackageReference Include="Avalonia.Skia" Version="11.3.4" />
  <PackageReference Include="WebScene.Sdk.Avalonia" Version="VERSION" />
  <PackageReference Include="WebScene.NativeEngine.Runtime.osx-arm64"
                    Version="VERSION" />
</ItemGroup>

Use linux-x64 or win-x64 in both the RuntimeIdentifier and runtime package for the other published desktop targets. The native component host is available on main; use a project reference to src/WebScene.Sdk.Avalonia until a package containing that implementation is published.

2. Package the web-authored component

Place webscene-component.json beside its declared assets:

components/
  StatusPanel/
    webscene-component.json
    dist/main.js
{
  "schemaVersion": "1.0",
  "id": "com.example.status-panel",
  "displayName": "Status panel",
  "version": "1.0.0",
  "profileVersion": "1.0",
  "entryPoint": "dist/main.js",
  "assets": ["dist/main.js"],
  "capabilities": ["dom", "css.layout", "input.pointer"],
  "lifecycle": {
    "mountExport": "mount",
    "unmountExport": "unmount"
  }
}

The JavaScript bundle must publish the configured mount and unmount functions on globalThis. Copy the whole package to output without flattening it:

<ItemGroup>
  <Content Include="components/**"
           CopyToOutputDirectory="PreserveNewest"
           CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>

3. Add the host in XAML

<Window
    x:Class="WebSceneDemo.MainWindow"
    xmlns="https://github.com/avaloniaui"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ws="using:WebScene.Sdk.Avalonia">
  <ws:WebSceneComponentHost
      x:Name="ComponentHost"
      PackagePath="components/StatusPanel" />
</Window>

PackagePath is relative to AppContext.BaseDirectory. With the default AutoMount="True", no Opened handler, native-library resolver, or direct LoadAsync call is needed. The host mounts when attached and unmounts when detached. Dispose it when the owning window lifetime ends:

Closed += async (_, _) => await ComponentHost.DisposeAsync();

If the application needs to register host capabilities or startup hooks, set AutoMount="False", configure the host, and call MountAsync after the control is attached, for example from Window.Opened. See Grant application capabilities.

Interoperate and diagnose

The component host installs a capability-gated asynchronous bridge for component-to-.NET calls. For .NET-to-JavaScript generated bindings and diagnostic evaluation, use its underlying view:

string result = await ComponentHost.View.EvaluateTextAsync(
    "({ title: document.title, readyState: document.readyState })");

using var interop = ComponentHost.View.CreateJavaScriptInvoker();
// Pass interop to a facade generated by WebScene.JavaScript.Interop.Generator.

Use ComponentHost.State, LastException, CompatibilityReport, Diagnostics, and DiagnosticReported for component-level failures. ComponentHost.View.RenderDiagnostics, CapturePerformanceSnapshot(), DrainConsoleMessages(), and OpenV8InspectorSession expose lower-level runtime diagnostics.

Advanced: host a document directly

WebScene.Backend.Avalonia.NativeWebSceneView remains available for applications that deliberately need direct document navigation, custom resource loading, or backend-level experiments rather than a packaged component.

<Window
    xmlns="https://github.com/avaloniaui"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:native="clr-namespace:WebScene.Backends.Avalonia.Native;assembly=WebScene.Backend.Avalonia">
  <native:NativeWebSceneView x:Name="WebContent" />
</Window>
var document = new Uri(
    Path.Combine(AppContext.BaseDirectory, "web", "index.html"));

await WebContent.LoadAsync(
    document.AbsoluteUri,
    nativeLibraryPath,
    compilationCacheDirectory,
    cancellationToken);

Direct hosting means the application owns URL policy, native-library resolution, navigation cancellation, resource layout, interop disposal, unload, and view disposal. Choose it only when the component host's package model is not appropriate.

The backend-level integration authority remains the Avalonia native runtime showcase. Continue with Lifecycle and diagnostics and Packages and deployment.