Metano.Build 2.1.0

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

Metano

Write shared domain code once in C#. Ship clean TypeScript today, with an experimental Dart/Flutter backend on the same IR.

Metano is a Roslyn-powered transpiler for teams that keep their backend in .NET and want to share domain code with frontend or app targets. Its primary target emits idiomatic TypeScript that fits normal JS tooling; an experimental Dart/Flutter target is also available for validating the multi-backend architecture.

NuGet npm License: MIT

Why Metano?

Most full-stack .NET products end up describing the same concepts twice: entities, DTOs, enums, validation rules, small calculations, and JSON contracts. Metano keeps C# as the source of truth and generates real target code, not only declaration stubs. TypeScript is the mature target today; Dart is intentionally documented as experimental while its coverage grows.

Use it when you want:

  • One domain model across backend and frontend without hand-maintained type mirrors.
  • Behavior as well as shapes: records, methods, operators, guards, LINQ, async, exceptions, and JSON serializer contexts.
  • Idiomatic generated code: modules, classes, interfaces, branded primitives, string unions, normal imports, and target-specific output where the backend supports it.
  • Low runtime weight: no .NET runtime in the browser, no global shim, only small helper imports when the emitted code needs them.
  • Native target workflow: generated TypeScript packages work with Bun, Vite, Vitest, Biome, ESLint, bundlers, and source maps; the Dart backend emits .dart files consumed by the Flutter sample.

What It Generates Today

using Metano.Annotations;

[assembly: TranspileAssembly]
[assembly: EmitPackage("sample-todo")]

namespace SampleTodo;

[StringEnum]
public enum Priority { Low, Medium, High }

public record TodoItem(string Title, bool Completed = false, Priority Priority = Priority.Medium)
{
    public TodoItem ToggleCompleted() => this with { Completed = !Completed };

    public TodoItem SetPriority(Priority priority) => this with { Priority = priority };

    public override string ToString() => $"[{(Completed ? "x" : " ")}] {Title} ({Priority})";
}
export const Priority = {
  Low: "low",
  Medium: "medium",
  High: "high",
} as const;

export type Priority = (typeof Priority)[keyof typeof Priority];

export class TodoItem {
  constructor(
          readonly title: string,
          readonly completed: boolean = false,
          readonly priority: Priority = "medium",
  ) {}

  toggleCompleted(): TodoItem {
    return this.with({ completed: !this.completed });
  }

  setPriority(priority: Priority): TodoItem {
    return this.with({ priority: priority });
  }

  toString(): string {
    return `[${this.completed ? "x" : " "}] ${this.title} (${this.priority})`;
  }

  equals(other: any): boolean {
    return (
            other instanceof TodoItem &&
            this.title === other.title &&
            this.completed === other.completed &&
            this.priority === other.priority
    );
  }

  hashCode(): number {
    const hc = new HashCode();
    hc.add(this.title);
    hc.add(this.completed);
    hc.add(this.priority);

    return hc.toHashCode();
  }

  with(overrides?: Partial<TodoItem>): TodoItem {
    return new TodoItem(
            overrides?.title ?? this.title,
            overrides?.completed ?? this.completed,
            overrides?.priority ?? this.priority,
    );
  }
}

Note: parts of the generated code were omitted for brevity and files got merged into this single example. The excluded part contains the imports, for example.

Feature Highlights

  • C# records, classes, structs, interfaces, delegates, inheritance, generics, overloads, extension methods, nullable types, async, exceptions, pattern matching, and nested types.
  • TypeScript-friendly output controls such as [StringEnum], [PlainObject], [Branded], [Ignore], [NoContainer], [GenerateGuard], [ObjectArgs], [Optional], and [Import].
  • BCL mappings for collections, LINQ, decimal, Guid, temporal types, BigInteger, tasks, strings, math, and console output.
  • Cross-project package generation with [EmitPackage], generated barrels, npm dependency updates, and package-aware imports.
  • System.Text.Json source-generation metadata emitted as a TypeScript SerializerContext.
  • TypeScript and Dart/Flutter compiler targets built on a shared IR.

Getting Started

The default walkthrough targets TypeScript, because that is the production path and the one wired into Metano.Build.

Prerequisites: .NET SDK 10.0 preview, C# preview features, and a JS runtime such as Bun.

dotnet add package Metano
dotnet add package Metano.Build

Point your C# project at a generated TypeScript package:

<PropertyGroup>
  <MetanoOutputDir>../my-domain-ts/src</MetanoOutputDir>
  <MetanoClean>true</MetanoClean>
</PropertyGroup>

Then build:

dotnet build

For manual runs:

dotnet tool install --global Metano.Compiler.TypeScript
dotnet metano-typescript -p path/to/YourProject.csproj -o path/to/output/src --clean

The full walkthrough is in Getting Started.

For the experimental Dart backend:

dotnet run --project src/Metano.Compiler.Dart/ -- \
  -p samples/SampleCounterV1/SampleCounterV1.csproj \
  -o targets/flutter/sample_counter/lib/sample_counter \
  --clean

See the Dart/Flutter roadmap and the Flutter sample target.

Documentation

Start here Purpose
Documentation home Map of the guides and references
Getting started First TypeScript project, build integration, generated package flow
Attribute reference Every public annotation and when to use it
BCL mappings How standard C# types lower, with current tables focused on TypeScript
Cross-project references Multi-project packages and generated imports
JSON serialization JsonSerializerContext support
Architecture Compiler pipeline, shared IR, TypeScript/Dart targets, and extension points
Comparison How Metano differs from Blazor, Bridge.NET, NSwag, and Fable
ADRs Design decisions behind the current architecture

Samples

  • HelloWorld — top-level statements and the smallest generated module.
  • SampleTodo — records, string enums, LINQ overloads, and JSON serializer context output.
  • SampleTodo.Service — Hono service, cross-package imports, DTOs, and module entry points.
  • SampleIssueTracker — richer domain model with branded IDs, aggregates, LINQ, inheritance, and repositories.
  • SampleOperatorOverloading — value objects, operator overloads, exceptions, and BigInteger.
  • SampleCounterV1 through SampleCounterV5 — UI-oriented counter variants covering MVP, MVU, component models, Inferno interop, SolidJS interop, and a related Dart/Flutter target.

Generated TypeScript lives under targets/js. Experimental Dart output is exercised by targets/flutter/sample_counter.

Contributing

Metano is young and moving quickly. Before changing compiler behavior, read the architecture guide and the relevant architecture decision records.

Useful local checks:

dotnet run --project tests/Metano.Tests/
dotnet csharpier format .
bunx biome check .

Versions are computed from git tags with MinVer. Releases publish the NuGet packages plus the metano-runtime npm package.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

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
2.1.0 27 5/2/2026
2.0.0 26 5/1/2026
1.1.0 37 5/1/2026
1.0.3 64 4/30/2026
1.0.2 57 4/30/2026
0.9.0 80 4/29/2026
0.8.1 86 4/27/2026
0.8.0 84 4/25/2026
0.7.0 91 4/23/2026
0.6.1 101 4/22/2026
0.6.0 89 4/22/2026
0.5.0 90 4/17/2026
0.4.2 111 4/14/2026
0.4.1 99 4/13/2026
0.4.0 103 4/13/2026
0.3.0 106 4/12/2026
0.2.0 97 4/11/2026
0.1.0 107 4/11/2026