r/nim 14h ago

lumber: A JSON logger with CLI

Post image
11 Upvotes

Hi all! I've just released lumber, a JSON logger for Nim inspired by pino, and I'd love for you to try it out. I hope to incorporate some feedback before freezing the API for v1.0.0.

Highlights

  • Compile-time log elimination: build with -d:lumberLevel=INFO and calls below the threshold vanish from the binary entirely; runtime-filtered calls never evaluate their arguments either
  • Structured logging: named fields (logger.info("login", user="alice")), per-logger context, child loggers, and thread-local scoped context
  • Exception logging: pass an exception as an argument and its message, type, and stack trace become structured fields
  • Thread-safe: share one module-level logger across threads
  • Flexible outputs: size/time-based file rotation, buffering with level-triggered flush, and a background-thread async writer
  • Middleware: rate limiting, sampling, and redaction (including nested fields) built in, or write your own
  • CLI prettifier: pipe JSON logs through the lumber binary for colored human-readable output with level/field filtering, regex highlighting, and timezone conversion
  • Minimal dependencies: stdlib plus one pure-Nim package, no C libraries

Example

import std/strformat
import lumber

type
  User = object
    name: string

var logger = newLogger(name = "demo")
var user = User(name: "Alice")

logger.trace("This is a trace")
logger.debug(user)
logger.info(&"{user.name} logged in")
logger.warn("Disk usage high", partition="/dev/sda1", usage=92)

proc loadConfig() =
  raise newException(IOError, "file not found: config.toml")

proc initApp() =
  loadConfig()

try:
  initApp()
except IOError as e:
  logger.error("Failed to load config", e)

logger.fatal("Game over")

Output

Raw output

{"timestamp":"2026-07-22T05:03:27.833Z","level":"TRACE","name":"demo","filename":"minimal.nim","line":18,"message":"This is a trace"}
{"timestamp":"2026-07-22T05:03:27.833Z","level":"DEBUG","name":"demo","filename":"minimal.nim","line":19,"message":"User(name: \"Alice\")"}
{"timestamp":"2026-07-22T05:03:27.833Z","level":"INFO","name":"demo","filename":"minimal.nim","line":20,"message":"Alice logged in"}
{"timestamp":"2026-07-22T05:03:27.833Z","level":"WARN","name":"demo","filename":"minimal.nim","line":21,"message":"Disk usage high","extra":{"partition":"/dev/sda1","usage":92}}
{"timestamp":"2026-07-22T05:03:27.833Z","level":"ERROR","name":"demo","filename":"minimal.nim","line":32,"message":"Failed to load config","extra":{"error":"file not found: config.toml","errorType":"IOError","stackTrace":"/Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(30) minimal\n/Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(27) initApp\n/Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(24) loadConfig\n"}}
{"timestamp":"2026-07-22T05:03:27.833Z","level":"FATAL","name":"demo","filename":"minimal.nim","line":34,"message":"Game over"}

Piped through the CLI

2026-07-21T22:04:45.613-07:00 PDT [TRACE] (minimal.nim:18) demo: This is a trace
2026-07-21T22:04:45.613-07:00 PDT [DEBUG] (minimal.nim:19) demo: User(name: "Alice")
2026-07-21T22:04:45.613-07:00 PDT [INFO ] (minimal.nim:20) demo: Alice logged in
2026-07-21T22:04:45.613-07:00 PDT [WARN ] (minimal.nim:21) demo: Disk usage high
  partition: "/dev/sda1"
  usage: 92
2026-07-21T22:04:45.613-07:00 PDT [ERROR] (minimal.nim:32) demo: Failed to load config
  error: "file not found: config.toml"
  errorType: "IOError"
  stackTrace:
    /Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(30) minimal
    /Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(27) initApp
    /Users/cryo/projects/nim/nim-lumber/examples/minimal.nim(24) loadConfig
