Nimony

The road to Nim 3

Nimony

Efficient, expressive, elegant

Nimony is a new compiler for Nim, organised around NIF: an interchange format that every stage of the pipeline reads and writes. NIF is what makes plugins possible and it is also how we can offer incremental and parallel builds. The Nim 3 language features (borrow checking, explicit nilability, sum types, checked generics, …) are built on top of it.

With plugins you can go far beyond what a macro system can accomplish easily:

For how Nimony relates to Nim 3 and Nim 2, see the FAQ.

Nightly builds

Prebuilt toolchains are published every day.

→ Browse the nightly releases and grab the newest archive for your platform. We currently offer builds for Linux x86_64, Linux ARM64, macOS ARM64 and Windows x86_64.

Extract the archive, add its bin/ directory to your PATH, and make sure a C compiler (gcc or clang) is available. On Windows, run hastur install from the extracted directory to fetch the bundled MinGW+LLVM toolchain. Or build from source.

Below are small language sketches Nimony emphasizes alongside that toolchain story.


Sum types (algebraic data types)

Variant objects no longer need a separate discriminator enum: tags live in the case section, and `case value of Tag(fields):` pattern matching binds the fields for that arm — like expressions you’d write in ML-family languages, checked for exhaustiveness.

type
  Expr = ref object
    case
    of Lit:
      value: int
    of Add, Sub:
      left, right: Expr

proc eval(e: Expr): int =
  case e
  of Lit(value):
    result = value
  of Add(left, right):
    result = eval(left) + eval(right)
  of Sub(left, right):
    result = eval(left) - eval(right)

echo eval(Add(left: Lit(value: 10), right: Lit(value: 32)))  # 42

Shared fields can live outside the case, variants can nest (seq[Tree] in a branch), and grouped matchers like {Add, Sub}(left, right) appear where multiple tags share the same shape — see Case in object in the manual.


Borrow checking — iterator safety and aliasing

Nimony rejects classic footguns at compile time:

proc grow(s: var seq[int]; use: int) =
  s.add use

var s = @[1, 2, 3]
# for v in s:
#   grow(s, v)   # Error: `s` is borrowed during iteration — no realloc under active borrows

This follows prefix exclusion: while s (or s.elements) is borrowed, that path cannot be mutated until the borrow ends — sibling fields can still be updated.


Type checked generics

By default generics are type checked: the code is checked when the generic is defined, not only when it is instantiated! Duck typing is still available, you get it via the {.untyped.} pragma.

The required operations are described via concepts:

type
  Comparable = concept
    proc `<`(a, b: Self): bool

proc min[T: Comparable](a, b: T): T =
  if a < b: a else: b

echo min(3, 7)
echo min("b", "a")

Container-style concepts (e.g. Findable[T]) work the same way with iterators and indexed access — see Concepts and Generics in the manual.


Latest news

2026-09-08 Nimony 0.6.2 has been released. It ships with a guest report from a user who spent a year porting real projects over. A Vulkan visualiser, a web framework, an embedded server: Nim, one year in.

Older entries, including the 0.2 release, live on the News page.