Why a new systems language in 2026?
fastC's foundational thesis — what wedge it takes against C, Rust, Zig, and Go.
We did not set out to build a new language. We set out to find a stack we could ship LLM-generated systems code on, with a review process that fit inside the bandwidth a human reviewer actually has in a working day. The honest finding, after a quarter of trying, is that none of the existing languages were built for that constraint. So we built one.
This post is the foundational thesis. The five posts that follow walk through how the language actually got built — the stages, the trade-offs, the dead ends, the work that landed. This one is the why.
The 2026 framing
The modal author of new code in production today is an LLM. The modal reviewer is a human with fifteen minutes per PR. That is a different working environment from the one C was designed for in 1972, the one Rust was designed for in 2010, the one Go was designed for in 2009, the one Zig was designed for in 2016. Each of those languages optimizes for properties that mattered to its era: portability and minimal runtime, memory safety with zero-cost abstractions, simplicity and fast compiles, explicit control over allocation and undefined behavior.
None of them optimize for the cost of reviewing 800 lines of code an agent wrote yesterday.
That is the cost we ended up trying to minimize. The downstream consequence is a small list of language properties that, when you compose them, give you a review experience that scales. We will defend the list in the next five posts. Here it is in compressed form.
The four structural properties fastC commits to
1. Capability-typed I/O. Every I/O surface in fastC requires a capability argument in the function signature. fs::read needs a ref(CapFsRead). net::connect needs a ref(CapNetConnect). proc::spawn needs a ref(CapProcSpawn). The capability set is finite, named, and minted exactly once, in main, via caps::init(). There is no ambient I/O. A function whose signature declares no capabilities cannot reach for the network, the filesystem, the process table, or the environment. The compiler refuses the call.
The reviewer reading a diff of fastC reads the signatures first. The I/O surface of every function is visible in its signature. The reviewer does not have to read the body to know whether the function does I/O.
2. Mandatory contracts. @requires(cond) and @ensures(cond) are first-class function annotations. They sit above the signature. v1 lowers both to runtime traps via if (!cond) fc_trap(). v2.1 ships a three-tier discharge pipeline: syntactic patterns at tier 1 (no Z3 needed, the obvious cases), Z3 with a per-obligation budget at tier 2 (the SMT-shaped cases), runtime fallback at tier 3 (everything else). The discharge artifact is JSON, so the reviewer can audit which obligations were proved statically and which were left as runtime traps.
The agent that writes a divide-by-zero gets caught at runtime if the contract is present. The reviewer reading the contract sees what the function promises. The signature is the operating manual.
3. No executable build scripts. fastC’s manifest is declarative TOML. There is no build.rs. There is no go generate. There is no cgo. There is no preprocessor. The manifest declares dependencies, target triples, and feature flags. The compiler reads it. Nothing in the dependency tree gets to run code during fetch or build.
This is the structural answer to the 2025-26 wave of typosquat attacks against language registries. faster_log, async_println, evm-units, the timeapi.io impersonation — every one of them used build.rs to exfiltrate keys at compile time. fastC does not have a build.rs. The bug class is gone, not patched.
4. Vendored content-hashed deps. Dependencies are git URLs with rev, sha256, and cosign keyless signature verification. The vendor directory lives in your repo. There is no central registry. fastc.dev is a search frontend over GitHub; there is no service whose compromise would compromise every fastC build.
The 2017 npm event-stream takeover, the 2024 xz-utils backdoor, the 2025 tj-actions/changed-files compromise — every one of them depended on a central choke point. fastC has none.
What we don’t claim
The honest section, because the posts that follow get specific and we want to set the frame correctly.
fastC does not have a borrow checker. Rust still wins on the strong static guarantee that a freed pointer cannot be read. fastC’s contracts plus runtime trap layer get you most of the way for typical agent-generated code, but if your threat model requires memory safety as a hard compile-time property, Rust is still the answer.
fastC’s ecosystem is small. The curated launch set is eleven packages. Rust has 150,000+ crates. For most niches outside the curated set you will either write the binding yourself or FFI to a C library. We are explicit about this trade. The next posts cover where the trade is worth it.
fastC has no async story yet. Stage 2.3 is where async lands. Until then, every fastC program is synchronous. If your workload is “ten thousand concurrent connections,” fastC is the wrong tool today.
fastC’s source is verbose compared to Rust or Go. Types on every binding, parens on every binary operator, explicit casts on every width change. We think the verbosity is a feature for agent-generated code (the reviewer reads less context per line) but we acknowledge that humans writing fastC by hand feel the cost.
“Agent-friendly” is a hypothesis we measure, not a slogan. The README’s cross-language benchmark table is where we publish first-compile success rates by model. The numbers move; we update them. If they stop being favorable we will say so.
What this sets up
The next five posts walk through how the language actually got built. Post 2 is the core — the front-end, the safety baseline, the type system, traits, generics, and the stdlib MVP that took six months. Post 3 is the structural-safety wedge — capabilities and contracts, the two non-Rust claims. Post 4 is supply-chain and cross-compile — sha256, cosign, SLSA L3, eight pre-wired targets. Post 5 is the agent-tooling layer — fastc fix, fastc context, fastc diff, MCP. Post 6 is the curated ecosystem — the eleven packages, the v1.1 vendor cutover, the one-answer-per-domain thesis.
Each post is honest about where fastC loses. The wedge is real but it is narrow. The case for fastC is not “better than Rust at everything.” It is “the right shape for the specific working environment of LLM-generated systems code reviewed under bandwidth pressure.” If that is your environment, the wedge matters. If it is not, you have other good options.
The next post is where the actual building starts.
Comments? Issues? Disagreements? Open an issue at github.com/Skelf-Research/fastc/issues.