BccCode.I18N.SourceGen 1.2.0

dotnet add package BccCode.I18N.SourceGen --version 1.2.0
                    
NuGet\Install-Package BccCode.I18N.SourceGen -Version 1.2.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="BccCode.I18N.SourceGen" Version="1.2.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BccCode.I18N.SourceGen" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="BccCode.I18N.SourceGen">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
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 BccCode.I18N.SourceGen --version 1.2.0
                    
#r "nuget: BccCode.I18N.SourceGen, 1.2.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 BccCode.I18N.SourceGen@1.2.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=BccCode.I18N.SourceGen&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=BccCode.I18N.SourceGen&version=1.2.0
                    
Install as a Cake Tool

BccCode.I18N.SourceGen

A Roslyn incremental source generator that reads JSON translation files (the format vue-i18n uses) and generates strongly typed C# for them. Texts are checked at compile time and selected from the current culture at run time.

Read the user manual

Features

  • Language: a typed member per key, for example Language.menu.save or Language.greeting(name).
  • LanguageKeys: const string key paths, for example to send keys to a frontend.
  • LanguageStrings: lookups, listings and formatting by key at run time.
  • LocalizedLanguage: the same members as Language for an explicit culture.
  • Culture matching through parent cultures and language aliases (nb-NO uses no.json), with per-key fallback to a fallback language.
  • vue-i18n message syntax: placeholders, plural forms, linked messages and literals, plus .NET format specifiers such as {date:d}.
  • Optional IStringLocalizer implementation when the project references Microsoft.Extensions.Localization.
  • Build diagnostics for invalid files, missing or extra keys and placeholder mismatches.
  • Generated code is shaped so that hot reload applies translation edits.

Quick start

dotnet add package BccCode.I18N.SourceGen

Add one JSON file per language, named after the language (en.json, no.json):

{
  "greeting": "Hello, {name}!",
  "menu": { "save": "Save" },
  "files": "no files | one file | {count} files"
}

Mark the files and choose the fallback language and namespace in the project file:

<PropertyGroup>
  <FallbackLanguage>en</FallbackLanguage>
  <GeneratedNamespace>MyApp.Localization</GeneratedNamespace>
</PropertyGroup>

<ItemGroup>
  <AdditionalFiles Include="en.json" I18NTranslation="true" />
  <AdditionalFiles Include="no.json" I18NTranslation="true" />
</ItemGroup>

Build once, then use the generated classes:

using MyApp.Localization;

string save = Language.menu.save;               // "Save", or "Lagre" for a Norwegian UI culture
string greeting = Language.greeting("Kari");    // "Hello, Kari!"
string files = Language.files(3);               // "3 files"
string key = LanguageKeys.menu.save;            // "menu.save"
string byKey = LanguageStrings.GetString(key);  // "Save"

The fallback language defaults to no when FallbackLanguage is not set. Without GeneratedNamespace, the classes are generated in the project's RootNamespace.

Documentation

Development

Packaging and integration testing

The NuGet package is built as an analyzer package:

  • BccCode.I18N.SourceGen.dll is packed under analyzers/dotnet/cs
  • normal lib/ output is disabled so consumers do not reference the generator assembly directly
  • build/BccCode.I18N.SourceGen.props is included so FallbackLanguage remains compiler-visible for package consumers

The repository contains two integration test projects under BccCode.I18N.SourceGen/BccCode.I18N.SourceGen:

  • BccCode.I18N.SourceGen.IntegrationTests tests consumption through an analyzer-style ProjectReference
  • BccCode.I18N.SourceGen.NuGetIntegrationTests tests the packed .nupkg through PackageReference

Use the following commands from the nested repository root BccCode.I18N.SourceGen/BccCode.I18N.SourceGen:

dotnet test .\BccCode.I18N.SourceGen.IntegrationTests\BccCode.I18N.SourceGen.IntegrationTests.csproj

dotnet pack .\BccCode.I18N.SourceGen\BccCode.I18N.SourceGen.csproj -c Release -p:PackageVersion=0.0.0-local -o .\artifacts

Remove-Item .\packages -Recurse -Force -ErrorAction SilentlyContinue
dotnet restore .\BccCode.I18N.SourceGen.NuGetIntegrationTests -p:BccCodeI18NSourceGenPackageVersion=0.0.0-local --packages .\packages
dotnet test .\BccCode.I18N.SourceGen.NuGetIntegrationTests -c Release --no-restore -p:BccCodeI18NSourceGenPackageVersion=0.0.0-local

CI runs the same steps (.github/workflows/test.yml) on every pull request and push to main.

Releasing

Push a tag vX.Y.Z (or a prerelease such as vX.Y.Z-beta.1) on a commit that is on main. .github/workflows/publish-nuget.yml then runs all tests, packs with that version, tests the packed package, pushes it to nuget.org via trusted publishing and creates a GitHub release with generated notes and the .nupkg attached.

This mirrors the source-generator publishing flow described by Andrew Lock: first verify compiler integration through an analyzer-style project reference, then verify the actual packed analyzer from a local NuGet source without polluting the machine-wide NuGet cache. Clearing the local packages folder before restore is important when reusing the same package version locally, otherwise NuGet can keep an older packed analyzer and stale build props.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has 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
1.2.0 751 10/15/2026
1.1.0 78 10/15/2026
1.0.0 85 10/15/2026
0.2.0 129 10/15/2026
0.1.0 9,030 4/20/2026