I remember the the day I first learned about the internal access modifier when reading The Swift Programming Language.
At the time, I was coding a take-home test for a job at Revolut. I was desperate to show how clever I was for knowing this keyword (which is synthesised by the compiler automatically). Subsequently, like a puppy marking its territory, I pissed internal on every (API) surface I saw, in the hope that Storonsky-senpai would notice me.
Later, I worked with a… well, a Staff Engineer but because we were in consulting she was called “Senior Manager”. She’d modularised our codebase - a novel concept for me at the time - and our ModelKit module was chock-full of properties marked:
public private(set) variableName: VariableType
As intimidated as I was, I swore that one day I would be intelligent enough wield access control keywords with the same finesse as she.
And one day, I was.
In order to protect the good people at Revolut from code snippets like the following abomination, I’m going to explain how to apply each access control level in Swift, and make you indistinguishable from the mighty Staff Engineer.

I do give Revolut big kudos for actually responding to my pathetic tech test with some helpful feedback, so you should apply for a job at Revolut if you need time away from your spouse. Revolut, please sponsor my Substack.
🗝️ Access control keywords 🗝️
Access control in Swift, like most languages, has a hierarchy:
Most restrictive
private
fileprivate
internal
public
open
Least restrictive
Quick aside for beginners: Why do we need access control?
Access control keywords like
publicandprivatedefine what other code is able to see the code you write.It’s important to be thoughtful about this, because your programs become a lot easier to understand when, for instance, a given part of your code is only allowed to use a small number of functions and see a small number of variables.
Just think how complicated things would become if every part of your code could talk to every other part of your code!
🔒 Don't Peek at My Privates 🔒
The private keyword is the exclusive VIP club - invisible to anything outside the scope of the entity in which it’s defined (by entity I mean any struct, enum, actor, or class).
If you’re new to Swift, when in doubt, go private! The Swift compiler will correct you if anything outside your entity needs access.
🖤 fileprivate: The Black Sheep 🖤
The fileprivate keyword is the ‘quirky’ cousin of private who only really gets invited to big family gatherings. It denotes visibility scoped in a file. There are more useful keywords out there, but hey, it's family.
📦 internal: Implicit but not forgotten 📦
The internal keyword is pretty vanilla - but trust me, we’re getting to the good part! The Swift compiler synthesises this ‘implicitly’ for every entity, method, and property - that means it’s free!
In Kotlin, the public keyword is the one that’s synthesised implicitly, and internal needs to be explicitly denoted on a property, entity, or method. Oh, and they’re called visibility modifiers, which makes my “invisible to” metaphor work a lot better.
…then why does the internal keyword exist at all? 🤔
Read and find out!
🧩 One More Piece of the Puzzle 🧩
Quick history lesson.
Back in the Objective-C days, you didn’t just write a property for a class. You also had to write
get()andset()mini-methods explaining how to fetch and change the value.Now - I’ll blow your mind here - Swift does this too.
get()andset()methods are synthesised for all the properties of your entity, and these methods areinternalby default.If you want to enjoy yourself, this StackOverflow thread from 2014 contains a bunch of iOS 7 devs with their minds blown that Swift 1.0 was doing this automatically.


