Features

Intuitive and clean syntax

Taking inspiration from multiple languages, the Nim syntax is easily understood and results in code that can be modified very effectively.

  • Indentation significant syntax
  • Multiple constructs inspired by Python
  • Multi-line lambdas
  • It combines successful concepts from Ada and Modula.
import strformat
type
  Person = object
    name*: string # Field is exported using `*`.
    age: Natural  # Natural type ensures the age is positive.

var people = [
  Person(name: "John", age: 45),
  Person(name: "Kate", age: 30)
]

for person in people:
  # Type-safe string interpolation.
  echo(fmt"{person.name} is {person.age} years old")

Support for multiple operating systems

Nim supports every mainstream operating system and platform as well as multiple niche platforms. We take pride in supporting all three major operating systems fully.

JavaScript compilation

Nim includes a first-class JavaScript backend so you can target the client and server effortlessly at the same time.

New Game: N Play/Pause: P Controls: ← → ↑ ↓

The above game is written in Nim, compiled using the JavaScript backend and drawn using the canvas API.

Source code: https://github.com/dom96/snake

Game website: http://picheta.me/snake

import dom

proc onLoad(event: Event) =
  let p = document.createElement("p")
  p.innerHTML = "Click me!"
  p.style.fontFamily = "Helvetica"
  p.style.color = "red"

  p.addEventListener("click",
    proc (event: Event) =
      window.alert("Hello World!")
  )

  document.body.appendChild(p)

window.onload = onLoad

Small core with a rich prospect for extensibility

Nim implements a small core language with a powerful set of metaprogramming features.

The metaprogramming features in Nim include support for generics, templates, and macros. This allows Nim to be extended with support for various programming paradigms and allows developers to avoid boilerplate. The standard library implements async await using these metaprogramming features and the Nim community has developed various packages implementing different programming paradigms.

import macros, strutils

macro toEnum(words: static[string]): untyped =
  result = newTree(nnkEnumTy, newEmptyNode())

  for w in splitWhitespace(words):
    result.add ident(w)

type
  Color = toEnum"Red Green Blue Indigo"

var color = Indigo

Decentralised package management

The Nim package manager is called Nimble. Packages are distributed via Git and Mercurial repositories, and tags are queried remotely to determine version information.

A mapping between package names and repository URLs is defined in a packages.json file that is stored on GitHub.

Packages are defined using a specially formatted .nimble file that is evaluated by the Nim compiler. This means that it supports a large subset of the Nim programming language, allowing various powerful features including the ability to determine the OS and specify external dependencies.

# Package

version       = "v0.1.0"
author        = "Benedict Cumberbatch"
description   = "Sample package."
license       = "MIT"

# Dependencies
requires "nim >= 0.13.0", "jester >= 0.1.0"

import distros
if detectOs(Ubuntu):
  foreignDep "libssl-dev"
else:
  foreignDep "openssl"

task test, "Run the tester!":
  withDir "tests":
    exec "nim c -r tester"

Easy C, C++ and Objective C wrapping

{.passL: "-lsfml-graphics -lsfml-system -lsfml-window".}

type
  VideoMode* {.importcpp: "sf::VideoMode".} = object
  RenderWindowObj {.importcpp: "sf::RenderWindow".} = object
  RenderWindow* = ptr RenderWindowObj
  Color* {.importcpp: "sf::Color".} = object
  Event* {.importcpp: "sf::Event".} = object

{.push cdecl, header: "<SFML/Graphics.hpp>".}
{.push importcpp.}

proc videoMode*(modeWidth, modeHeight: cuint,
                modeBitsPerPixel: cuint = 32): VideoMode
proc newRenderWindow*(mode: VideoMode, title: cstring): RenderWindow
proc pollEvent*(window: RenderWindow, event: var Event): bool
proc newColor*(red, green, blue, alpha: uint8): Color
proc clear*(window: RenderWindow, color: Color)
proc display*(window: RenderWindow)

Nim makes it easy to bind to C, C++ and Objective C libraries. This allows developers to easily access a large ecosystem of mature and powerful libraries.

Helpful tracebacks

Inspired by Python.

When a Nim application crashes with an exception, it will output a stack trace before terminating. The format of this stack trace is very easy to grasp and contains all the required information to debug the exception.

Traceback (most recent call last)
module.nim(10)           module
module.nim(8)            readData
strutils.nim             parseInt
Error: unhandled exception:
       invalid integer: Hello World [ValueError]

More questions? See the FAQ