Compile-time i18n for .NET
Zero-allocation translations via source generators. ICU MessageFormat with CLDR plural rules. Industry-standard PO files.
Zero Allocations
The source generator emits direct TextWriter.Write chains. No dictionary lookups, no string formatting, no per-request allocations.
ICU MessageFormat
Full CLDR plural rules for all Unicode locales, baked into the binary as inline arithmetic. No ICU runtime library needed.
PO File Format
Industry-standard format supported by Crowdin, Weblate, Poedit, and every major translation management system.
Compile-Time Safety
Diagnostics MB0001–MB0009 catch missing variables, malformed syntax, and type errors directly in your IDE.
Lingui.js Compatible
Share PO files between .NET and JavaScript. Both extractors use ICU MessageFormat as the msgid key.
Markdown Support
_m() converts markdown to HTML with reorderable numbered placeholders. Translators never touch raw HTML.
How it works
You write Razor views
@* _ViewImports.cshtml *@
@using static MoonBuggy.Translate
@* In any view *@
<h1>@_t("Welcome to $name$!", new { name = Model.SiteName })</h1>
<p>@_t("You have $#x# item|#x# items$", new { x = Model.Count })</p>
<p>@_m("Click **[here]($url$)** to continue", new { url })</p>
The compiler generates direct writes
// Emitted by the source generator (conceptual)
switch (lcid) {
case 10: // Spanish
writer.Write("Tienes ");
if (x == 1) { writer.Write("1 artículo"); }
else { writer.Write(x); writer.Write(" artículos"); }
break;
default: // English (source locale)
writer.Write("You have ");
if (x == 1) { writer.Write("1 item"); }
else { writer.Write(x); writer.Write(" items"); }
break;
}
Quick install
dotnet add package intelligenthack.MoonBuggy
dotnet add package intelligenthack.MoonBuggy.SourceGenerator
dotnet tool install intelligenthack.MoonBuggy.Cli