DEV Community

Cover image for G#: a modern .NET language with Go, Kotlin, and Swift ergonomics
withNext.NET
withNext.NET

Posted on Originally published at withnext.net

G#: a modern .NET language with Go, Kotlin, and Swift ergonomics

This article was originally published on our engineering blog, WithNext.NET. It's reposted here with the canonical link pointing back to the original.

"I want modern, concise syntax — but I don't want to give up the .NET runtime or ecosystem." A new language called G# goes after both. Built by David Obando and announced at its 0.3 release in July 2026, G# brings the feel of Go, Kotlin, and Swift while compiling directly to managed .NET assemblies with full interop. Microsoft's David Fowler shared it as "a new .NET programming language," and it drew a lot of attention. This post tours what G# is, how it reads, and how it connects to .NET.

What is G#?

G# is a language that compiles directly to managed .NET assemblies. It borrows modern design — Go's package layout, Kotlin/Swift null-safety — while letting you use the CLR runtime, BCL, NuGet, MSBuild, Portable PDB, and C# interop as-is. The author frames the goal like this: "C# is excellent, but it's also large and carries decades of history. G# starts from a different constraint: keep the language surface small and predictable."

G# positioning: modern syntax (Go packages, Kotlin/Swift null safety, data class, explicit numeric types) times .NET power (CLR/BCL/NuGet, MSBuild, Portable PDB, C# interop), compiling straight to managed assemblies

Modern, concise syntax

package / import / func, plus ${...} string interpolation. If you've used Go or Kotlin, it reads almost without explanation.

package Hello
import System

func greet(name string) string {
    return "Hello, ${name}!"
}

Console.WriteLine(greet("world"))
Enter fullscreen mode Exit fullscreen mode

A data class auto-synthesizes structural equality, with-copy, and deconstruction — the spirit of C# records, in fewer keystrokes.

data class Person(Name string, Age int32)

let alice = Person("Alice", 30)
let older = alice with { Age = 31 }
let (n, a) = older

Console.WriteLine(alice == Person("Alice", 30))  // True
Enter fullscreen mode Exit fullscreen mode

Nullability is part of the type system. G# uses nil rather than null; a plain T can't hold nil, only T? can. You unwrap safely with if let.

func Greet(name string?) {
    if let n = name {
        Console.WriteLine("hi ${n}")
    } else {
        Console.WriteLine("hi stranger")
    }
}
Enter fullscreen mode Exit fullscreen mode

G# language features: data class (auto equality/with/deconstruction), null safety (T can't hold nil, only T?), structured concurrency (scope joins child tasks, async/await), explicit numeric types (int8..float64)

Structured concurrency and explicit numerics

async/await run over Task and Task[T] — note that generics use brackets []. The standout is the scope { ... } block, which enforces structured concurrency by automatically joining any child tasks started inside it. Numeric types carry their width in the name (int32, uint64, float64), so the size of a value is explicit in the source.

async func compute(n int32) int32 {
    await Task.Delay(5)
    return n * 2
}

scope {
    runAll().Wait()
}
Enter fullscreen mode Exit fullscreen mode

.NET interoperability

What makes G# practical is interop: you can call any .NET type — BCL, NuGet packages, your own code — and LINQ, properties, for-in over IEnumerable[T], and P/Invoke all work. Existing test assets work too; the screenshot below is a G# test using xUnit's @Fact / @Theory / @InlineData. It's a new language, but it lives inside the .NET ecosystem.

A G# xUnit-style test: a @Fact Greet_Returns_Hello_With_Name and a @Theory with @InlineData(Alice/Bob), using func declarations and Assert.Equal(greeter.Greet(...))

Tooling and getting started

The toolchain is complete: the gsc CLI compiler (emitting managed PE + Portable PDB), the gsi REPL/script runner, a C#-to-G# migrator cs2gs, a VS Code extension, and an LSP language server. Getting started takes three commands — all you need is the .NET SDK.

Start G# in 3 steps: install template (dotnet new install Gsharp.Templates), create project (dotnet new gsharp-console -n HelloG), build and run (cd HelloG && dotnet build && dotnet run)

dotnet new install Gsharp.Templates
dotnet new gsharp-console -n HelloG
cd HelloG
Enter fullscreen mode Exit fullscreen mode

Rewrite the generated Program.gs to exercise data classes and structural equality:

package HelloG
import System

data class Person(Name string, Age int32)

func describe(p Person) string {
    return "${p.Name} (${p.Age})"
}

let alice = Person("Alice", 30)
let older = alice with { Age = 31 }

Console.WriteLine(describe(alice))
Console.WriteLine(describe(older))
Console.WriteLine(alice == Person("Alice", 30))
Enter fullscreen mode Exit fullscreen mode
dotnet build && dotnet run
Enter fullscreen mode Exit fullscreen mode

You should see:

Alice (30)
Alice (31)
True
Enter fullscreen mode Exit fullscreen mode

The with-copy and structural equality just work.

What it means for .NET developers

G# fits teams that want React/Go/Kotlin-style modern syntax but real CLR interop, folks learning or teaching .NET without starting from C#, and anyone who likes Go's packages or Kotlin/Swift null-safety on the CLR. It isn't a C# replacement — think of it as another language option on .NET, one you can mix with existing C# code.

That said, G# is pre-1.0 (v0.3). The 0.3 base is an implementation milestone, not a long-term compatibility guarantee; some interop is emit-only, and cs2gs coverage is still expanding. Start with small experiments and learning, and keep up with updates.

What the community is saying

The signal boost came from Microsoft Distinguished Engineer David Fowler (ASP.NET Core, and much of the .NET stack). A short post — but coming from a central figure in the .NET community, it put G# on a lot of radars.

FAQ

Is G# a replacement for C#?
No — it's another language option on .NET. It compiles to managed assemblies and interops with C#, so you can mix it with existing code. It suits teams who prefer a smaller, more predictable syntax or Go/Kotlin/Swift-style design.

Can I use existing .NET libraries (NuGet, BCL)?
Yes — BCL, NuGet packages, and your own code are all callable, with LINQ, bracket generics [], for-in, and P/Invoke. It sits on MSBuild and Portable PDB, so dotnet build/run and debugging work as usual.

Is it production-ready?
It's pre-1.0 (v0.3), so there's no long-term compatibility guarantee yet. Some interop is emit-only and the migrator is still growing. Start with validation, learning, and small experiments.

References


Originally published on WithNext.NET, where we write about .NET modernization, performance, and applied AI.

Top comments (0)