Validated on real codebases
-O2Validated on real codebases
A single executable that cross-compiles to all targets from any platform.
C-like syntax with modern conveniences. Function overloads, type inference, generics, struct literals, defer, slices, named arguments.
struct Rect { i32 x, y, w, h; } bool contains(Rect r, i32 px, i32 py) { return px >= r.x && px < r.x + r.w && py >= r.y && py < r.y + r.h; } i32 main() { print("Hello, world! 🎉\n"); var box = Rect{ .x = 0, .y = 0, .w = 64, .h = 48 }; print("hit = {}\n", contains(box, px: 10, py: 20)); return 0; }
The compiler is ~150k lines of minc and compiles itself to a 2.1 MB executable with no external dependencies.
Math functions lower to single CPU instructions or come from a math library written in minc, so results are identical on every platform.
Programs call the operating system directly: kernel32.dll on Windows, raw syscalls on Linux, libSystem.B.dylib on macOS and iOS.
On WebAssembly a small minc stdlib provides the same functions.
Small and medium projects compile in milliseconds.
// Cross-compiler + all targets: ~2.1 MB
$ minc run hello.mc
-> hello.exe (2.5 KB) (4 lines) // 20 ms
Hello, world! 🎉
$ minc sokol_cube.mc
-> sokol_cube.exe (137.5 KB) (61,804 lines) // 200 ms
One executable writes Windows, Linux, macOS, iOS, Android, WASM and UEFI binaries itself, with its own assembler and linker. Cross-compile from any platform to any target. macOS ad-hoc code signing is built in.
JIT: libminc (.dll, .so, .dylib) recompiles code at run time and hot-swaps it through a cross-platform API.
// Cross-compile from any platform: $ minc app.mc --target windows // Windows PE $ minc app.mc --target linux // Linux ELF $ minc app.mc --target macos // macOS Mach-O $ minc app.mc --target wasm // WebAssembly // Launches built-in webserver and runs WASM // --shader-live enables shader live edits $ minc run --target wasm --shader-live app.mc
Generics, tagged unions with exhaustive pattern matching, type aliases, auto-deref, type inference, function overloading, named arguments, destructuring, range-based for-loops, compile-time format strings, and a module system.
union Result<T, E> { Ok(T), Err(E) } // tagged union var p = Point{3, 4}; // type inference var (x, y) = get_pos(); // destructuring node.next.value; // auto-deref (no -> needed) draw(width: 800, height: 600); // named arguments for i32 i in 0..n { sum += data[i]; } // range-based for print("{} + {} = {}\n", a, b, a+b); // compile-time T max<T: Numeric>(T a, T b) { // constrained generic return a > b ? a : b; }
Vector and matrix types such as float4, float4x4 and f64x2
are part of the language. Arithmetic on them lowers to native SIMD
instructions (SSE/AVX, NEON, WASM SIMD) on every target.
// Built-in vector and matrix types float4 pos = float4{x, y, z, 1.0}; float4x4 mvp = proj * view * model; // Arithmetic lowers to SIMD (SSE/AVX, NEON, WASM SIMD) float4 clip = mvp * pos; float4 lit = color * light + ambient; f32 d = dot(a, b); float4 n = normalize(v); // Same types used in shaders (@shader) and CPU code.
Write shaders in minc syntax with @shader annotations.
The compiler translates them to HLSL, GLSL, Metal or WGSL for the
target API as part of the normal build.
Shader live reload: save a shader file while the app runs and the change appears on screen. The file-watch API behind it works on every platform.
struct VsOut { float4 pos; float4 color; } @shader vertex VsOut cube_vs( @attr(0) float4 position, @attr(1) float4 color, @uniform float4x4 mvp ) { VsOut o; o.pos = mul(mvp, position); o.color = color; return o; } @shader fragment float4 cube_fs(VsOut input) { return input.color; }
Arithmetic and indexing have defined behavior everywhere. Arrays are bounds-checked,
integer arithmetic wraps, mixed signed/unsigned is a compile error, and lossy
conversions need an explicit cast. @strict_float pins a function's
floating-point results to the same bits on every target. Defer for deterministic
cleanup. Format strings are checked at compile time. Built-in atomics, threads
and cooperative fibers.
// Defer: deterministic LIFO cleanup var fd = open("data.bin", 0); defer close(fd); var buf = alloc<u8>(4096); defer free(buf); // both freed in reverse order at scope exit // signed overflow wraps, no UB i32 x = 0x7FFFFFFF + 1; // Cooperative fibers (import fiber;) void producer(void* arg) { print("step 1\n"); fiber_yield(); print("step 2\n"); } // Threads (import thread;) Thread t; thread_create(&t, worker, arg); thread_join(&t);
Call C functions with an extern declaration that names the library.
The Windows API works the same way, straight from the DLL name. Link COFF, ELF
and Mach-O objects directly, or let a library bundle its own C shim. minc functions
pass back to C as callbacks, since minc follows the platform C ABI on every target.
// The library is named at the declaration. when os(windows) { extern "user32.dll" i32 MessageBoxW(void* hwnd, u16* text, u16* title, u32 flags); } when os(linux) { // block form: one lib, many fns extern "libc.so.6" { i32 getpid(); i64 sysconf(i32 name); } } // A library can carry its own C shim. The @link tag // follows the import, so `minc app.mc` links it: // lib/audio.mc: @link "audio_shim.obj" import audio; // minc functions flow back into C as callbacks // (the platform C ABI on every target): extern void set_log_handler(fn(u8*): void cb); void on_log(u8* msg) { /* ... */ } set_log_handler(on_log);
A native debugger (minc-dbg) for Windows, Linux and macOS ships with the
compiler. minc debug prints a symbolized backtrace on a crash,
minc profile samples where the time goes, and
--track-alloc reports leaks when main returns.
The VS Code extension ships with the compiler and adds F5 debugging. Backed by the minc language server for go-to-definition, hover, completion and live diagnostics.
Simple, fair pricing based on company size. No enforcement, honor system.
If your company makes over €100k/year and uses minc commercially, buy a license.