fastC

compare · Zig

fastC vs Zig

The closest in spirit. Zig is excellent at cross-compilation and C interop; fastC chooses capability typing and contracts as the wedge.

Zig and fastC share a lot of taste: no hidden control flow, explicit syntax, "C but better" framing, fast cross-compilation, manual memory management with safety help, and a deep respect for binary size. The two languages diverge on which checks they push into the type system. Zig's wedge is comptime and explicit allocators; fastC's wedge is capability-typed I/O and mandatory contracts.

Row by row

Dimension fastC Zig Note
Memory safety without GC Yes (partial) — runtime checks + contracts Partial — explicit allocators, no borrow checker Roughly even; both ship safety-via-runtime-checks.
Capability-typed I/O Yes — CapFsRead, CapNetConnect, ... in signatures No — std.fs / std.net are ambient fastC's wedge over Zig.
Compile-time contracts Yes — @requires/@ensures, three-tier discharge Partial — comptime asserts, no postconditions Different goals; SPARK-style vs metaprogramming.
No executable build scripts Yes — declarative fastc.toml No — build.zig is arbitrary Zig Same critique Washburn made of Zig's package manager.
Outputs portable C11 Yes — auditable C No — emits LLVM IR directly Differentiated use case for fastC.
Cross-compilation 8 presets via `zig cc` 50+ targets natively, no sysroot Zig wins. fastC literally uses Zig's `zig cc` as backend.
C interop (ingesting C) No — emits C, does not parse C Yes — `@cImport` works on real C headers Zig wins. Different threat model.
Comptime / metaprogramming No — kept the surface small Yes — comptime is a major feature Zig wins on expressiveness; trade-off for surface area.
Package system Vendor-first, content-hashed, no central registry Zon manifest; arbitrary build.zig fastC's no-executable-build wins on supply chain.
Stripped 'hello' binary 53 KB 50 KB Roughly tied.
Provenance on releases Sigstore + SLSA L3 Project-by-project fastC structural.
Status / stability v1.0 feature-complete; v1.x roadmap Pre-1.0; rapid breaking changes fastC chose to commit to v1.0 earlier.
Agent-first toolchain (MCP, structured diagnostics) Yes — fastc-mcp + JSON output everywhere Standard CLI output fastC's wedge for the agent use case.
Safety on the T5 large_sum benchmark 3/3 correct, 0 silent-wrong 0/3 compiled (refused on signed `/` without `@divTrunc`) Different failure modes; both refused to ship wrong bytes.

Where fastC wins

fastC wins where the threat model is supply chain (no build.zig), capability-aware I/O, contracts as compile-time obligations, agent-first tooling (MCP, structured JSON diagnostics), and stability commitments. The capability and contract systems are the parts of language design Zig deliberately did not take on.

Where Zig wins

Zig wins where the threat model is C-interop-first (ingesting existing C codebases via `@cImport`), comptime metaprogramming, the broadest cross-compile target list, or where pre-1.0 instability is acceptable for access to a more aggressive feature roadmap. Zig is also the better tool for projects that want LLVM IR optimization quality directly.

The honest framing

We genuinely admire Zig. fastC's `--target` presets are implemented by shelling out to `zig cc`. The disagreement is narrow: should I/O be ambient (Zig) or capability-typed (fastC), and should pre/postconditions live in the language (fastC) or in comptime asserts (Zig). On the supply-chain side, we and Washburn appear to agree; Zig has not yet shipped that.

← all comparisons