2026-07-21T22:04:45.613-07:00 PDT [FATAL] (minimal.nim:34) demo: Game over

---

More docs and examples are available in the README.

All feedback is very welcome: ergonomics, missing features, performance, or anything that feels un-Nim-like.


r/nim 1d ago

I wrote a local PDF unlocker in Nim because I didn't want to upload private PDFs

20 Upvotes

I recently needed to remove the password from a lot of PDFs. Most of the search results were websites asking me to upload the file and enter its password.

They might be perfectly legitimate, but I wasn't comfortable uploading bank statements, tax documents or contracts just to remove a password.

So I wrote this:

https://github.com/advaita-saha/nim-pdftools

It is a small command-line PDF unlocker written in Nim. Everything runs locally and it doesn't use any third-party Nim packages.

pdftools unlock -p 'password' document.pdf

It currently handles RC4, AES-128 and AES-256 encrypted PDFs. Both user and owner passwords work.
It is not a password cracker. You still need to know the password lol.

I ended up implementing most of the crypto and compression code directly on top of Nim's standard library. This was partly because I wanted a standalone binary and partly because digging through the PDF encryption spec seemed like a good idea at the time.

This is still v0.1, so I'm sure there are strange PDFs in the wild that it won't handle properly. I'd especially appreciate people testing files generated by different PDF software and reporting anything that breaks.

Contributions are welcome too. Parser fixes, test cases, code review, packaging improvements and additional local PDF commands would all be useful.


r/nim 1d ago

QtCreator + nim + gdb yielding terrible workflow

6 Upvotes

As a disclaimer, I'm very new to nim. Currently using QtCreator as IDE, I intent to port my game engine over to nim, but at first glance, gdb spits out utter garbage at breakpoints and inspection is practically impossible due to a variable apparently being "too complex" (?) to inspect... yeah...

Now my game engine is not something trivially small or simple at this point and (except for the syntax) I'm very pleased with what nim has to offer.

Can someone point me in the best practices direction please ?


r/nim 1d ago

Narduino (Nim->Arduino Library) Update

17 Upvotes

Narduino is a library that allows you to write and flash Arduino firmware with Nim using your favorite IDE easily.

https://github.com/Niminem/narduino

Today I added serial monitor support via a simple command.

You can now monitor your board's serial output directly from the CLI:

Flash the board:

narduino flash --src:examples/serial.nim

Monitor the port:

narduino monitor

It's fully interactive too!

Read and write to your board in real time, just like the Arduino IDE's serial monitor. You can Ctrl+C to exit safely.

import narduino
setup:
  Serial.begin(9600)
loop:
  if Serial.available() > 0:
    let c = Serial.read()
    Serial.print("Got: ")
    Serial.println(char c)

Flash it, open the monitor, type something and it echoes back what you send.

The monitor command auto-detects your board's port (like everything else in narduino) and supports a --baud flag if you need a different baud rate (default is common 9600).

NOTE: Some boards, like the Arduino UNO R4 WiFi, may have routes serial through some bridge, which can produce garbled serial monitor output after plugging in or flashing. If you see garbled output, just hit refresh button on your board and run the monitor command again.


r/nim 3d ago

Nim tooling !? I am confused after 2yrs

26 Upvotes

So I am coding stuff in Nim for around 2.5years.
I have seen stuff improve over the years, but one thing still bugs me is the tooling support.

Why is the VS Code extension so bad ?
I mean either hogs up the CPU, then unable to read and parse complex codebases. Suggestions come super late. Validations and errors are extremely late ( better if I compile and check )

An open question to everyone working with nim. What tooling are you guys using ?


r/nim 4d ago

Nim Docker Hub images are now official

27 Upvotes

Hi!

After an entire year under review and dozens of fixes, the Nim Docker Hub images are finally have the official status and can be pulled with docker pull nim

The new official home for the images is https://hub.docker.com/_/nim

