Skip to content
Swift logo

Swift

First appeared 2014 · Chris Lattner

Apple's modern systems-and-apps language — safe by default, fast, and increasingly cross-platform.

Overview

Swift is a powerful, intuitive, modern, and safe general-purpose programming language developed by Apple for building applications across its entire ecosystem including iOS, macOS, watchOS, tvOS, and beyond. Introduced at Apple's Worldwide Developers Conference (WWDC) in June 2014, Swift was designed from the ground up to be fast, safe, and expressive, offering modern language features and programming paradigms while maintaining performance characteristics comparable to C and C++. Swift combines the best aspects of modern language thinking with wisdom from Apple's engineering culture and the diverse contributions from its open-source community. The language features automatic memory management through Automatic Reference Counting (ARC) that deterministically manages memory without the unpredictability of garbage collection, strong static typing with sophisticated type inference that catches errors at compile time while keeping code concise, optionals as a first-class language feature that makes handling null values explicit and safe, and a clean, expressive syntax that's easy to read and write, making code more maintainable and reducing bugs. Swift supports both object-oriented and functional programming paradigms, providing developers with multiple approaches to solving problems. The language includes powerful features like generics for writing flexible and reusable code, closures with clean syntax for functional programming patterns, protocol-oriented programming that emphasizes composition over inheritance, value types (structs and enums) as first-class citizens alongside classes, pattern matching for expressive control flow, powerful error handling through typed errors and do-catch blocks, and extensions that allow adding functionality to existing types. Swift's type system is remarkably sophisticated, with features like associated types, type constraints, conditional conformance, and opaque return types that enable powerful abstractions while maintaining type safety. The language provides excellent performance through aggressive compiler optimizations, whole-module optimization, and the ability to drop down to unsafe operations when necessary for maximum performance. Swift includes modern concurrency features with async/await syntax, actors for safe concurrent programming, and structured concurrency that makes asynchronous code easier to write and reason about. The language comes with a comprehensive standard library covering collections, strings, numbers, and fundamental algorithms, plus access to all of Apple's frameworks for building sophisticated applications. Swift has expanded beyond Apple platforms with Swift on Linux, Windows support, and initiatives for server-side development with frameworks like Vapor and Kitura. The language has excellent tooling including Xcode with integrated debugging and profiling, Swift Playgrounds for interactive learning and prototyping, SwiftUI for declarative user interface development, and Swift Package Manager for dependency management. Swift's design emphasizes safety without sacrificing performance, making it suitable for everything from system programming to high-level application development. The language has been adopted rapidly across Apple's ecosystem and has become the preferred language for iOS and macOS development, with Apple actively encouraging developers to adopt Swift over Objective-C.

Key facts

The reference details, without the paragraph.

First appeared
2014
Designed by
Chris Lattner and the Swift team at Apple
Typing
Static, strong, with optionals for nullability and powerful protocol-based generics
Execution
Compiled ahead of time to native machine code via LLVM
Memory model
Automatic Reference Counting (ARC) — deterministic, no garbage collector, no stop-the-world pauses
Package manager
Swift Package Manager, built into the toolchain
File extensions
.swift
Current version
Swift 6, with strict compile-time data-race checking
Platforms
Apple platforms, Linux and Windows; server-side and embedded targets are supported
Licence
Apache 2.0 with a Runtime Library Exception

History

How the language got here — the decisions that still shape how you write it.

