Zig as an Intermediate Language for EiffelStudio

by Finnian Reilly (modified: 2026 Jun 02)

    Contents
  1. Preface
  2. Introduction
  3. Prior Art and Community Context
    1. John Wolter's 2024 Proposal
    2. Eric Bezault's Practical Validation
    3. What This Paper Adds
  4. Eric Bezault's Observations
    1. Frozen Mode is Already Incrementally Generated
    2. The zig cc Caching Benefit is Already Validated
    3. C Interop from Zig
    4. The Garbage Collector — The Most Significant Open Question
    5. Acknowledgement
  5. Bertrand Meyer's Response
    1. On frozen/finalised behavioural divergence
    2. On C's platform ubiquity and accumulated expertise
    3. On the .NET backend precedent
    4. On the GC and concurrency
    5. On the real obstacle: cross-platform UI
    6. Bertrand's conclusion
  6. The C Backend: A Structural Assessment
    1. The Three-Tier Problem
    2. Frozen and Finalised Behavioural Divergence
    3. The Design by Contract Penalty
  7. The .NET Backend as Proof of Concept
  8. Why Zig Rather Than LLVM IR Directly
    1. Readability and Debuggability of Generated Code
    2. No Undefined Behaviour
    3. Cross-Compilation as a First-Class Feature
    4. The zig cc Stepping Stone
  9. The Macro Problem: A Significant Technical Challenge
    1. What the Macro Layer Actually Does
    2. What Zig Offers Instead
    3. The Real Implication: The Code Generator Must Be Smarter
  10. Zig's Incremental Compilation: The Central Argument
    1. The 50ms Claim: From the Founder's Own Words
    2. Collapsing the Three Tiers into One
    3. Design by Contract Restored
  11. The Zig Project: Credibility and Sustainability
    1. Financial Independence
    2. Community Reception
    3. The No-AI Policy: A Signal About Code Quality
    4. Moving to Codeberg
  12. Implementation Considerations and Risks
    1. Zig Is Not Yet at Version 1.0
    2. The Existing C Backend Investment
    3. Community and Ecosystem Size
  13. A Proposed Path Forward
  14. Conclusion (revised)
  15. See Also
  16. References and Notes

A Case for Replacing the C Backend — Discussion Paper for Review by Eiffel Software Engineering

(35–45 minutes: 6800 words)

Preface

This paper was inspired by watching the interview ''Zig 2026: No-AI Policy, $670K Foundation, Left GitHub & Why Zig Isn't 1.0 - Andrew Kelley Explains'', published 27 May 2026, in which Zig's creator Andrew Kelley describes — among other things — the incremental compilation milestone his team had just reached: sub-50-millisecond rebuilds of million-line codebases using Zig's own native x86 backend. That single claim prompted a discussion about what such a capability might mean for EiffelStudio's Melting Ice compilation model, and this paper grew out of that discussion.

The technical arguments were developed collaboratively between a practising Eiffel developer and an AI assistant (Claude, Anthropic). The Eiffel developer provided domain knowledge, real-world experience of the frozen/finalised divergence problem, and editorial direction throughout. The AI contributed structure, prose, and a number of the technical observations. The result is what it is: a plausible and reasonably well-informed argument, but one that should be reviewed by Eiffel Software engineers before being treated as authoritative. Factual corrections are actively welcomed.

Introduction

EiffelStudio has long used C as its primary intermediate language — the mechanism by which Eiffel source code becomes native executables. This was a sound choice when first made. C compilers are available on virtually every platform, and targeting C allowed EiffelStudio to achieve portability without building and maintaining a separate native code generator for each architecture. The approach is pragmatic and time-tested.

However, the C backend also carries structural costs that have become increasingly visible over decades of use. The three-tier Melting Ice compilation model — with its fundamental split between development and production behaviour — exists largely as a workaround for the slowness and opacity of invoking a C compiler as a subprocess. Frozen and finalised executables differ in behaviour in ways that are difficult to diagnose. Contract-heavy code written to Eiffel's Design by Contract philosophy runs at a significant penalty during development, encouraging developers to disable the very mechanisms that make Eiffel trustworthy.

This paper argues that Zig — a modern systems programming language with a mature and growing compiler infrastructure — represents a compelling candidate to replace or augment C as EiffelStudio's intermediate language. The argument draws on four pillars: the precedent established by the existing .NET backend; Zig's architectural properties as a compilation target; the specific advantages Zig's incremental compilation model offers for Eiffel's development workflow; and the credibility and sustainability of the Zig project itself.

Prior Art and Community Context

