Software Design

Library vs. framework: “Who calls whom?” (Inversion of Control)

We call Alamofire a library and SwiftUI a framework. But aren’t both just “using code written by someone else”? What’s the difference?

4 min read
Cover image for Library vs. framework: “Who calls whom?” (Inversion of Control)

We call Alamofire a library and SwiftUI a framework. But aren’t both just “using code written by someone else”? What’s the difference?

You often hear that “a framework is larger,” but size isn’t the essence. There are small frameworks and huge libraries.

Who calls whom?

Once you establish this one criterion, it naturally leads to the important concept of Inversion of Control (IoC). You’ll encounter it again when studying dependency injection, so understanding it properly here pays off.

Here’s the key summary.

  1. Library: a collection of tools my code calls when needed. I retain control.
  2. Framework: a skeleton that owns the flow and calls my code. The framework retains control.
  3. This reversed call direction is called Inversion of Control.
  4. Hollywood Principle: “Don’t call us, we’ll call you.”

Library: the tool I call

A library is a bundle of code that implements specific functionality in advance. My code determines entirely when and in what order to use it.

// My code owns the flow
let json = try JSONDecoder().decode(User.self, from: data)
let hash = SHA256.hash(data: input)

I design the program’s beginning, end, and overall flow, then take out the tools I need along the way. It’s like taking a screwdriver from a toolbox. The screwdriver doesn’t decide the order of the work.

Alamofire and Kingfisher fall into this category. I decide when to send network requests and when to load images.


Framework: the skeleton that calls me

A framework is a skeleton with the application’s overall structure and execution flow already defined. I fill in the places it leaves open.

iOS apps make this clear. UIKit and SwiftUI control the app’s entry point, event loop, and screen lifecycle. What I write—such as viewDidLoad, body, and onAppear—is code the framework calls at defined points.

struct ProfileView: View {
    var body: some View {   // I don’t call it.
        Text("Hello")       // SwiftUIIt calls it when needed
    }
}

I never call body manually. SwiftUI decides when and how many times it is called. The owner of the flow has changed.

The call direction is reversed. That’s Inversion of Control.
The call direction is reversed. That’s Inversion of Control.

Inversion of Control and the Hollywood Principle

This reversed relationship has a name: Inversion of Control (IoC).

In a typical procedural program, my code controls the flow and calls external code. In a framework-based program, the framework controls the flow, and my code is called at the points where it was registered. Control has moved in the opposite direction, hence “inversion.”

The witty expression for this is the Hollywood Principle.

“Don’t call us, we’ll call you.” — Don’t call us; we’ll contact you.

An actor who auditions doesn’t keep calling the production company. Once cast, the production company contacts them. That is exactly the relationship between a framework and my code.

The delegate pattern follows the same principle. When implementing UITableViewDataSource, do I call cellForRowAt? No. The table view calls me when it needs it. The syntax of the framework world permeates code everywhere.


So what changes in practice?

The learning approach differs. With a library, you look for “what functionality does it provide?” With a framework, you first learn “when does it call me?”—the lifecycle and calling conventions. That’s why learning UIKit starts with the lifecycle.

The replacement cost differs. You can switch libraries by changing the call sites, but an entire codebase built on a framework’s skeleton makes replacement effectively a rewrite. That’s why moving from UIKit to SwiftUI isn’t just changing a few functions.

The testing strategy differs. Code called by a framework is difficult to run independently of that framework. That’s why you repeatedly hear the advice to separate logic into framework-independent layers—pure Swift.

Don’t call us, we’ll call you — the Hollywood Principle
Don’t call us, we’ll call you — the Hollywood Principle

In one sentence for interviews

“A library is a tool called by my code, while a framework is a skeleton that controls the flow and calls my code. This difference in the direction of control is called Inversion of Control.”

Follow-up questions usually proceed with “Give an example of IoC” (lifecycle methods, delegates), followed by “Why is it useful?” (it standardizes the flow so developers can focus on business logic).


Summary

  • The criterion is call direction, not size.
  • Library: a tool my code calls when needed. I retain control.
  • Framework: a skeleton that controls the flow and calls my code at defined points. The framework retains control.
  • This reversed control is Inversion of Control (IoC), also known as the Hollywood Principle.
  • viewDidLoad, body, and delegate methods are all code that gets called.
  • Practical differences: learn the framework lifecycle first, replacement is difficult, and separating logic becomes essential for testing.