Swift was developed by Apple and first announced by Craig Federighi at the Worldwide Developers Conference (WWDC) on June 2, 2014, with version 1.0 released alongside iOS 8 and Xcode 6 in September 2014. The project was initiated in 2010 by Chris Lattner, who had previously created LLVM (Low Level Virtual Machine) and the Clang compiler while at Apple. Lattner began working on Swift as a personal project, initially without official approval, driven by his vision of creating a modern programming language that could eventually replace Objective-C for Apple platform development. Objective-C, which had been the primary language for Apple development since the NeXT days in the 1980s, was showing its age despite being a capable language. Its syntax, inherited from Smalltalk and C, was verbose and unfamiliar to many developers, and its dynamic nature made certain classes of errors difficult to catch at compile time. Apple recognized the need for a more modern, safer, and more approachable language that could attract new developers while providing better tools for building robust applications. As Swift development progressed, it became an official Apple project with a dedicated team of engineers. The language drew inspiration from many sources: Objective-C for its message-passing semantics and dynamic features, Rust for its approach to memory safety, Haskell for its type system and functional programming features, Python for its readability, C# for its modern syntax, and many others. Swift was designed to be familiar to developers coming from other languages while introducing innovative features that would make programming safer and more productive. The announcement of Swift at WWDC 2014 was met with tremendous excitement from the developer community, though the initial versions were rough around the edges with frequent breaking changes as the language evolved rapidly. Swift 1.0 through 1.2 saw significant changes and improvements, sometimes requiring substantial code updates between versions. Swift 2.0, announced at WWDC 2015, brought major improvements including error handling with do-catch, protocol extensions that enabled protocol-oriented programming, guard statements for early exits, and availability checking. Most significantly, at WWDC 2015, Apple announced that Swift would be open-sourced, a historic move for a company known for keeping its technologies proprietary. On December 3, 2015, Swift was released as open-source under the Apache 2.0 license, with the source code, compiler, standard library, and package manager all made available on GitHub. This open-sourcing included the formation of Swift.org as the home for the open-source project, with a clear governance model and community participation. The open-source release included support for Linux, marking Swift's expansion beyond Apple platforms. Swift 3.0, released in September 2016, was a major milestone that focused on stabilizing the language and establishing source compatibility going forward. This version included significant API changes to make the language more consistent and Swifty, though it required substantial code migration. Swift 4.0 and 4.1 continued refining the language while maintaining source compatibility, adding features like Codable for easy serialization, improved strings, and exclusive access to memory. Swift 4.2 introduced new features and began the transition to ABI (Application Binary Interface) stability. Swift 5.0, released in March 2019, achieved ABI stability, a crucial milestone that meant Swift libraries could be included in the operating system and apps wouldn't need to bundle the Swift runtime, reducing app sizes and improving launch times. This version also introduced Result types, raw strings, and other improvements. Swift 5.1 brought opaque return types and property wrappers, enabling the development of SwiftUI, Apple's declarative UI framework announced at WWDC 2019. SwiftUI represented a paradigm shift in how developers build user interfaces for Apple platforms, leveraging Swift's language features to create a reactive, declarative framework. Swift 5.5, released in 2021, introduced async/await and actors, bringing modern concurrency features to the language and making asynchronous programming significantly easier and safer. This was one of the most significant additions to Swift since its inception, addressing a long-standing challenge in concurrent programming. Subsequent versions have continued adding features like distributed actors, regex literals, and ongoing improvements to the type system and performance. Throughout its evolution, Swift has been adopted rapidly across Apple's ecosystem. Major apps from companies like LinkedIn, Lyft, Kickstarter, and countless others have been built with or migrated to Swift. Apple itself has been rewriting significant portions of its own applications in Swift. The language has also found success in education, with Apple promoting Swift as an ideal first programming language through initiatives like Swift Playgrounds, an iPad app that teaches programming through interactive puzzles and games. Swift has expanded into server-side development with frameworks like Vapor and Kitura, though adoption in this space has been more modest compared to its dominance in Apple platform development. The language has also been used for machine learning with Swift for TensorFlow (though this project has since been archived), and there have been efforts to use Swift for systems programming. Chris Lattner left Apple in 2017 but Swift's development has continued under the leadership of Ted Kremenek and the Swift core team, with contributions from Apple engineers and the broader open-source community. The language continues to evolve with regular releases, guided by the Swift Evolution process where proposals are discussed publicly and decided through community input and core team review. Swift represents Apple's long-term vision for software development across its platforms, and the company has made it clear that Swift is the future while Objective-C remains supported for legacy code. The language's combination of safety, performance, modern features, and excellent tooling has made it one of the most loved programming languages, consistently ranking high in developer satisfaction surveys. Swift's success demonstrates that it's possible to create a modern, safe language that doesn't sacrifice performance, and its influence can be seen in other language designs and the broader programming language community.

  1. 2010

    A secret project

    Chris Lattner, the creator of LLVM, begins designing a replacement for Objective-C — one that keeps the Cocoa frameworks but drops the C inheritance and manual memory management.

  2. 2014

    Announced at WWDC

    Swift is revealed with optionals, type inference, generics and closures. Objective-C developers have to learn a genuinely different language, and adoption is nonetheless rapid.

  3. 2015

    Open-sourced, and Linux support

    Swift 2.2 is released under Apache 2.0 with a public evolution process. The language stops being Apple-only, at least in principle.

  4. 2019

    SwiftUI and ABI stability

    Swift 5 stabilises the ABI, so apps no longer bundle the runtime. SwiftUI arrives as a declarative UI framework and property wrappers land alongside it.

  5. 2021

    Structured concurrency

    Swift 5.5 adds `async`/`await`, actors and task groups — concurrency with compile-time protection against data races, integrated into the language rather than a library.

  6. 2023

    Macros and C++ interoperability

    Swift 5.9 adds a macro system and direct, bidirectional C++ interop, widening its reach into existing native codebases.

  7. 2024

    Swift 6

    Strict concurrency checking becomes the default in the Swift 6 language mode: data races that were runtime bugs are now compile-time errors. Embedded Swift also arrives for constrained devices.