The idea of using Zig as a backend for Eiffel did not originate with this paper. It has been circulating in the Eiffel community since at least 2024, and one implementation has already quietly shipped. This section acknowledges that prior work and situates this paper's contribution within it.

John Wolter's 2024 Proposal

In September 2024, John Wolter posted to the eiffel-users mailing list under the subject Zig can work as an Eiffel backend, describing early experiments using Zig as an additional Eiffel backend using open source tooling. He identified the lack of a formal object-oriented system in Zig as a challenge, but noted that Zig's language features might allow OO translation to happen nonetheless, and pointed to Zig's cross-compilation capabilities and support for diverse emerging hardware targets as opening new markets for Eiffel. That post attracted 50 views but limited follow-up discussion — the community was not quite ready to engage with it at the time. It deserves recognition as the seed of the idea.

Eric Bezault's Practical Validation

The most significant prior contribution comes from Eric Bezault (Gobo Eiffel), who in February 2024 reported to the eiffel-users list that he had successfully used zig cc as a backend C compiler for the Gobo Eiffel compiler. His observation is worth quoting directly, as it is the most important single piece of evidence for the feasibility of Stage 1 of the path proposed in this paper:

quote: Gobo already supported clang as backend C compiler and zig cc is built on top of clang. So if EiffelStudio works with clang, it should be possible to use Zig as well. | Eric Bezault, eiffel-users, February 2024

This is not speculation — it is a statement from an Eiffel compiler expert who had already done it. The clang lineage of zig cc means that any Eiffel compiler already supporting clang as a backend C compiler can adopt zig cc with minimal friction. Eric also independently arrived at the same zero-install vision that Andrew Kelley describes as his gold standard: download, unzip, compile, with no further configuration or environment variables required. He credits Paul Cohen for originally bringing the Zig project to his attention.

By February 2026, Eric's Gobo Eiffel package was shipping with Zig toolchain integration as a standard part of the distribution, with users already experiencing faster subsequent compilations as a result. Stage 1 of the path proposed in this paper is therefore not a proposal — it is an existence proof. The question for EiffelStudio is whether to follow where Gobo has already gone.

What This Paper Adds

What the earlier discussions did not attempt, and what this paper tries to provide, is a detailed technical case: why the C backend's structural costs matter, what Zig's properties mean specifically for Design by Contract and the Melting Ice model, what the macro layer challenge involves and how Zig addresses each use case, and what a credible staged path from the current state to a full Zig backend might look like. The technical argument rests on prior community work and is now supported by Andrew Kelley's 2026 description of Zig's incremental compilation milestone. The present paper attempts to connect those dots.

Eric Bezault's Observations

