What is ABI stability vs source compatibility vs module stability?
Mental model. Source compatible: old code still compiles. ABI stable: old binaries still run. Module stable: old compiled modules still load.
Source compatibility — code written against the old API still compiles against the new one.
ABI stability — a binary compiled against the old library still links and runs against the new one (Swift 5 on Apple platforms).
Module stability — a .swiftinterface lets a binary framework ship without a compiler-locked .swiftmodule, so it can be consumed by different compiler versions.
They are independent: you can break source without breaking ABI (e.g. renaming a parameter label) and break ABI without breaking source (changing a @frozen layout while recompiling everything).
Common traps
- “ABI stable means I can change anything.” No — it means clients do not need to recompile, but layout and symbol changes still break them.
- Assuming Swift packages need library evolution by default. They do not; source packages are recompiled, so resilient layout is optional overhead.
- Confusing module stability with ABI stability. Module stability is about the compiler interface file, not binary layout.
They might follow up with
- Which one does SwiftUI rely on? ABI stability plus module stability on Apple platforms, so apps built with older Xcode can run on newer OS versions.
- What does
-enable-library-evolutiondo? Turns on resilient layout and accessors, so the library can change without recompiling clients.
Related questions
- 1.10.5 What does @frozen on an enum mean for you as an API author?
- 1.10.6 You need to add a field to a public struct in a binary SPM library used by five apps. What do you consider?
- 1.3.8 How do you evolve a public protocol without breaking clients?
← Macros vs property wrappers vs result builders — one sentence each. What does @frozen on an enum mean for you as an API author? →