What it is good at

The reasons teams pick it, stated concretely.

  • Optionals make absence explicit

    `String` and `String?` are distinct types, and you cannot use the optional without unwrapping it. Objective-C's silent nil-messaging behaviour is gone, and with it a large class of subtle bugs.

  • Fast, with predictable memory behaviour

    Compiled through LLVM to native code, with value types stack-allocated and ARC releasing objects deterministically. No garbage-collection pauses, which matters for smooth sixty-frames-per-second interfaces.

  • Value semantics by default

    Structs, enums and collections are copied on assignment (with copy-on-write for efficiency), so passing data around does not create hidden shared mutable state. This is a genuinely good default that most languages do not offer.

  • Protocol-oriented design

    Protocols with default implementations and associated types let you compose behaviour without deep inheritance hierarchies. Generic code stays fully typed rather than falling back on casts.

  • Concurrency the compiler verifies

    Actors isolate mutable state, `Sendable` marks what is safe to cross boundaries, and in Swift 6 the compiler rejects code that could race. Very few languages check this statically.

Trade-offs

Every language costs you something. Knowing what, before you commit, is the whole point.

  • The Apple ecosystem dominates

    Linux and Windows support is real and improving, but the libraries, documentation, tooling and jobs are overwhelmingly Apple-platform. Server-side Swift is a small community next to Node, Go or Java.

  • Compile times on large projects

    Type inference across complex expressions can be slow, and SwiftUI view bodies are notorious for occasionally producing 'the compiler is unable to type-check this expression in reasonable time'. Breaking expressions up and adding annotations helps.

  • Xcode is the practical requirement

    Building for Apple platforms means macOS and Xcode. Alternative editors work with the language server, but simulators, provisioning and App Store submission do not.

  • ARC needs your attention on cycles

    Reference counting cannot collect cycles, so two objects referring to each other leak. `weak` and `unowned` fix it, but you have to notice — closures capturing `self` are the common case.

  • A fast-moving language

    Concurrency, macros, ownership and strict data-race checking have all arrived recently. The pace is a strength for capability and a cost for reading older code and tutorials.

Code examples

Not syntax tours — the idioms that make code read like the language rather than a translation of another one.

Optionals, unwrapped safely
struct User {
    let name: String
    let email: String?
}

