Swift: The Platform — From a Secret Project to ABI Stability
Before we write a single line of Swift, let's understand where it came from, how the compiler turns our code into native machine instructions, and why ARC — not a garbage collector — manages our memory.
A secret project, 2010
Every language has an origin story, and Swift's begins quietly. In July 2010, a compiler engineer at Apple named Chris Lattner started sketching a new language in his spare time. He told almost no one. For the first year, much of the work happened in the evenings and on weekends, and even most of Apple didn't know it existed. That name matters, because Lattner was not a newcomer. While a graduate student at the University of Illinois around the turn of the millennium, he had created LLVM — a compiler infrastructure that would go on to power Clang, Rust, and a great deal of the modern toolchain. By 2010 he understood compilers as well as almost anyone alive. So when he set out to design a language, he was building on a foundation he had laid himself a decade earlier. The goal was ambitious. Apple's platforms ran on Objective-C, a language from the early 1980s that bolted Smalltalk-style messaging onto C. It was powerful and battle-tested, but it carried four decades of baggage: header files, manual memory rituals, square-bracket message syntax, and the ever-present danger of null pointers. Lattner wanted something safe, fast, and expressive — a language that felt modern but could still call into every existing Objective-C framework on day one. The little bird in Swift's logo hints at the ambition: light, quick, and meant to fly. But in 2010, it was still a secret.
The reveal — WWDC 2014
On 2 June 2014, Apple's Worldwide Developers Conference was rolling through the usual announcements when Craig Federighi put a single word on the screen: Swift. The room, expecting incremental news, was genuinely stunned. Apple had built an entire programming language in near-total secrecy and was shipping it to millions of developers. The pitch was memorable: Swift was "Objective-C without the C." It kept the rich Cocoa and Cocoa Touch frameworks but threw away the C inheritance that made Objective-C feel ancient. The demo that won the crowd was Playgrounds — type a line of code, see the result instantly in the margin, watch a graph draw itself as values changed. For a community used to compile-run-debug cycles, watching code come alive as you typed felt like magic. Swift 1.0 shipped that September alongside Xcode 6. It was, frankly, a moving target. The syntax churned from release to release — collection types changed, error handling was redesigned, and code written in one version often refused to compile in the next. Early adopters jokingly measured a project's age by how many migration assistants it had survived. But the direction was clear, and the momentum was real. Within a few years Swift would top "most loved language" surveys and become the default for new Apple development. Not bad for a project that started as one engineer's evening hobby.
Going open source, 2015
A language locked inside one company can only go so far. On 3 December 2015, Apple did something many thought it never would: it open-sourced Swift under the Apache 2.0 licence (with a runtime library exception), launched Swift.org, and put the entire compiler, standard library, and core libraries on GitHub.
Crucially, the release included Linux support. For the first time, Swift could run on servers and machines that had nothing to do with Apple. The Swift Package Manager arrived to handle dependencies, and a community formed around server-side frameworks like Vapor. Today Swift also targets Windows, WebAssembly, and even tiny embedded systems.
Open-sourcing brought something just as important as portability: a transparent design process. Changes to the language now flow through Swift Evolution, a public proposal system. Every feature gets a number — you'll see references like SE-0296 throughout this series — a written rationale, and an open review period where anyone can argue for or against it. When we discuss async/await or opaque types later, we're really discussing community-reviewed proposals, not decisions handed down from behind a curtain.
So Swift stopped being "Apple's language" and started becoming a language that Apple happens to lead.
How the compiler thinks
So what actually happens when we hit build? Our .swift files don't run directly — they are translated, in stages, all the way down to the native machine code our CPU understands. Let's trace that journey.
The first stages are familiar from any compiler: the parser turns text into an abstract syntax tree, and Sema (semantic analysis) type-checks it, resolving every var, every call, and every generic placeholder. If you've ever fought the type-checker, this is the stage you were fighting.
Then comes the part that sets Swift apart: SIL, the Swift Intermediate Language. Most compilers hand off to LLVM right after type-checking, but Swift inserts its own high-level intermediate representation in between. SIL is where Swift proves that every variable is initialised before use (definite initialisation), enforces exclusive access to memory, and performs Swift-specific optimisations like eliminating unnecessary retain and release calls. Only after SIL has done its work does the code descend into LLVM IR and, finally, the native instructions for your particular chip.
That extra layer is why Swift can give such precise diagnostics and still produce fast binaries. The language understands itself before it ever speaks to LLVM.
Native code and the ABI stability story
Here's a question worth pausing on: where does Swift run? Unlike Java or Dart, there is no virtual machine sitting underneath your app in production. Swift is compiled ahead of time into native machine code that the CPU executes directly. There is a runtime — a library that handles reference counting, type metadata, and dynamic casts — but it is a support library, not an interpreter. For Swift's first five years, that runtime was a headache. Because the language was still changing, every app had to bundle its own copy of the Swift libraries inside the app package — several megabytes per app — so it wouldn't break when the OS updated. This is the "ABI" problem: the Application Binary Interface, the low-level contract for how compiled code lays out data and calls functions, wasn't yet stable. That changed with Swift 5 in March 2019, which delivered ABI stability. The Swift runtime became part of the operating system itself — iOS, macOS, and the rest now ship with Swift built in. Apps no longer bundle their own copy; they link against the one in the OS, so they got smaller and launched faster. Module stability followed, letting pre-compiled libraries work across compiler versions. Swift had finally grown up: a binary compiled today will keep working with the system libraries of tomorrow.
Memory: ARC, not a garbage collector
Most modern languages manage memory with a tracing garbage collector — a background process that periodically scans for objects nobody is using and frees them. Swift takes a different path: Automatic Reference Counting, or ARC.
The idea is simple. Every class instance carries a count of how many references point to it. When you assign it somewhere, the count goes up; when a reference goes away, the count goes down. The instant the count hits zero, the object is deallocated and its deinit runs. The twist is in the word automatic: you don't write these increments by hand. The compiler inserts the retain and release calls for you, at compile time, in exactly the right places.
ARC has real advantages. Deallocation is deterministic: an object dies the moment its last reference disappears, not whenever a collector next decides to run. There are no garbage-collection pauses, which matters enormously for smooth scrolling and animation. The cost is paid elsewhere — in the traffic of retain and release calls, and in one notorious failure mode: if two objects hold strong references to each other, their counts never reach zero and they leak. Breaking those reference cycles with weak and unowned is a skill we'll develop in the value-types and closures episodes.
This model isn't new to Swift, by the way. Objective-C gained ARC back in 2011, automating what programmers had previously done by hand with explicit retain and release messages. Swift simply inherited a proven idea and made it the default.
The shape of Swift today
We've travelled from a secret 2010 project to a native-compiled, ABI-stable language with its own intermediate representation and deterministic memory management. Let's place the milestones on a single line, because the rest of this series sits on top of them.
Each of those landmarks is a chapter waiting for us. The 2016 "grand renaming" of Swift 3 cleaned up the API guidelines and caused one last great migration. The 2019 ABI work we just saw made Swift dependable. In 2021, Swift 5.5 introduced async/await and actors — we'll devote a whole episode to them. And in 2024, Swift 6 turned on compile-time data-race safety, making whole categories of concurrency bug impossible.
Swift now runs far beyond the iPhone: on servers, on Linux and Windows, in the browser through WebAssembly, and on microcontrollers through embedded Swift. From here, the series builds upward — optionals and the type system, structs versus classes and value semantics, strings and Unicode, collections, protocols, and finally concurrency. Every one of those features rests on the foundation we've just laid: native code, SIL, and ARC. Alright then — let's start writing some Swift.
Swift: The Platform Quiz
7 questions
Test your understanding of Swift's history, its compiler pipeline, and how it manages memory.