I published a Q&A on the forum: https://forum.nim-lang.org/t/14068


r/nim 4d ago

Narduino: Write and flash Arduino firmware with Nim using your favorite IDE

26 Upvotes

https://github.com/Niminem/narduino

Write and flash Arduino firmware with Nim using your favorite IDE- easily!

The Arduino CLI powers the Arduino IDE and other official tooling. narduino provides abstractions on top of it (and the Nim compiler) so you can build firmware in Nim from any editor. Your Nim code is translated to C++, placed into a standard Arduino sketch, and arduino-cli then compiles that sketch for your board and flashes it.

All from a single command: narduino flash --src:examples/blink.nim

This repo is both a CLI tool AND a library. I've wrapped the vast majority of the Arduino API as well as providing templates to remove FFI boilerplate.

A simple example looks like this (blinks the internal LED on an Arduino UNO):

import
 narduino

setup:
  pinMode(LED_BUILTIN, OUTPUT)

loop:
  digitalWrite(LED_BUILTIN, HIGH)
  delay(1000)
  digitalWrite(LED_BUILTIN, LOW)
  delay(1000)

The toolchain (functions) powering the CLI is also provided as a library so you can create your own tooling if you wish.

An example:

import narduino/toolchain

# board discovery
let boards = listBoards()            # all detected ports + matching boards
let active = getActiveBoard()        # the single connected board (fqbn + port)

# core management
ensureCoreInstalled(active.fqbn)     # install the board's core if missing

# build & flash
let sketchDir = createSketch("blink.nim")  # nim -> c++ -> sketch dir
upload(sketchDir)                          # compile & upload via arduino-cli

The Arduino CLI itself supports A LOT of boards and 3rd party Cores (packages). As long as it supports your board you can use this repo easy peasy. See https://github.com/Niminem/narduino#supported-boards for more details.

---

I started getting into electronics and embedded systems recently. I didn't want to write in c++ nor did I want to use their IDE but I was willing to do it. I started exploring what was out there for Nim because I knew it HAD to be possible to use Nim's cpp backend and VSCode.

Everything I found was really old and fickle and just... janky.

I learned that Arduino has a CLI that powers their IDE and began exploring the possibility of using that. Works like a charm!

Figuring out how to compile Nim projects in a way that actually worked took some time, but was nearly as complicated as I thought. Knowing what I know now, I was even able to programmatically detect which cpu architecture your board uses and define that architecture when compiling Nim- pretty neat!

Anyways guys, I hope you enjoy. I did not port the USB / WIFI stuff from the API yet because I don't have a board to test them. PRs accepted otherwise it'll be a little while before I can get to it. Wrapping these functions are pretty straightforward anyway. Seems like the Arduino team really took their time to make the APIs as simple as possible.


r/nim 7d ago

3code, the economical coding agent

Thumbnail 3code.capocasa.dev
18 Upvotes

3code is a tiny programming agent a la Claude Code that is designed in every way to conserve tokens, your computer resources, and your brain cycles.

It works with any provider- GLM 5.2 works great and Hy3 is pretty good and free!

The special move: Self amnesia! Instead of splurgy subagents it does long hands off sessions ​by iterating over a plan-cum-todolist repeatedly keeping only the context relevant to the task.

Check it out and tell me what you think!

Edit: It is- of course- written in 100% fast, ingeniuos​ Nim code, which is why it's only a few megabytes and starts in an​ instant.


r/nim 8d ago

spec-compliant and dependency-free gitignore parser and pattern matcher

15 Upvotes

https://github.com/Niminem/gitignore

On my journey to create a coding agent I needed yet another library we don't currently have in our ecosystem.

This library is a parser and pattern matcher for .gitignore files, and effectively ports git's implementation. It's tested against their actual test tables. Stdlib only.

The gitignore libraries I've found in other languages mix parsing a pattern vs evaluating a file vs walking a repository. This one separates them into 3 distinct layers or APIs. One parses a single gitignore line and match paths against it, another parses a single file, and the other walks a repo.


