Skip to content

Add new webworker template project#65037

Merged
ilonatommy merged 50 commits intodotnet:mainfrom
ilonatommy:webworker-template-as-item
Feb 6, 2026
Merged

Add new webworker template project#65037
ilonatommy merged 50 commits intodotnet:mainfrom
ilonatommy:webworker-template-as-item

Conversation

@ilonatommy
Copy link
Member

@ilonatommy ilonatommy commented Jan 13, 2026

Worker Class Library template ( dotnet new webworker)

Summary

Adds a new .NET Web Worker project template that provides infrastructure for running .NET code in a WebWorker, keeping your WebAssembly UI responsive during heavy computations.

Background

Blazor WASM applications with heavy computing had to rely on server requests. Computing on the UI thread interfered with UI rendering and affected UX. In .NET 10 we added an article with a sample application to make offloading heavy work to a WebWorker easier. In .NET 11 we decided to add official template support. This PR adds a project template that enables running .NET code in a WebWorker.

Template Output

MyWebWorker/
├── MyWebWorker.csproj
├── WorkerClient.cs              # C# client with factory pattern
└── wwwroot/
    ├── worker-client.js         # JS WorkerClient class
    └── dotnet-web-worker.js     # Worker entry point

Usage

# 1. Create Blazor WebAssembly app
dotnet new blazorwasm -n MyApp

# 2. Create .NET Web Worker
dotnet new webworker -n MyWebWorker

# 3. Add reference
cd MyApp
dotnet add reference ../MyWebWorker/MyWebWorker.csproj

# 4. Add AllowUnsafeBlocks to app (required for [JSExport])
# <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

# 5. Create worker methods in the app
// In MyApp - worker methods with [JSExport]
[SupportedOSPlatform("browser")]
public static partial class MyWorker
{
    [JSExport]
    public static string Greet(string name) => $"Hello, {name}!";

    [JSExport]
    public static string GetUsers()
    {
        var users = new List<User> { new("Alice", 30), new("Bob", 25) };
        return JsonSerializer.Serialize(users);  // Serialize before returning
    }
}

public record User(string Name, int Age);

// In component
await using var worker = await WebWorkerClient.CreateAsync(JSRuntime);

// String result
var greeting = await worker.InvokeAsync<string>("MyApp.MyWorker.Greet", ["World"]);

// Complex result (automatically deserialized)
var users = await worker.InvokeAsync<List<User>>("MyApp.MyWorker.GetUsers", []);

Methods

public sealed class WebWorkerClient(IJSObjectReference worker) : IAsyncDisposable
{
    public static async Task<WebWorkerClient> CreateAsync(IJSRuntime jsRuntime);
    public async Task<TResult> InvokeAsync<TResult>(string method, object[] args, CancellationToken cancellationToken = default);
    public async ValueTask DisposeAsync();
}

Fixes dotnet/runtime#95452

@ilonatommy ilonatommy added this to the 11.0-preview1 milestone Jan 13, 2026
@ilonatommy ilonatommy self-assigned this Jan 13, 2026
@ilonatommy ilonatommy added the area-blazor Includes: Blazor, Razor Components label Jan 13, 2026
The webworker item template generates a .csproj file into the content/
folder during build. NuGet was discovering and trying to restore this
generated project, but it failed because:

1. The package Microsoft.AspNetCore.Components.WebAssembly version
   11.0.0-ci doesn't exist in NuGet feeds (it's built in this repo)
2. The generated project was being evaluated before the package was built

Fix: Add Web.ItemTemplates/content/**/*.proj to ProjectToExclude in
eng/Build.props, matching the existing exclusion for Web.ProjectTemplates.

Also simplified Directory.Build.props in the content folder to remove
the sources.props import which is no longer needed since the projects
are excluded from build.
The ByteOrderMarkTest requires all .razor files in templates to have
UTF-8 BOM (Byte Order Mark) for proper encoding detection.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new dotnet new webworker template that enables WebWorker support for Blazor WebAssembly applications, allowing compute-intensive .NET code to run off the main UI thread for improved responsiveness. The template provides both an infrastructure-only mode (--empty) and a full mode with demo code showcasing GitHub API integration.

Changes:

  • New WebWorker item template with client library, JavaScript worker infrastructure, and optional demo files
  • Integration with BlazorWeb template to optionally include WorkerClient project
  • Comprehensive README documentation and localization for 13 languages

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/.template.config/template.json Template configuration defining parameters, symbols, and post-actions
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/WebWorkerTemplate.WorkerClient/WorkerClient.cs C# client for communicating with WebWorker via JSInterop
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/WebWorkerTemplate.WorkerClient/wwwroot/worker.js JavaScript WebWorker entry point for loading .NET runtime
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/WebWorkerTemplate.WorkerClient/wwwroot/worker-client.js JavaScript client for managing worker lifecycle and message passing
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/Worker/GitHubWorker.cs Demo worker class showing GitHub API data processing
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/Pages/WebWorkerDemo.razor.cs Demo Blazor page comparing WebWorker vs UI thread performance
src/ProjectTemplates/Web.ItemTemplates/content/WebWorker/Models/GitHubModels.cs Model classes for GitHub API responses
src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/.template.config/template.json Updated to reference WorkerClient project
src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1.sln Solution file with conditional WorkerClient project inclusion
src/ProjectTemplates/Web.ItemTemplates/Microsoft.DotNet.Web.ItemTemplates.csproj Build configuration for generating WorkerClient.csproj
eng/Build.props Updated to exclude template content projects from build
src/ProjectTemplates/Web.ItemTemplates/.gitignore Ignore generated .csproj files
Multiple localization files Translated template descriptions for 13 languages

…harp/WorkerClient.cs

Co-authored-by: Daniel Roth <daroth@microsoft.com>
@ilonatommy ilonatommy removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jan 29, 2026
@ilonatommy ilonatommy requested a review from javiercn February 4, 2026 08:32
Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Let's get it in for now and we'll get to play with it and refine it if necessary

@ilonatommy ilonatommy merged commit de6ec42 into dotnet:main Feb 6, 2026
25 checks passed
akoeplinger added a commit to dotnet/sdk that referenced this pull request Feb 15, 2026
Add .NET entry to approval baselines after dotnet/aspnetcore#65037
introduced the webworker template.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET Web Worker docs, samples, and project template

5 participants