func contactLine(for user: User?) -> String {
    // guard-let exits early and unwraps for the rest of the function.
    guard let user else { return "no user" }

    // if-let handles the optional field.
    if let email = user.email, email.contains("@") {
        return "\(user.name) <\(email)>"
    }

    // Nil-coalescing supplies a default.
    return user.name.isEmpty ? "anonymous" : user.name
}
`guard let` is the idiomatic way to handle the failure case first and keep the happy path unindented. Force unwrapping with `!` compiles but crashes on nil — reserve it for values you can prove are present, and prefer `guard` almost everywhere.
Value types and copy-on-write
struct Inventory {
    private(set) var items: [String] = []

    mutating func add(_ item: String) {
        items.append(item)
    }
}

var warehouse = Inventory()
warehouse.add("hammer")

var backup = warehouse       // a copy, not a reference
backup.add("saw")

print(warehouse.items.count) // 1 — unaffected
print(backup.items.count)    // 2
Structs are copied on assignment, so `backup` cannot mutate `warehouse` by accident. The underlying array storage is shared until one side writes, so the copy costs nothing until it has to — this is copy-on-write, and it is why value semantics are practical rather than wasteful.
Enums with associated values, matched exhaustively
enum LoadState<Value> {
    case idle
    case loading
    case loaded(Value)
    case failed(Error)
}

func describe(_ state: LoadState<[String]>) -> String {
    switch state {
    case .idle:              return "Not started"
    case .loading:           return "Loading…"
    case .loaded(let items): return "\(items.count) items"
    case .failed(let error): return "Failed: \(error.localizedDescription)"
    }
}
The associated value is only accessible in the branch where it exists, so there is no way to read `items` from a failed state. `switch` must be exhaustive, so adding a fifth case turns every incomplete switch into a compile error.
Actors and structured concurrency
actor ImageCache {
    private var storage: [URL: Data] = [:]

    func image(for url: URL) async throws -> Data {
        if let cached = storage[url] { return cached }
        let (data, _) = try await URLSession.shared.data(from: url)
        storage[url] = data          // isolated — no lock needed
        return data
    }
}

// Run independent work concurrently and collect the results.
let images = try await withThrowingTaskGroup(of: Data.self) { group in
    for url in urls { group.addTask { try await cache.image(for: url) } }
    return try await group.reduce(into: []) { $0.append($1) }
}
An `actor` serialises access to its own mutable state, so `storage` cannot be corrupted by concurrent callers and needs no mutex. Under Swift 6's strict checking, passing non-`Sendable` data across that boundary is a compile error rather than an intermittent production bug.

Common pitfalls

The mistakes that cost everyone an afternoon at least once.

  • Force unwrapping with `!`

    It crashes the app when the value is nil. Use `guard let`, `if let` or `??`. Reserve `!` for genuine invariants — and even then, `guard` with a clear message is usually better.

  • Retain cycles in closures

    A closure that captures `self` strongly, stored on `self`, leaks both forever. Use `[weak self]` in escaping closures and unwrap it at the top of the block.

  • Confusing structs and classes

    Structs copy, classes share. Choosing a class for a model type and then wondering why an edit in one screen changed another is a classic. Default to `struct` and reach for `class` when you need identity or inheritance.

  • Updating the UI off the main thread

    It produces intermittent glitches and crashes. Mark UI code `@MainActor` and let the compiler enforce it rather than remembering to dispatch manually.

  • Overusing `@Published` and observation

    Every change publishes and re-renders. Making a large model observable wholesale causes unnecessary view updates; keep observable state granular.

  • Giant SwiftUI view bodies

    Type inference across a deeply nested body is what produces the 'unable to type-check in reasonable time' error. Extract subviews — it fixes the compile time and reads better.

In production

Where it is running at scale, and what it is doing there.

  • Apple

    iOS, macOS, watchOS, and tvOS app development.

  • Uber

    iOS mobile applications and internal tools.

  • LinkedIn

    iOS mobile app development.

  • Airbnb

    iOS mobile applications for hosts and guests.

Learning path