r/nim 11d ago

spec-compliant SSE & Json Schema libraries

15 Upvotes

I've just published two libraries I think some of you in the community would like to use.

https://github.com/Niminem/sse

A spec-compliant Server-Sent Events library for Nim. Stdlib only, no external dependencies, no std/httpclient either (HTTP is done by hand over sockets).

NOTE: For making SSE servers I only included helpers. In this way, you're not boxed in to an implementation. For client-side we have async using Nim's standard async implementation but we also have a purely synchronous version in case you'd like to use threads. Added bonus is a 'cancelToken' so you can stop mid-stream. Those building some sort of chat app or similar may find that useful.

https://github.com/Niminem/jschema

A spec-compliant JSON Schema (draft 2020-12) validator and builder for Nim.

NOTE: This is stdlib only as well. No deps aside from the PCRE (regex) DLL or whatever it's called. Which comes installed with Nim. Just something to be mindful of if you're shipping something- you'll need that alongside your binary.


So I'm building a coding agent from scratch and needed these libraries. SSE for streaming and Json Schema building / validation for LLM tool calling.

Instead of just building the minimum for what LLM providers need with both libraries, I chose to go all in and build them against the specs since they're available and we don't have them in our ecosystem yet. Because supply chain attacks are on the rise and largely through dependencies becoming a super common attack vector, I also made the choice to use stdlib only.

They are going to be used in commercial applications and will be maintained.

If you run into any issues please let me know or make a PR, I've tested as much as humanly possible prior to making the repos public.


r/nim 13d ago

Nimble / SIGSEGV: Illegal storage access. (Attempt to read from nil?)

6 Upvotes

I just try to use nimble on macOS / nix-darwin. nimble init is ok, but after that:

> nimble install puppy
Downloading Official package list
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
fish: Job 1, 'nimble install puppy' terminated by signal SIGSEGV (Erreur de frontière d’adresse)

> nimble --version
nimble v0.20.1 compiled at 1980-01-01 00:00:00
git hash: v0.20.1

Any idea?


r/nim 14d ago

Nimpack.org down

9 Upvotes

Might be a temporary outage but I've been having consistent difficulty accessing nimpack for a while now and currently down detector is reporting the site is down. According to cloudflare, it's a host-side issue.

Anyone know if something is going on? Or if it's just experiencing a regular outage?


r/nim 14d ago

I've built NumTris with @base44!

Thumbnail numbered.base44.app
7 Upvotes

r/nim 18d ago

Merenda: Pure Nim GUI toolkit based on Cocoa/OpenStep

31 Upvotes

Merenda is a new pure Nim GUI framework based on OpenStep and Cocoa with a splash of QT! It's fast, GPU rendered, with themes and look and feel along with a full suite of OpenStep/Cocoa style widgets and an accessibility layer. Support for BIDI and Harffbuzz are coming soon!

It's already implements a substantial amount of the core functionality of OpenStep and Cocoa. It's not a one-to-one implementation, but generally the APIs try to follow Cocoa's design patterns. Though cleaned up to take advantage of Nim's stronger type system than Objective-C.

For example here's the table demo showing a table view backed by a data model (EDITED):

Overall Merenda is based on several years of working on and experimenting with GUIs. I worked Figuro and was happy with many aspects of it. However the object model ran into limitations when building more complex widgets. Things like:

Merenda solves this by adopting Cocoa's dynamic methods and protocols. These are provided by Sigils. The ability for objects to adopt protocols at runtime enables implementing the rich behavior and functionality seen in Cocoa and iOS.

