Swift vs Kotlin: Modern Languages That Replaced Their Predecessors
Comparing Swift and Kotlin — null safety, async patterns, protocol vs interface design, ecosystem differences, and which one to learn based on where you want to work.
Swift replaced Objective-C. Kotlin replaced Java (for Android, at least). Both were designed to fix real pain points in older languages while maintaining full interoperability with the codebases they were replacing. The result is two languages that are surprisingly similar in philosophy, despite targeting completely different platforms.
The Parallel Origin Stories
Apple introduced Swift in 2014 because Objective-C, despite being powerful, was showing its age. The bracket syntax was polarizing, memory management (even with ARC) was tricky, and the type system couldn't prevent common crashes like null pointer dereferences. Swift was designed to be safe, fast, and expressive — and to make iOS development accessible to more people.
JetBrains introduced Kotlin in 2011 (stable in 2016) because Java was verbose, slow to evolve, and riddled with null pointer exceptions. Google made Kotlin a first-class Android language in 2017 and the preferred language in 2019. Kotlin kept full Java interop — you can call Java from Kotlin and vice versa — while eliminating most of Java's boilerplate.
Both languages were pragmatic, not academic. They looked at what developers actually struggled with and fixed those specific things.
Null Safety: Different Approaches, Same Goal
Null pointer exceptions are the single most common crash in both iOS and Android apps. Both Swift and Kotlin made eliminating them a core language feature, but they approached it differently.
Swift uses optionals. A type is eitherString (guaranteed non-null) or String? (might be nil). You unwrap optionals with if let, guard let, or the ? operator for chaining. Force unwrapping with ! exists but it's a deliberate "I know what I'm doing" escape hatch — and every Swift style guide tells you to avoid it.
Kotlin uses nullable types with a ? suffix — very similar syntax. String is non-null, String? is nullable. You use ?. for safe calls, ?: (the Elvis operator) for defaults, and !! for force unwrapping (same "I accept the risk" semantics as Swift's !).
In practice, the two approaches feel almost identical to use. Both languages push you toward handling the null case explicitly, and both make the common path (non-null) the default.
Syntax: Closer Than You'd Think
Put Swift and Kotlin code side by side and you'll notice striking similarities.
Both have:
- Type inference (
let/valfor constants,varfor variables) - String interpolation
- Trailing closures / lambda syntax
- Extension functions/methods
- Data classes / structs with auto-generated equality and hashing
- Sealed classes for restricted type hierarchies
- Pattern matching (
whenin Kotlin,switchin Swift) - First-class functions and higher-order functions
The differences are mostly cosmetic. Kotlin uses
fun for functions, Swift uses func. Kotlin has when, Swift has switch (but both support exhaustive matching). Swift has value types (structs) as a first-class concept alongside reference types (classes), while Kotlin is class-oriented with data class for value semantics.
Async Programming
Both languages added structured concurrency, but at different times and with different designs.
Kotlin has coroutines, which shipped as stable in 2018. They're library-based (kotlinx.coroutines) rather than built into the language grammar. You usesuspend functions, launch and async builders, and structured concurrency through CoroutineScope. The system is flexible and powerful — you can choose your dispatcher, control cancellation, and build complex concurrent pipelines. The mental model is "lightweight threads managed by the library."
Swift added async/await in Swift 5.5 (2021). It's built into the language itself. async functions, await calls, Task groups, and actors for safe mutable state. Swift's approach is more opinionated — actors are a language-level construct, not a library pattern. The compiler enforces data isolation between actors at compile time, similar to how Rust enforces memory safety.
Both work well. Kotlin's approach is more flexible; Swift's is more integrated with the compiler's safety guarantees.
Protocol-Oriented vs Interface-Oriented
Swift leans heavily on protocols (similar to interfaces, but with associated types, default implementations, and protocol extensions). "Protocol-oriented programming" became a defining paradigm of Swift after Apple's famous WWDC 2015 talk. The idea is to prefer composition over inheritance, define behavior through protocols, and use protocol extensions to provide shared implementations.
Kotlin uses interfaces with default methods, delegation (by keyword), and extension functions to achieve similar patterns. Kotlin Multiplatform also uses expect/actual declarations for platform-specific implementations.
Both approaches solve the same problem — avoiding deep inheritance hierarchies — with slightly different mechanics.
The Ecosystem Question
This is where the real decision lies. The language features are similar enough that the ecosystem and job market matter more than syntax preferences.
Choose Swift if:- You want to build iOS, macOS, watchOS, or tvOS apps
- You're interested in Apple's ecosystem (SwiftUI, Combine, Core Data)
- You want to work at companies that ship Apple products
- You want to build Android apps
- You're interested in backend development with Kotlin (Ktor, Spring Boot with Kotlin)
- You want cross-platform mobile with Kotlin Multiplatform (KMP)
- You want to work in the broader JVM ecosystem
Cross-Platform Potential
Both languages are expanding beyond their original platforms.
Kotlin Multiplatform (KMP) lets you share business logic between Android, iOS, desktop, and web. It's not a UI framework — you write platform-specific UI and share the data layer, networking, and business rules. It's gaining real traction, and Google officially supports it for Android. Swift on Server exists (Vapor framework) but hasn't achieved the same adoption. Swift's Linux support is solid but the server-side ecosystem is small compared to what Kotlin gets from the JVM. Swift is also being used in some cross-platform contexts, but it's primarily an Apple-ecosystem language.If cross-platform is important to you, Kotlin currently has the stronger story.
Which to Learn First
Be practical about this. If you own an iPhone and want to build apps for it, start with Swift. If you own an Android phone and want to build apps for it, start with Kotlin. If you don't have a platform preference, consider the job market in your area — check listings and see which has more demand.
The good news: learning one makes the other much easier. The concepts transfer directly. Null safety, closures/lambdas, protocol/interface-oriented design, structured concurrency — once you internalize these patterns in one language, you'll pick them up almost instantly in the other.
Both languages are available on CodeUp with interactive exercises that run in your browser. You can try both side by side and see which one feels more natural before committing to a deeper learning path.