A realistic order to learn things in, with something to build at each step.

  1. 1

    Weeks 1–2

    Language fundamentals

    Constants and variables, optionals, functions, closures, structs versus classes, enums with associated values, and protocols. Use a Playground or `swift repl` for instant feedback.

    Build this: Model a small domain — a task list or a recipe book — using structs, enums and protocols.

  2. 2

    Weeks 3–4

    The type system in earnest

    Generics, protocol extensions, `Result`, error handling with `throws`, and value versus reference semantics. Protocol-oriented design is what makes Swift feel different from Java or C#.

    Build this: Write a generic caching layer that works for any `Codable` type.

  3. 3

    Weeks 5–8

    Building an app

    SwiftUI for the interface, state management with `@State` and `@Observable`, navigation, lists, and `Codable` for talking to an API. UIKit is still worth knowing for existing codebases.

    Build this: Build an app that loads data from a public API and displays it with loading and error states.

  4. 4

    Months 3–4

    Concurrency and persistence

    `async`/`await`, tasks and task groups, actors, `Sendable`, plus SwiftData or Core Data for local storage, and XCTest or Swift Testing.

    Build this: Add offline caching and concurrent image loading, with tests covering the failure paths.

  5. 5

    Ongoing

    Beyond the app

    Performance with Instruments, memory graph debugging for retain cycles, macros, interoperability with C and C++, and server-side Swift with Vapor if that interests you.

    Build this: Profile your app with Instruments and fix a retain cycle you find in the memory graph.

Ecosystem and tooling

The tools you will end up installing whichever project you join.

ToolWhat it does
XcodeThe IDE, simulators, Instruments profiler and the path to the App Store
Swift Package ManagerBuilt-in dependency management and build system; increasingly the default over CocoaPods
SwiftUIDeclarative UI across iOS, macOS, watchOS, tvOS and visionOS
UIKit / AppKitThe imperative UI frameworks — still essential for existing apps and fine-grained control
Swift Concurrency`async`/`await`, actors and task groups, with compile-time data-race checking in Swift 6
SwiftData / Core DataLocal persistence; SwiftData is the modern declarative layer over the same engine
VaporThe leading server-side Swift framework, for HTTP APIs on Linux
InstrumentsProfiling for CPU, allocations, leaks and rendering performance

Swift libraries

19 catalogued, each with installation, worked examples and best practices.

Frequently asked

Do I need a Mac to write Swift?

To build iOS or macOS apps, yes — Xcode is macOS-only and App Store submission requires it. For the language itself, and for server-side or command-line Swift, official toolchains exist for Linux and Windows.

SwiftUI or UIKit?

SwiftUI for new projects: less code, live previews, and it is where Apple's investment goes. UIKit remains necessary for existing apps, for support of older OS versions, and for cases where you need control SwiftUI does not yet expose. The two interoperate, so mixing them is normal.

Is Swift only useful for Apple platforms?

In practice, mostly. Linux server support is genuine, Vapor is a capable framework, and Embedded Swift targets constrained devices — but the ecosystem, hiring and documentation are heavily Apple-centred. Choose Swift for the server if the team already writes it, not on general merit.

What is ARC and do I need to think about it?

Automatic Reference Counting inserts retain and release calls at compile time, so memory is freed deterministically with no garbage collector. You mostly do not think about it — except for reference cycles, which it cannot collect. That is what `weak` and `unowned` are for.

Swift or Kotlin for mobile?

It is not really a choice: Swift for iOS, Kotlin for Android. They are strikingly similar languages — optionals and nullable types, structured concurrency, value types, protocol and interface extensions — so learning the second is much faster than the first. For sharing code between them, Kotlin Multiplatform is currently the most established option.

How significant is Swift 6's strict concurrency?

Very. It turns data races into compile errors, which almost no mainstream language does. Migrating an existing codebase into Swift 6 mode takes real work — you will annotate `Sendable` conformances and isolate mutable state — but it eliminates a category of bug that is otherwise nearly impossible to reproduce.