The implementation of this is called NimKit, mirroring Cocoa's AppKit. NimKit ships the core controls needed for desktop-style interfaces:

  • Windows and views: newApplication, sharedApplication, newWindow, newView
  • Layout and containers: newStackView, newGridView, newFormView, newSplitView, newScrollView, newTabView, newBox, newGroupBox, newSeparatorBox
  • Text: newTextField, newLabel, newTitleLabel, newStatusLabel, newTextEditor, newMonoTextEditor
  • Buttons and choices: newButton, newCheckBox, newRadioButton, newComboBox, newPopupMenuButton, newMenu, newMenuItem
  • Value and status controls: newSlider, newStepper, newSwitchButton, newProgressIndicator
  • Data and navigation views: newTableView, newOutlineView, newCascadingView, newCollectionView, newDocumentTabs, newButtonMatrix, newRadioMatrix

It's been my hobby work the last few months. I've been building and testing all of these, item by item!

Yes it's mostly built with Codex + GPT-5.5 but I continuously review the generated code and refactor and simplify it. Plus more importantly it's based on solid architectural components I've been building for years. It's definitely not what I'd call vibe coded.

EDIT:

Made some updates to the default theme to make it much more like early Mac OS X aqua days! Well I enjoy it at least. This is all done without any images and all the chrome and detailing is done in real time on the GPU:


r/nim 21d ago

Interested in nim for game development

21 Upvotes

I am currently investigating nim for game development, having been searching for a good environment for many years. nim seems promising so far and I may use raylib bindings as my framework.

The main things that make nim appealing for game development to me are its ergonomics, unopinionated workflow, being able to shape it to my needs via macros and templates, and high performance despite resembling a scripting language. Most languages and frameworks/engines I have tried have been too rigid for the creative iterative process that game development demands, or are simply just not fun to use. Programming in my environment being fun and detached from work is my top priority.

My main concern is tooling. It was a bit of a pain to get nim set up on Windows. I am using VS Code with nimlangserver, and while it has been surprisingly solid at parsing macros it has been showing some problems. Tooltip hovering seems to just randomly stop working, and it occasionally highlights errors that aren't actually errors at all.

I would like to know what is suggested for a good tooling environment for nim. Bad tooling can undermine the semantics and power that the programming language provides.


r/nim 23d ago

C GTK Libraries with Nim

13 Upvotes

Never used Nim, or developed [full applications] in a serious way.

Want to develop a native Linux application, and prefer to use GTK.

With the latest discussion around Nim and GUI libraries, I genuinely do not understand the extent of difference in hardship between using native GTK C libraries, compared to having native Nim libraries.

Even though the OCD in me cannot stand to have non-matching libraries like this, can I not get the full benefits of GTK using Nim, just by incorporating the "straight" C (whatever that means.)

Are there some examples of Nim projects or lessons that that incorporate regular C GTK libraries? Can't I get "all" of GTK this way, and do whatever I could do in a C application?

Can I plunge headlong into developing a native Linux GUI in GTK in Nim, with full expectation of being able to do anything I would have done in GTK if the application were a C application? . . . perhaps with a little extra work than if there would be for Nim-native GTK?

Is it a matter of creating personal custom "bindings" on a per-need basis?

Thanks.


r/nim 25d ago

Full Nim Programming Crash Course - Beginner to Advanced

Thumbnail youtu.be
73 Upvotes

10 hour long Nim crash course is now available on YouTube


r/nim 25d ago

Rigx: toml based build system with native Nim support, hermetic build and tool chains leverage nix.

Thumbnail github.com
14 Upvotes

I wanted something simple like Make but hermetic like Bazel with toolchains from Nixpkgs, toml- syntax, not nix-lang, and native Nim support. This is what I settled on.


r/nim Jun 21 '26

dokime; SQL the Compiler Checks for You

19 Upvotes

Most SQLite wrappers treat SQL as opaque strings. Dokime prepares every query against your real database at compile time. Typo in a table name? Your build breaks. Wrong column? Build breaks. It's a Nimony plugin, not an ORM.

