What is ABI stability vs source compatibility vs module stability?

1.10.4 · L5 · Interview

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-evolution do? 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? →