Available on NuGet Read more

Transpose: The C# to JavaScript Compiler

Write browser front-ends in statically-typed C# and compile them to JavaScript that runs in any browser.

Why Transpose?

C# in the browser

Write your application logic, UI components, and algorithms in C#. Transpose compiles them to JavaScript that runs in any browser, on any device.

Compile-time type checking

The compiler is built on Roslyn, so browser code gets the same type checking, generics, nullable analysis, and error messages as the rest of your .NET solution. A misspelled member is a CS… build error rather than a runtime undefined is not a function.

One toolchain with the rest of .NET

Transpose.Core provides strongly-typed bindings for the DOM and the ES5/ES6 APIs, Transpose.Newtonsoft.Json gives you Json.NET-style serialization, and Transpose.HttpClient gives you HttpClient. Anything else is reachable through Script.Write or an [External] binding you declare yourself.

Fast rebuilds

tps is a plain CLI, invoked once per project by the Transpose.Build.Target MSBuild SDK. Incremental builds reuse the previous compilation when the inputs hash the same, and tps --watch rebuilds the site and reloads the browser on every save.


Write C#. Run it in the browser.

Transpose maps C# types onto the JavaScript runtime it ships (tps.js), keeping .NET semantics for the constructs it emits.

The C# source

public class TodoItem
{
    public int Id { get; set; }
    public string Task { get; set; }
    public bool IsDone { get; set; }

    public void Toggle()
    {
        this.IsDone = !this.IsDone;
        Console.WriteLine($"Task {Id} is now {(IsDone ? "done" : "pending")}");
    }
}

The Transpose output

Transpose.define("App.TodoItem", {
    fields: {
        Id: 0,
        Task: null,
        IsDone: false
    },
    methods: {
        Toggle: function () {
            this.IsDone = !this.IsDone;
            System.Console.WriteLine("Task " + this.Id + " is now " + (this.IsDone ? "done" : "pending"));
        }
    }
});

Your type and member names are preserved, so the output stays readable. The runtime global is Transpose; language helpers are reached through TransposeR.


Toolchain

  • Target framework: projects target .NET Standard 2.0 or 2.1, so types can be shared with a back-end project.
  • Built on Roslyn: the compiler binds with Roslyn and emits JavaScript directly from the syntax tree, using the same front end as the C# compiler.
  • MSBuild SDK: a project sets Sdk="Transpose.Build.Target/<version>" and dotnet build runs the compiler. There is no global-tool compiler to install and no compilation server.
  • Diagnostics in MSBuild's canonical format: compile errors land in the IDE error list, navigable to the file and line.

Packages

See NuGet Packages for the full list.


Get started

1. Create a project file:

MyWebProject.csproj
<Project Sdk="Transpose.Build.Target/*">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Transpose.BCL" Version="*" />
    <PackageReference Include="Transpose.Core" Version="*" />
  </ItemGroup>
</Project>

2. Build:

dotnet build

3. Serve the output:

dotnet tool install --global dotnet-serve
dotnet serve ./bin/Debug/netstandard2.0/tps/

Replace each * with the latest published version — see Getting Started for the full walkthrough.


Coming from h5?

Transpose is the next generation of the h5 compiler, rebuilt around a Roslyn translator and rebranded. Porting an existing project is mostly a rename of packages, the config file, and namespaces — see Migrating from h5.


Ready to build?

Download Transpose on NuGet

Get the latest version of the base library.

Browse the source

The compiler, the BCL, and the binding libraries.

Changelog

What changed in each release.

Transpose lets you build for the browser in C#, compiled to standards-compliant JavaScript.

© 2026 Curiosity. All rights reserved.