Shortly after this paper was posted to the eiffel-users mailing list, Eric Bezault — author of the Gobo Eiffel compiler and the first person to ship an Eiffel compiler using the Zig toolchain in production — posted [https://groups.google.com/g/eiffel-users/c/bqCTH95TALk/m/HpMlmBQ7AQAJ a detailed technical response] raising four points that materially improve the paper's accuracy. They are summarised here with the paper's assessment of each.

Frozen Mode is Already Incrementally Generated

The paper implies that freeze mode involves regenerating C for the entire system. Eric corrects this: the Eiffel-to-C generation in frozen mode is already incremental — only modified classes have their C regenerated, thanks to the way Eiffel calls are implemented in C. It is the subsequent C compilation step that is slow, not the C generation step. Finalised mode by contrast does regenerate C from scratch in order to perform whole-program optimisations.

This is an important correction. It means that a Zig backend at the code generation stage would initially be slower than the current melt/freeze combination, because the Eiffel-to-Zig generation would not yet have the incremental machinery that the current C backend has accumulated over many years. The full benefit of Zig's incremental compilation only arrives once the Zig backend itself implements incremental code generation — which is a non-trivial engineering investment beyond simply targeting Zig as an output language.

The zig cc Caching Benefit is Already Validated

The paper underestimated the immediate benefit of adopting zig cc as the C compiler. Eric notes that the Zig toolchain provides an object file cache — if a generated C file has not changed since the last compilation, zig cc reuses the cached object file rather than recompiling. This is independent of anything EiffelStudio's code generator does, and it directly addresses the C compilation bottleneck in frozen mode. Eric confirms that Gobo Eiffel already takes advantage of this and it works well.

This strengthens the case for Stage 1 of the proposed path considerably. The caching benefit is available immediately, requires no changes to the code generator, and has been validated in production by Gobo. For a large EiffelStudio project where most classes are unchanged between builds, the reduction in C compilation time could be substantial.

C Interop from Zig

The paper does not address the significant role of external C routines in the Eiffel ecosystem. A large proportion of EiffelStudio's own libraries — Vision2, WEL, and many third-party wrappers — call existing C libraries directly through Eiffel's external routine mechanism. Eric raises the question of how easily this C code can be called from Zig.

This is actually one of Zig's strongest features. Zig can import C headers directly via @cImport and call C functions with no FFI overhead. The Zig toolchain bundles its own C compiler and libc implementations, making C interop a first-class capability rather than an afterthought. For a Zig backend, the external C routine mechanism that Eiffel libraries depend on would map naturally onto Zig's C interop without architectural changes.

The Garbage Collector — The Most Significant Open Question

The most technically substantive point Eric raises is one the paper omitted entirely: EiffelStudio has its own garbage collector implemented in C, deeply integrated with the runtime. A Zig backend raises questions the paper did not address:

  • Does the GC remain as C code and get called from generated Zig via C interop?
  • Does it need to be rewritten in Zig?
  • Can an existing GC such as the Boehm GC be used via a Zig binding?
  • Is implementing a GC for Eiffel objects even feasible given Zig's explicit memory
 management philosophy?

Zig's memory management model — explicit allocators, no hidden allocation, no built-inGC — means that a tracing garbage collector does not fit naturally into idiomatic Zig.However Zig's excellent C interop means the most pragmatic initial answer is probablyto retain the existing ISE GC as a C library called from generated Zig, exactly as itis called today from generated C. The GC does not need to be rewritten in Zig for afirst backend implementation — it simply needs to remain callable, which C interopmakes straightforward.

The Boehm GC option Eric mentions is worth noting as an alternative. The Boehmconservative tracing GC has been used successfully with many language runtimes, hasC bindings that Zig can call directly, and could serve as a fallback or alternativeto the ISE GC if needed. However given that the ISE GC is mature, well-tested, andalready integrated with Eiffel's object model, retaining it via C interop is likelythe lower-risk path for an initial implementation.

The GC question is the most significant unresolved technical challenge identified inresponse to this paper. It does not appear to be a showstopper — C interop providesa pragmatic bridging solution — but it is a genuine architectural question that anyserious implementation effort would need to resolve early.

Acknowledgement

The paper is indebted to Eric Bezault for these observations. His practical experienceshipping Gobo Eiffel with Zig toolchain integration makes his corrections particularlyvaluable, and his willingness to engage substantively with a paper explicitly flaggedas AI-assisted and in need of expert review is exactly the kind of community responsethe preface was hoping to attract.

Bertrand Meyer's Response

Prof. Bertrand Meyer — the designer of Eiffel and originator of Design by Contract — responded to this paper on the eiffel-users mailing list, offering a measured and substantive assessment. His response is reproduced in summary here, with the paper's revised position on each point. Bertrand acknowledged the proposal as technically feasible while questioning whether the effort is justified by the rationale offered. His specific observations are worth engaging with directly.

On frozen/finalised behavioural divergence

Bertrand writes that cases of semantic discrepancy between melted, frozen and finalised code are rare in his experience and, when they arise, are characterised as bugs and fixed. He invites others who have had a different experience to say so. Having examined the Eiffel-Loop commit history across 1,891 commits spanning a decade, this paper's author found only three commits that document genuine frozen/finalised behavioural discrepancies — all occurring in 2021, all on EiffelStudio 16.05, and all likely fixed in subsequent releases. Bertrand's characterisation of the problem as rare is supported by this evidence. The paper's original framing overstated this argument and it is withdrawn as a primary justification. The frozen/finalised divergence is a real phenomenon but not frequent enough to constitute a strong case for backend replacement on its own. The more honest observation is that the migration barrier to versions where these bugs are fixed is itself non-trivial — 57 ECF files to update, development preferences to re-establish, new version-specific bugs to find and work around. The structural cost is less the divergence itself and more the friction of staying current. But this is a maintenance argument, not an architectural one.

On C's platform ubiquity and accumulated expertise

Bertrand notes that C is available on essentially any platform with well-maintained compilers, and that decades of experience have been accumulated in understanding what the C backend can and cannot do. Starting over with a new technology means starting that clock again from zero, and getting to the right level of reliability and stability is a separate challenge from producing a basic version that works. This is the strongest counter-argument in his response and it is accepted in full. The C backend's stability is not incidental — it represents an enormous investment in understanding a specific technology's behaviour under a specific set of constraints. A Zig backend would not inherit any of that knowledge. The staged approach proposed in this paper is partly an answer to this concern — beginning with zig cc as a drop-in C compiler requires no new knowledge at all, and each subsequent stage can be validated against the C backend before proceeding. But Bertrand's caution is well-founded and the paper does not minimise it.

On the .NET backend precedent

Bertrand observes that despite all the effort invested in the .NET retargeting, and all the good technical arguments for it, it has not seen much traction. Most users still prefer the C-based platform even without SCOOP. He does not fully know why but the reality is undeniable. This is a sobering observation that the paper did not anticipate. If the .NET backend — a mature, well-resourced target with a large developer ecosystem — failed to attract significant adoption, it raises a genuine question about whether a Zig backend would fare differently. The .NET case suggests that technical merit alone does not drive adoption of alternative backends, and that the C backend's incumbency is stickier than architectural arguments would predict. This paper has no good answer to this point. It is noted as an open question.

On the GC and concurrency

Bertrand echoes Eric Bezault's question about the garbage collector and raises an additional concern: concurrency and SCOOP. The .NET retargeting hit the concurrency obstacle. A Zig backend would face the same question — how does Eiffel's SCOOP concurrency model map onto Zig's concurrency primitives, which are deliberately minimal? These are the two most technically serious unresolved questions identified in response to this paper. The GC question is addressed in the Eric Bezault section above — C interop provides a pragmatic bridging solution. The SCOOP question is harder and this paper does not attempt to answer it. It is flagged as a prerequisite for any serious implementation effort.

On the real obstacle: cross-platform UI

Bertrand's most important reframe is his suggestion that the real technical obstacle for Eiffel's attractiveness is not the melt/freeze/finalise split but the difficulty of writing seamless applications across desktop platforms, the browser, and mobile, with graphics and concurrency fully supported. Does Zig retargeting help here? The honest answer is: not directly. Zig's cross-compilation story helps with native desktop targets but does not solve the browser and mobile problem. WebAssembly is a Zig target, which is relevant, but the full cross-platform UI story requires much more than a compiler backend change. Bertrand has correctly identified that this paper addresses a real but secondary problem. The primary obstacle to Eiffel's wider adoption is elsewhere.

Bertrand's conclusion

Bertrand closes by saying he does not necessarily believe C as a target language will be with Eiffel forever, and that he welcomes the discussion, but the choice of replacement must be made very carefully, starting from the basic question of what would most increase Eiffel's attractiveness. This paper accepts that framing as the right one.

The C Backend: A Structural Assessment

The C backend has served EiffelStudio well, but understanding its limitations requires examining not just what it does, but the architectural constraints it imposes on the entire compilation pipeline.

The Three-Tier Problem

EiffelStudio's Melting Ice Technology divides compilation into three modes: melting, freezing, and finalising. Each mode exists to serve a different goal — speed of iteration, debuggable native code, and optimised production output respectively. The elegance of the metaphor — frozen ice, melted drops — should not obscure that this three-tier model is fundamentally a consequence of using C as the backend.

Melting is fast because it bypasses C compilation entirely, running changed code through a bytecode interpreter. This achieves fast iteration at the cost of running two execution models simultaneously: recently changed code is interpreted while unchanged code runs as compiled native binary. The resulting execution environment is not the same as a deployed system.

Freezing generates C and invokes the C compiler, producing a debuggable native binary. However, the C compiler used at freeze time does not perform the whole-program optimisation that finalisation performs. Devirtualisation, dead feature elimination, cross-class inlining — these are unavailable to the freeze-time C compiler because it does not have visibility across the entire system at once.

Finalisation performs a global analysis pass before emitting C, enabling these whole-program optimisations. The resulting binary runs substantially faster — sometimes matching hand-written C++ — but is not debuggable, because the optimisations it applies destroy the structural correspondence between source lines and machine instructions that a debugger requires.

The practical consequence is that developers cannot work with the same binary they will ship. They debug in an environment that runs differently from production, and they measure performance in a build that cannot be debugged. This is not a minor inconvenience — it is a fundamental separation between development and deployment that opens a gap in which bugs can hide.

Frozen and Finalised Behavioural Divergence

In practice, experienced EiffelStudio developers know that unit tests must be run against finalised code, because frozen and finalised builds can behave differently. This divergence is rare but when it occurs it is extremely difficult to diagnose. The developer cannot attach a debugger to the build exhibiting the problem, and the build that accepts a debugger does not exhibit the problem.

The root causes are several. Finalisation's dead feature elimination may incorrectly determine that a feature is unreachable, removing code that frozen builds retain. Devirtualisation at finalisation time may incorrectly resolve a polymorphic dispatch, inlining the wrong concrete method. Most fundamentally, the generated C may contain patterns that constitute undefined behaviour under the C standard — patterns that a conservatively optimising freeze-time compiler tolerates silently, but that an aggressively optimising finalise-time compiler exploits in ways that change observable behaviour.

The Design by Contract Penalty

Eiffel's Design by Contract — preconditions, postconditions, and class invariants — is the language's most distinctive contribution to software engineering. It is the mechanism by which Eiffel programs can provide correctness guarantees that are enforced at runtime, not merely stated in documentation.

The C backend creates a practical dilemma for DbC during development. Class invariants that walk data structures on every call, or postconditions that perform non-trivial verification, impose runtime costs that are substantial in melted and frozen builds — where virtual dispatch overhead is not eliminated, where inlining does not collapse contract calls into inline comparisons, and where the interpreter adds its own overhead on top. The result is that developers routinely reduce assertion levels during development to make the system responsive, re-enabling contracts only for final validation.

This is a significant compromise. Consider a real-time audio or playback system where timing constraints are hard. In melted mode the system may simply be too slow to demonstrate correct behaviour under real-time conditions. The developer must disable contracts to hit the timing budget, and in doing so removes the safety net precisely when it is most needed — when exploring new code under production-like stress.

The .NET Backend as Proof of Concept

Before examining Zig's properties as a target, it is worth observing what the existence of EiffelStudio's .NET backend demonstrates about the team's capabilities and the compiler's architecture.

Targeting the .NET Common Language Runtime required solving a set of deeply non-trivial problems. The CLR has a rich, opinionated type system; mapping Eiffel's class hierarchy and multiple inheritance model onto CLR types required careful design. The CLR manages memory through a garbage collector the Eiffel runtime does not control; reconciling Eiffel's own memory semantics with the CLR's required significant engineering. .NET generics are constrained in ways that Eiffel's parametric polymorphism is not. The CLR's exception model uses structured exception handling; Eiffel's rescue and retry mechanism had to be expressed in terms of a fundamentally different exception architecture.

Solving these problems required the EiffelStudio team to decouple Eiffel's semantics from assumptions baked into the C backend — to identify what was fundamental to the language and what was an artefact of one particular implementation strategy. This decoupling is precisely the prerequisite for targeting a second backend. The .NET backend did not merely add a compilation target; it forced and validated an architectural separation between the language's semantics and its implementation.

Targeting LLVM IR — which Zig uses as one of its own backends — is arguably less demanding than targeting .NET. LLVM IR is minimal and low-level; it has almost no opinions about type systems, memory models, or calling conventions. A team that successfully mapped Eiffel onto the CLR has already demonstrated the harder conceptual capability.

Why Zig Rather Than LLVM IR Directly

Given that LLVM IR is an ultimate compilation target anyway, one might ask why Zig should be the intermediate language rather than targeting LLVM IR directly. The answer lies in the practical advantages Zig offers beyond what LLVM IR alone provides.

Readability and Debuggability of Generated Code

LLVM IR, while more readable than machine code, is not designed for human inspection. Zig is. Generated Zig code, while not what a human programmer would write by hand, is readable, structured, and checkable. When the code generator has a bug — and code generators always have bugs — the intermediate representation can be inspected and understood by an engineer familiar with Zig. The existing C backend provides this property to some extent, but C's undefined behaviour makes generated C treacherous to reason about. Zig's explicit treatment of unsafe operations makes generated Zig considerably more trustworthy as an artefact for human inspection.

No Undefined Behaviour

The frozen/finalised behavioural divergence discussed earlier is largely a consequence of C's undefined behaviour. Zig does not have this category of problem. Operations that would be undefined in C — signed integer overflow, out-of-bounds access, use of uninitialised memory — are either detected at runtime in debug builds or must be explicitly opted into. A code generator targeting Zig cannot accidentally produce UB that is silently tolerated in development and exploited in release.

Cross-Compilation as a First-Class Feature

Zig's cross-compilation story is substantially better than C's. Zig ships with its own libc implementations for a wide range of targets and can cross-compile to any supported target from any host with a single compiler invocation. For EiffelStudio, which targets Windows, macOS, Linux, FreeBSD, and other platforms, this would simplify build infrastructure considerably. Notably, Uber already uses zig cc to cross-compile Go code with C dependencies for ARM64 targets — a practical validation of this capability at production scale.

The zig cc Stepping Stone

An important practical point: adopting Zig does not require immediately rewriting the code generator. Zig ships a C compiler frontend — invocable as zig cc — that is a drop-in replacement for clang, with full cross-compilation support. EiffelStudio could adopt zig cc as the C compiler used during freeze and finalise as an immediate first step, gaining cross-compilation benefits without any changes to the code generator itself.

The Macro Problem: A Significant Technical Challenge

Any honest assessment of a Zig backend for EiffelStudio must confront a substantial technical obstacle: EiffelStudio's generated C relies heavily on C macros, and Zig has no macro system. This is not a minor compatibility issue — the macro layer is load-bearing in the current architecture.

What the Macro Layer Actually Does

EiffelStudio's use of C macros in generated code is not accidental — each use case was well-motivated. Macros abstract over platform differences: a type alias such as EIF_INTEGER expands to the appropriate integer type for the target architecture, with the C preprocessor resolving the variation before the compiler sees it. Macros implement virtual dispatch table access, allowing the exact structure of type descriptors to be tuned per platform. Macros control assertion levels at compile time. Macros implement garbage collector write barriers — inlined at every reference assignment. And macros paper over calling convention differences and alignment requirements across the platforms EiffelStudio targets.

In aggregate, the macro layer functions as a second code generation step performed by the C preprocessor for free.

What Zig Offers Instead

Zig has a deliberate answer to every macro use case, and in each case the answer is architecturally cleaner — but it requires the code generator to do more work explicitly.

Platform portability, currently handled by type-aliasing macros, is addressed in Zig through comptime and the builtin target query system. Virtual dispatch tables become explicit Zig struct definitions with function pointer fields. Assertion level control maps naturally onto Zig's builtin.mode — a compile-time value representing the optimisation tier — allowing contract checks to be gated on comptime conditionals that the compiler eliminates entirely in release builds. Garbage collector write barriers become Zig inline fn declarations — a genuine language guarantee of inlining, unlike C macros, and with full type-system participation.

The Real Implication: The Code Generator Must Be Smarter

The absence of macros in Zig means every platform variation currently resolved by the preprocessor must instead be resolved by the code generator itself. What the code generator emits is what Zig sees — there is no second pass.

This is genuinely more work. The implicit platform knowledge encoded in the macro layer — accumulated over decades and distributed across header files — must be made explicit. However, this constraint contains an opportunity. EiffelStudio's C macro layer is essentially undocumented tribal knowledge, encoding platform portability logic, GC integration details, dispatch mechanisms, and contract handling in a form that is difficult to read, impossible to type-check, and invisible to debuggers. Moving to Zig forces all of that implicit knowledge into explicit, typed, debuggable code.

The macro layer was a solution to 1990s problems: unreliable C compiler availability, unstable portable type definitions, untrustworthy inline functions. Zig eliminates each of these problems at the language level.

Zig's Incremental Compilation: The Central Argument

The most compelling argument for Zig as EiffelStudio's intermediate language is Zig's incremental compilation architecture and what it would mean for the Melting Ice model.

The 50ms Claim: From the Founder's Own Words

This is not speculation. In a 2026 interview, Andrew Kelley — Zig's creator — described the capability directly:

quote: When you're using our own x86 backend, we now have incremental compilation that brings even massive million line code bases down to 50 milliseconds or less with changes. You make a change to your code, you have a new binary already updated, 50 milliseconds, million line codebase. And this is simply not possible with LLVM, but this is something that we can do now with our own code. | Andrew Kelley, interview, 2026

Kelley explained the architectural reason this is possible: Zig is in the process of ditching LLVM for its own native backends, which it describes as removing a core product dependency. By owning the entire compilation pipeline, Zig can implement true incremental compilation — patching object code in-place rather than recompiling. This is categorically different from what Melting Ice achieves. Melting Ice achieves fast iteration by abandoning native compilation for changed code. Zig's incremental compilation achieves fast iteration while retaining it.

Collapsing the Three Tiers into One

If EiffelStudio targeted Zig and took advantage of Zig's incremental compilation, the three-tier Melting Ice model could collapse into a single development build. There would be no need for a distinct melt mode running interpreted bytecode, because the native build would already rebuild in milliseconds. There would be no frozen/finalised divergence, because there would be one code generation path with one set of optimisation decisions. The binary a developer runs and debugs would be the same binary — at a lower optimisation level — as the binary shipped to users.

This is not a marginal improvement. It resolves the fundamental structural problem with EiffelStudio's compilation model — that development and production are different worlds — without sacrificing either iteration speed or execution correctness.

There is also an important interaction with the debugger. Modern LLVM-based debug info (DWARF) is sophisticated enough that meaningful debugging is possible at moderate optimisation levels. A development build using Zig could be moderately optimised — enough that contracts are not cripplingly slow — while retaining good line-level debugger fidelity. That middle ground barely exists in EiffelStudio's three-tier model today.

Design by Contract Restored

If incremental native compilation makes development builds fast enough that full contract checking is affordable throughout the development cycle, developers no longer face a choice between responsive development and contractual correctness. Preconditions, postconditions, and class invariants can remain enabled continuously — catching violations at the earliest possible moment, in the normal flow of development rather than only in finalised test runs.

For a real-time system, a development build at moderate optimisation with full contracts might well meet the timing requirements that an interpreted melted build cannot, while still rebuilding in milliseconds after a change. The contracts would be doing their job throughout the development process.

The Zig Project: Credibility and Sustainability

An argument for depending on Zig requires confidence that Zig will exist and be maintained over the multi-year horizon of a backend project. The evidence here is reassuring.

Financial Independence

The Zig Software Foundation is a US 501(c)(3) nonprofit — not a startup, not VC-backed. In 2024 its total income was $670,000, of which 91% went directly to paying the five contractors who work on the project. Kelley is the foundation's sole employee, drawing a salary of $154,000 — the median senior software engineer salary in New York City at the time the nonprofit was formed. The income is deliberately diversified across many individual donors and companies, so that no single sponsor can exert leverage. As Kelley put it: we can turn to any individual sponsor and say I'm sorry but we will not do what you say and if you take your money away we will survive.

When asked whether he would accept a hypothetical $100 million donation, Kelley said he would take it — but not grow. He would put it in the bank and never fundraise again for 100 years. This is not a project chasing growth or an exit. It is run as a long-term craft.

Community Reception

Zig is consistently ranked in the top five most admired programming languages in developer surveys. Notable production users include Ghostty (a terminal emulator by Mitchell Hashimoto), TigerBeetle (a financial transaction database that achieves a thousand-fold performance advantage over Postgres-based OLTP by using Zig's predictable allocation model), Bun (a JavaScript runtime, now owned by Anthropic), and Uber (which uses zig cc for cross-compiling Go code with C dependencies). This is not a toy language — it is in production at serious organisations.

The No-AI Policy: A Signal About Code Quality

Zig has a strict no-LLM, no-AI policy for contributions. Kelley's reasoning is worth understanding: AI-generated pull requests are invariably garbage — they consume limited reviewer time, teach the contributor nothing, and will never lead to core team membership. The policy is also framed as part of Zig's educational mission: the project exists partly to develop skilled systems programmers, and AI contributions undermine that goal.

This policy is relevant to EiffelStudio for a different reason: it signals that the Zig codebase and its contributors are held to a high standard of genuine understanding. A project that makes this choice about its own contributors is likely to make careful decisions about language design as well.

Moving to Codeberg

In late 2025, Zig moved its main repository from GitHub to Codeberg after GitHub's continuous integration became unreliable. Codeberg is a German nonprofit hosting service. This move caused some community discussion about whether it would harm adoption, but Kelley's view is clear: I don't think that people are discovering Zig through GitHub or Codeberg. I think they're discovering it through talks, meetups, YouTube videos. The move is consistent with the project's preference for nonprofit infrastructure and independence from corporate platforms.

Implementation Considerations and Risks

Zig Is Not Yet at Version 1.0

Zig's most recent release at the time of writing is 0.16 (beta). The language's incremental compilation with its own x86 backend is arriving in this release cycle, but full feature coverage across all targets is still in progress. Targeting an unstable language as an intermediate representation carries the risk of breaking changes requiring ongoing maintenance of the code generator.

This concern is genuine but bounded. Kelley has stated that when 1.0 arrives, it will be a true uncompromising labor of love — we will not have to be stuck with any bad decisions that we had to rush to lock in. The core language semantics are substantially stable already. A multi-year backend project would likely complete after 1.0 is tagged.

The Existing C Backend Investment

Decades of engineering work are embedded in EiffelStudio's C code generator, runtime, and garbage collector integration. A Zig backend would not replace this overnight. The practical approach would be incremental: the zig cc adoption path requires no changes to the code generator. A Zig backend could initially target a well-defined subset of Eiffel, with the C backend retained as reference and fallback throughout.

Community and Ecosystem Size

Both Eiffel and Zig are languages with smaller communities than C, Rust, or Go. A dependency between two smaller ecosystems concentrates risk. This risk is partially mitigated by LLVM as a fallback — a Zig backend for EiffelStudio would have the option of targeting LLVM IR directly if Zig itself became problematic.

A Proposed Path Forward

Rather than framing this as a binary choice, a staged approach distributes risk while capturing early benefits.

Stage 1 — Adopt zig cc as the C compiler
Replace the C compiler invoked during freeze and finalise with zig cc. No changes to the code generator. Immediate gain in cross-compilation capability and a basis for evaluating Zig tooling.
Stage 2 — Prototype Zig code generation for a subset
Implement a Zig code generator for a well-defined subset of Eiffel — perhaps flat classes without agents or generics — and validate output correctness against the C backend. At this stage, explicitly map each macro use case to its Zig equivalent and document the code generator requirements. Evaluate the development experience with Zig's incremental compilation on this subset.
Stage 3 — Extend to full Eiffel feature set
Progressively extend the Zig backend to cover agents, generics, expanded types, and the full rescue/retry mechanism. Maintain the C backend as reference and fallback throughout.
Stage 4 — Collapse the Melting Ice tiers
Once the Zig backend achieves feature parity and Zig's incremental compilation is stable across targets, restructure the development build to use Zig's incremental native compilation in place of the melt/freeze distinction. Evaluate whether the finalise tier can be simplified or whether LLVM-level optimisation should remain as a release-only path.

Conclusion (revised)

This paper began as a case for replacing EiffelStudio's C backend with Zig. It ends in a more modest but more honest position, shaped by substantive responses from Eric Bezault and Bertrand Meyer. The original argument rested on three pillars: frozen/finalised behavioural divergence, the Design by Contract performance penalty, and the incremental compilation opportunity. Of these, the first has been substantially weakened by examining the actual commit history — three genuine incidents over a decade on one EiffelStudio version does not constitute a strong case. The second remains valid but is a development experience argument rather than a correctness one. The third remains the most technically compelling, but Eric Bezault's correction — that the Eiffel-to-C generation step is already incremental, and that only the C compilation step would benefit immediately from Zig — narrows the near-term gain.

What survives scrutiny is a more limited but still worthwhile case:

Stage 1 — adopt zig cc — is already validated and low risk. Eric Bezault has done it for Gobo Eiffel. The object file caching alone delivers meaningful build speed improvement for frozen mode with zero changes to the code generator. EiffelStudio already works with clang, and zig cc is built on clang. This is the one recommendation from this paper that is actionable immediately, at low cost, with existing evidence of success.

The full Zig backend is a long-term research question, not a near-term project. Bertrand is right that the choice of a C replacement must be made carefully, starting from first principles about what would most benefit Eiffel. The GC question, the SCOOP question, the accumulated C expertise question, and the .NET adoption cautionary tale all argue for deliberation rather than urgency. The macro layer analysis in this paper is a contribution to that deliberation — it identifies what a Zig backend would need to do differently — but it does not resolve the deeper questions.

The cross-platform UI observation reframes the whole discussion. If the primary obstacle to Eiffel's attractiveness is seamless cross-platform development including browser and mobile, then compiler backend work is addressing the wrong problem. A Zig backend might eventually help at the margins — better WASM compilation, cleaner cross-compilation — but it is not the answer to the question Bertrand is actually asking. That question deserves its own discussion.

The DbC argument stands independently. Whatever backend EiffelStudio uses, the Design by Contract performance penalty during development is a real cost that discourages developers from using contracts as continuously as Eiffel's philosophy intends. Faster development builds — by whatever means — would restore contracts to their proper role. Zig is one path to faster builds. It may not be the only or best path.

This paper has been more useful as a prompt for expert discussion than as a definitive proposal. The responses from Eric Bezault and Bertrand Meyer have improved the understanding of the problem considerably, and the conversation they have started is more valuable than any specific recommendation the paper made. That is perhaps the most that a discussion paper written by an AI-assisted Eiffel developer over the course of a single day should claim to have achieved. The discussion continues, and Bertrand's closing invitation — let's continue the discussion — is the right note on which to end.

See Also

References and Notes

  • Incremental compilation timing claim: Andrew Kelley, video interview, 2026. Direct quote used in the body of this article.
  • Zig Software Foundation finances: 2024 annual report, published on the Zig blog.
  • EiffelStudio compilation modes: Melting Ice Technology documentation on eiffel.org.
  • This article should be reviewed for accuracy regarding EiffelStudio's internal C code generation, the precise role of macros in generated output, and the current state of the .NET backend. The authors welcome corrections from Eiffel Software engineers.