/smɛlt/ — to form ore into metal.
We stopped reading agent-generated code. PRs get approved with a mass thumbs-up, diffs scroll past unreviewed, the code "works" and nobody questions the stack underneath. If the human is no longer the bottleneck — no longer the one checking every line — then why keep generating bloated, interpreted, runtime-dependent code?
smlt takes the logical next step: let the agent write code as close to the metal as it gets. The LLM acts as a compiler frontend, emitting portable LLVM IR from natural language. The result is small, fast, dependency-free native binaries. No runtime. No garbage collector. No node_modules. Just machine code.
curl -fsSL https://github.com/smltdev/smlt/releases/latest/download/smlt-$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/aarch64/arm64/') -o /usr/local/bin/smlt
chmod +x /usr/local/bin/smltThen fetch the core toolchain (modules, platform libs):
smlt fetch coreThis clones the core repo into $SMLT_HOME (defaults to ~/.local/share/smlt). You can override it:
export SMLT_HOME=/path/to/smlt
smlt fetch coreRequirements: clang and llvm-link.
# macOS
xcode-select --install
brew install llvm
# Ubuntu / Debian
apt install clang llvmThe skill teaches Claude how to emit LLVM IR, use the module system, and build native binaries.
For projects inside the core repo — it works automatically. Claude picks it up from the project directory.
For any other project — run from your project directory:
smlt install-skillThis downloads the latest skill into .claude/skills/smlt/. For Codex or other agents that use .agents/:
smlt install-skill --agentssmlt build app.ll output --auto # build with auto-detected modules
smlt build app.ll output --use buf # explicit module selection
smlt cross app.ll myapp --auto # cross-compile for all platforms
smlt install app.ll # build and install to $SMLT_HOME/bin/
smlt run app.ll -- args # build to temp, execute, clean up
smlt fetch <module> # fetch module from registry
smlt install-skill # install Claude Code skill
smlt doctor # check build environmentnatural language
|
Claude (compiler frontend)
|
app.ll portable IR — no target triple, no OS constants
|
+ modules/ pre-built, audited IR modules (buf, http, str, ...)
+ platform/ per-target platform abstraction
|
smlt build → native binary
App IR declares module symbols. The build system resolves dependencies, links the correct platform module, and compiles to a native binary. LTO inlines everything — zero runtime overhead.
Pre-built modules cover common infrastructure so the LLM generates only app-specific logic:
| Module | Purpose |
|---|---|
| buf | Bounds-checked buffer writes, JSON escaping, IP formatting |
| cli | Argument parsing, help text formatting |
| ev | Async event loop (io_uring on Linux, kqueue on macOS) |
| fs | File I/O: read, write, append, exists, mkdir |
| hex | Hex encoding/decoding |
| http | Async HTTP/1.1 server (callback-based) |
| httpc | HTTP/1.1 client with TLS/HTTPS support |
| proc | Fork/exec, stdout capture |
| sha256 | SHA-256 hashing (incremental or one-shot) |
| sort | In-place insertion sort |
| str | String comparison, search, integer conversion |
| tar | Create and iterate tar archives in memory |
| tls | OpenSSL/LibreSSL wrapper for client and server TLS |
Modules are portable IR — no target triple, no OS constants. Each has a manifest.yaml with symbols and dependencies. See modules/buf/ as the reference implementation.
All cross-platform differences are hidden behind platform_* calls:
| macOS | Linux | |
|---|---|---|
| SOL_SOCKET | 65535 | 1 |
| SO_REUSEADDR | 4 | 2 |
| sockaddr_in byte 0 | sin_len (u8) | sin_family (u16) |
| addrinfo.ai_addr | offset 32 | offset 24 |
Supported platforms: darwin-arm64, darwin-x86_64, linux-x86_64, linux-arm64.
platform/ Per-target platform modules
modules/ Pre-built IR module library
apps/smlt/ smlt CLI tool (built with smlt)
apps/fetch/ curl-like HTTP/HTTPS client
apps/registry/ Module registry server
examples/ Example applications
.claude/skills/smlt/ Claude Code skill for IR codegen