Here's a personal expense tracker. It creates a schema, inserts rows, queries with optional filters, uses transactions, and handles nullable columns. Every mistake you could make is shown alongside the code that catches it.

import dokime

let db = connect("money.db")

# Schema: note is nullable (TEXT, no NOT NULL). Everything else is required.
discard exec(db, """
  CREATE TABLE IF NOT EXISTS expenses (
    id       INTEGER NOT NULL,
    category TEXT    NOT NULL,
    amount   REAL    NOT NULL,
    note     TEXT,
    date     TEXT    NOT NULL
  ) STRICT
""")

# exec() returns ExecResult with .lastRowid and .changes:
let r = exec(db, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    1'i64, "food", 23.50, "lunch", "2025-06-01")
echo r.lastRowid   # 1

# exec() accepts Opt[T] params — none binds SQL NULL, some binds the value:
discard exec(db, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    2'i64, "food", 12.00, none[string](), "2025-06-02")
discard exec(db, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    3'i64, "transport", 5.50, "bus", "2025-06-03")
discard exec(db, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    4'i64, "food", 45.00, "dinner with friends", "2025-06-04")


# ── If you typo the table name, you get a compile error ──
# query(db, "SELECT id FROM expenes WHERE id = ?", 1'i64)
# → Error: dokime: no such table: expenes

# ── A misspelled column also fails at compile time ──
# query(db, "SELECT id, full_name FROM expenses WHERE id = ?", 1'i64)
# → Error: dokime: no such column: full_name


# query() returns a tuple with fields named after your columns:
let dinner = query(db,
    "SELECT id, amount, note FROM expenses WHERE id = ?", 4'i64)
echo dinner.id        # 4       (int64 — type comes from the schema)
echo dinner.amount    # 45.0    (float64)
echo dinner.note.isSome        # true    (TEXT nullable → Opt[string])
echo dinner.note.unsafeGet     # "dinner with friends"


# ── Type mismatches are caught at compile time too ──
# let x: string = dinner.amount
# → Error: type mismatch: got: float64 but wanted: string


# query() requires at least one row — raises BadOperation if empty.
# Use queryOpt() when zero rows is expected:
let missing = queryOpt(db,
    "SELECT id, category FROM expenses WHERE id = ?", 42'i64)
echo missing.isNone   # true


# ── query() with no matching row raises at runtime ──
# query(db, "SELECT id FROM expenses WHERE id = ?", 999'i64)
# → ErrorCode: BadOperation


# Dynamic optional clauses: wrap in [...], pass Opt[T].
# Every combination of included/omitted clauses is validated at compile time.
let catFilter = some("food")
let minAmount = some(20.0)
for row in rows(db, """
  SELECT id, category, amount FROM expenses
  WHERE 1 = 1
    [AND category = ?]
    [AND amount >= ?]
  ORDER BY amount DESC
""", catFilter, minAmount):
  echo row.id, " ", row.amount   # 4 45.0, 1 23.5


# Transactions: use tx handle for queries, commit to persist.
# Using db directly during a tx raises BadOperation.
var tx = begin(db)
discard exec(tx, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    5'i64, "food", 8.00, "coffee", "2025-06-05")
discard exec(tx, "INSERT INTO expenses VALUES (?, ?, ?, ?, ?)",
    6'i64, "food", 15.00, none[string](), "2025-06-05")
commit(tx)
# If tx goes out of scope without commit/rollback → destructor auto-rollback.


# ── Using db handle during an active tx ──
# var tx = begin(db)
# exec(db, "INSERT ...")   → ErrorCode: BadOperation


close(db)

Setup

export DOKIME_DATABASE_PATH=dev.db
nimony c -r myapp.nim

First build caches validated query metadata to .dokime/queries/. CI builds without a database:

DOKIME_DATABASE_PATH= nimony c -r myapp.nim

What it is: compile-time validation for SQLite queries via Nimony plugins. Schema-driven types, named tuple fields, optional clauses, transactions with destructor safety.

What it isn't: an ORM, a migration tool, multi-database, or compatible with the stable Nim compiler. SQLite only, STRICT tables required.


r/nim Jun 20 '26

NimConf 2026 is Live!

Thumbnail youtube.com
39 Upvotes

r/nim Jun 20 '26

Code quality of standard library

13 Upvotes

hi

I remember reading somewhere in reddit or hackernews that nim standard library doesnt follow the most modern nim conventions and is not a good choice to copy its style in your own code

how true this statement is for anyone who have read nims standard library codebase?


r/nim Jun 19 '26

FigDraw + Harfbuzz for beautiful font shaping! 😍

19 Upvotes

FigDraw 0.25.0 now has optional support for Harfbuzz, the premier open source font shaping library!

The font backends will be swappable between Pixie and Harfbuzz at compile time. FigDraw's text API is mostly unchanged, however internally it tracks all the extra work needed for languages with complex scripts. This also includes support for BIDI and right-to-left scripts! I'm not sure about top-to-bottom languages (for now).

See the README for usage details.


r/nim Jun 18 '26

Like, what is nimble?

15 Upvotes

I am new-ish to nim, and I have used nimble a bit, and it seems like node/npm, because I can run, and install packages, but I don't know? Is it a runtime (like nodejs), a dependency manager (like composer for php) or something else.

Thank you for any answers!


r/nim Jun 17 '26

Update: Trying to add JS Binding with in-Browser Nim Compiler

Post image
19 Upvotes

A few weeks back I posted about getting Nim 2.2.4 to compile and run entirely in the browser prev post, no backend, no native toolchain, no JS fallback. However, I am still interested with using Nim instead of Rust Yew or C Clay to build Web UI.

Now it can. I built a module I called BindWeb, a binding layer that lets the Nim code you compile in-browser drive the actual DOM, Canvas2D, WebGL, WebGPU, Audio, WebSocket, Fetch, localStorage, and input events — and it all still compiles client-side through the same Nim → C → clang.wasmlld.wasm pipeline in browser.

🔗 Live demo: https://benagastov.github.io/bindweb-nim-WASM-compiler/
💻 Source: https://github.com/benagastov/bindweb-nim-WASM-compiler

How the bindings work

WASM can't touch the DOM directly, so BindWeb is built around a tiny command protocol instead of hundreds of individual imports:

  • Nim writes binary command packets (opcode + args) into a shared linear-memory buffer.
  • On flush, the JS runtime walks that buffer and replays each command against the real browser API.
  • DOM nodes / GL objects / audio elements live in JS and are referenced from Nim by integer handles, with a free-list so handles get recycled.
  • Events go the other direction through a second event buffer: JS encodes clicks/keys/fetch results/etc., Nim drains them on the next tick.

The whole API surface (the Nim modules, the JS runtime, and the C runtime) is generated from a single schema.def, so adding a new browser API is a schema entry rather than three hand-written layers that drift apart.

I had to keep the Nim-side references alive so ORC wouldn't collect the object holding a live DOM handle. Once that was sorted, you can create an element in Nim and attach an event listener to it, all Nim-side.

Haven't tried existing Nim JS-binding libs (std/dom, jsffi, Karax) — they target the JS backend not a static page, so I still dont find a lib to compile the C backend to WASM. The in-browser compiler is still experimental anyway.

What you can try in the demo

The dropdown has a few starter programs — a DOM counter, a Canvas2D animation, and mouse/keyboard input — all compiled to WASM in your browser and running live, no server round-trip.


r/nim Jun 17 '26

Yet Another Package Manager but in Nim

Thumbnail github.com
15 Upvotes

I started building a simple C++ project manager and build tool called Nimmake. It's designed to be easier than CMake for beginners and for quickly prototyping projects, since it removes much of the configuration and boilerplate that's usually required.