mordaunt.dev/code

code / jm

jm

my Odin collection: the packages my applications share, in one tree, usable by others without an API stability promise yet

  • Odin
  • Collection
  • Library
  • Scripting
  • HTTP
  • Shell
  • Tar
  • Debugging
  • Runner
  • Tooling
clone
https://mordaunt.dev/code/jm
license
Apache-2.0
activity
739 commitsthis year, since 2026

jm

Odin for everything you used to reach for Python to do.
Scripts that start like bash and run like C. Batteries linked in. A UI toolkit you can test without a window.

Scripts · Packages · UI · Streams · Fuzzing · Setup

#!/usr/bin/env odin-run
package main

import "core:fmt"
import "jm:prelude"
import "jm:sh"
import "jm:path"

must :: prelude.must

main :: proc() {
	context = prelude.init()
	branch := must(sh.out("git rev-parse --abbrev-ref HEAD"))
	for f in must(path.walk(".")) {
		fmt.println(branch, f)
	}
}

chmod +x and run it. The first run compiles; every run after starts the cached binary.

Write it like a script

The prelude puts an arena in the allocator, so a script never frees. Anything that can fail goes through must, which dies with the call site and logs the death. The shell, HTTP, paths, time and tar are one import each. When a script outgrows a script, it is already a native program. Writing scripts →

Ship one file

SQLite, zstd, wasm3, libgit2 and PostgreSQL’s own parser are vendored and linked statically, so a program that uses them installs nothing. libcurl and libpq are the only system libraries. A shipped binary updates itself from a signed release, by patch where it can: 197 KB instead of 946 KB between two builds 15 commits apart. Packages →

A UI whose frame is data

jm:ui is immediate mode, and every frame is plain arrays: a scene, a draw list, a hit list. A test clicks and types into it with no window. A change is checked as a text dump or a headless PNG, and the window hot-reloads the app from a child process on every build. Screen readers hear it through AccessKit on all three platforms. UI →

Material 3 buttons in every state Fluent 2 buttons in every state Primer buttons in the dark theme

Material 3 Expressive, Fluent 2 and GitHub Primer, generated from each system's own tokens. Every screenshot here was rendered headlessly by jm itself.

Pipelines that never block

jm:stream builds typed operators into a DAG of bounded edges. A node runs only when an edge changed and yields instead of waiting, so there is no thread per stage and no select. A stage hop costs about 20 ns, and the same pipeline runs on one thread for a deterministic test or on a pool in production. Streams →

Fuzzed, not hoped

Nine packages carry a property suite for jm:fuzz, with shrinking, a corpus and replayable seeds, and just test replays every corpus. The suites have found real bugs on their first runs: three crashes in the tar reader, a pointer check in the wasm host that wrapped, and invalid UTF-8 that PostgreSQL’s parser passes straight through. Fuzzing →

Linux, macOS, Windows

just check type-checks every package for all three targets from one machine. CI builds and tests every package on each of them. Building and testing →

Get started

git clone https://mordaunt.dev/code/jm && cd jm
./setup.sh             # install what the recipes need, report what is missing
just odin-run-install  # odin-run into ~/.local/bin, pointed at this checkout
just odin-run-example  # run examples/hello.odin

Then open a kitchen to see the UI: just material-kitchen, just fluent-kitchen or just primer-kitchen. Setup →

Learn more

Guide What it covers
Setup Toolchains and system libraries per platform
Writing scripts Conventions, logging, the odin-run cache
Packages Every package and what it does
Building and testing just recipes and CI
UI The frame model, needs and commands, hot reload, the example apps
Streams Dataflow pipelines and their measured costs
Fuzzing Property suites, isolation, and what they found
SQLite · zstd · WebAssembly The vendored C libraries and how they are built
PostgreSQL · Git The SQL parser, the libpq client and libgit2

Licence

Copyright 2026 Jack Mordaunt. jm is licensed under the Apache License 2.0. The vendored libraries keep their own licences, recorded beside their source or in their guide above. The jm name and mark are not covered by the code licence; see branding.

Commit log

Mirrored to sourcehut and GitHub.