# Meet An Upcoming Swift Access Modifier: package

Coming in Swift 5.9, `package` will be a new access modifier in the language.

The Swift team at Apple approved the Swift Evaluation proposal [SE-0386](https://github.com/apple/swift-evolution/blob/main/proposals/0386-package-access-modifier.md) which includes adding a new access modifier called `package` to allow symbols from being accessed inside the same package only.

Currently, there's only one way to access symbols throughout packages of a project and, it's by declaring them as `public`. However, sometimes you don't want a specific symbol to be accessed from a different module but only inside the same package. Right now, there's no way to make that restriction.

Fortunately, Swift Evaluation proposal [SE-0386](https://github.com/apple/swift-evolution/blob/main/proposals/0386-package-access-modifier.md) adds the exact restriction to the language by adding a new access modifier `package`. All you have to do is to declare the symbols as `package`.

Suppose we have two modules and packages called `Cat` and `Dog`. If we declare a `public` struct called `AnimalBehaviour` inside the `Cat` package, all of its symbols will be accessible in the `Dog` package, as well as in the others throughout the project:

```swift
// Module: Cat, Package: Cat
public struct AnimalBehaviour {
    public func run() {}
    public func actNaughty() {}
}

public struct Cat {
    public let behaviour: AnimalBehaviour
}

let cat = Cat(behaviour: AnimalBehaviour())
cat.behaviour.run() // ✅ Accessible
cat.behaviour.actNaughty() // ✅ Accessible

// Module: Dog, Package: Dog
public struct Dog {
    public let behaviour: AnimalBehaviour
}

let dog = Dog(behaviour: AnimalBehaviour())
dog.behaviour.run() // ✅ Accessible
dog.behaviour.actNaughty() // ✅ Accessible
```

However, we want the `actNaughty()` to be accessible inside the module only that we declared `AnimalBehaviour` in, which is `Cat`. We simply declare the method as `package`:

```swift
// Module: Cat, Package: Cat
public struct AnimalBehaviour {
    public func run() {}
    package func actNaughty() {}
}
```

Now, It's possible to access `actNaughty()` inside the `Car` module:

```swift
let cat = Cat(behaviour: AnimalBehaviour())
cat.behaviour.run() // ✅ Accessible
cat.behaviour.actNaughty() // ✅ Accessible
```

However, for the `Dog` module, the compiler will not be able to find the intended symbol:

```swift
let dog = Dog(behaviour: AnimalBehaviour())
dog.behaviour.run() // ✅ Accessible
dog.behaviour.actNaughty() // ❌ Not accessible. Error: cannot find 'actNaughty()' in scope
```

Hopefully, this new access modifier helps large projects to be structured better.

Overall, this access modifier is pretty much similar to internal, except it has been made for Packages which are expressed by Swift Package Manager to prevent undesirable symbols by only allowing them to be shared within the same package.

It's also worth mentioning that `package` is more accessible than `internal`, `fileprivate`, and `private`. And less accessible than `open` and `public`. For example, a `public` function cannot use a `package` type in its parameters or return type, and a `package` function cannot use an `internal` type in its parameters or return type. Similarly, an `@inlinable` `public` function cannot use a `package` declaration in its implementation, and an `@inlinable` `package` function cannot use an `internal` declaration in its implementation.

Swift 5.9 was announced on March 6th of 2023. The release date hasn't been revealed yet, but it's expected to be released with the launch of iOS 17.
