# realm-swift: a mobile database now maintained outside MongoDB

> The Swift SDK is still shipping, still on a community branch, and still carries MongoDB branding in its README. Its own release notes say the prebuilt binaries are no longer code signed because the project is no longer officially distributed by MongoDB. Both things are true at once.

**realm/realm-swift** — Realm is a mobile database: a replacement for Core Data & SQLite

- Repository: https://github.com/realm/realm-swift
- Website: https://realm.io
- Stars: 16,602 · Forks: 2,235
- Language: Objective-C
- License: Apache-2.0
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/realm-realm-swift

## What the data model looks like in code

The argument for an object-oriented local database is made in one short block. A model is a class inheriting from `Object`, its stored properties are marked with `@Persisted`, and relationships are typed object fields:

```swift
class Dog: Object {
    @Persisted var name: String
    @Persisted var age: Int
}
```

That is the whole modelling surface for a property. Primary keys are a property attribute rather than a separate schema, `@Persisted(primaryKey: true)`, and a to-many relationship is a `List<Dog>`. You assign and read fields with ordinary Swift syntax, and persistence is a write transaction:

```swift
let realm = try! Realm()
try! realm.write {
       realm.add(dog)
}
```

The README frames this as an ergonomic claim rather than a performance one: an object-oriented data model that is simple to learn, needs no ORM, and lets you write less code. The `try!` in the samples is worth pausing on, because it is not the pattern to copy into production. Every `try!` in the README is an example of shape, not of error handling, and `Realm()` can throw.

The `@Persisted` property wrapper is the load-bearing detail. It is what lets a plain Swift class property become a stored column without a separate entity class, without a managed object subclass, and without a fetch request to materialise it first. Compare that with Core Data, where the entity description lives in a model file, the class needs a generated or hand-written accessor for each attribute, and a context is required before anything can be saved.

## Live objects and how writes propagate

The second design decision is that objects stay live. When you hold a reference to a managed object, a write anywhere in the process updates what that reference reports, with no refetch and no notification plumbing on your side. The README demonstrates it by observing an object and then changing one of its properties:

```swift
token = dog.observe { change in
    switch change {
    case .change(let properties):
        for property in properties {
            print("Property '\(property.name)' changed to '\(property.newValue!)'");
        }
    case .error(let error):
        print("An error occurred: (error)")
    case .deleted:
        print("The object was deleted.")
    }
}
```

Three cases matter. `.change` carries the list of properties that changed along with their new values, which is enough to update a single label without redrawing a screen. `.error` is how an observer learns its observation was invalidated rather than silently receiving nothing. `.deleted` fires when the object is removed, so a view holding a stale reference finds out instead of reading a tombstone.

The token that comes back from `observe` has to be retained for the observation to stay alive, which is why the sample declares `var token: NotificationToken?` before assigning it. Dropping the token stops the observation.

On the SwiftUI side the same idea is exposed as a property wrapper, `@ObservedResults(Person.self)`, which gives a view a live, ordered collection and hands it `move`, `remove` and `append` as bound methods:

```swift
struct ContactsView: View {
    @ObservedResults(Person.self) var persons
```

The `@ObservedResults` collection is not a snapshot. When the underlying query results change, the view's `ForEach` re-runs, and `.onMove` and `.onDelete` write straight through to the database. That is the part of the design that removes the most code relative to a fetch-request model, and it is also the part that shapes your UI code, because writes become mutations of a collection rather than calls you make explicitly.

## Encryption is a 64-byte key on the configuration

Encryption is not a separate product feature you opt into later. It is a 64-byte key handed to the configuration before the database opens:

```swift
let config = Realm.Configuration(encryptionKey: key)
let realm = try Realm(configuration: config)
let dogs = realm.objects(Dog.self).filter("name contains 'Fido'")
```

The key itself has to be random, and the README generates it with `Data(count: 64)` filled by `SecRandomCopyBytes(kSecRandomDefault, 64, baseAddress)`. The fixed length is the part worth remembering: a 64-byte key is what the local file format expects, and it is not a passphrase you can derive from a password. Storing it is your problem, and losing it means losing the file, since nothing can decrypt the contents without it.

The README describes the effect in terms rather than mechanics: data can be encrypted in-flight and at-rest, keeping sensitive data protected. In practice the on-disk file is encrypted, so an extracted `.realm` file is not readable on its own.

The query syntax in that same line is also worth a look, because it is the API you will use constantly. `realm.objects(Dog.self)` returns a live typed collection, and `.filter("name contains 'Fido'")` passes a query string. Those results are live too, so a change made anywhere appears in an existing collection reference. The cost is that you are building a query language string rather than composing a typed predicate, which means query syntax errors surface as thrown errors at evaluation time.

## Four installation routes and a build-from-source path

Installation is a single sentence in the README: Swift Package Manager, CocoaPods, Carthage, or importing a dynamic XCFramework. The detail is delegated to `docs/guides/quick-start.md`, which is the document to read before you decide.

The repository supports that claim structurally. There is a `Package.swift` for SPM, `Realm.podspec` and `RealmSwift.podspec` for CocoaPods, a `Carthage/` directory, and `Configuration/` for build settings. The Objective-C and Swift layers are separate directories and separate products, `Realm/` and `RealmSwift/`, with `Realm.xcodeproj/` at the root and a `plugin/` directory for build tooling.

Building from source is the path that matters more than usual here, and the README gives it fully. Prerequisites are Xcode 15.3 or newer for building, and jazzy if you want the generated API reference. The build is one command:

```sh
sh build.sh build
```

It needs an internet connection on the first run to download the core binary, and it produces `Realm.xcframework` and `RealmSwift.xcframework` in `build/Release/`. `sh build.sh help` lists the other actions, including building for iOS or macOS separately, generating docs, and testing. The docs command is documented separately too, since the API reference is generated with jazzy from the `realm/jazzy` fork.

`build.sh` sits at the repository root alongside a `Gemfile`, a `Gemfile.lock` and a `.ruby-version`, which tells you the build tooling is Ruby-driven even though the product is Swift. There is also a `dependencies.list`, a `Configuration/` directory, `contrib/` and `scripts/`.

For local development the repository expects a mix of tooling: a `Gemfile` for the build scripts, `jazzy` for documentation, and the `plugin/` directory for Xcode integration. That is a real setup cost for a dependency you might otherwise add in a minute.

## The v20 releases and the code signing change

The release history is short, recent, and contains one line that changes the adoption calculus.

`v10.54.6` on 2025-10-15 added Xcode 26.0.1 binaries and dropped support for Xcode below 16.3. `v20.0.4` on 2026-02-23 updated build scripts for Xcode 26, fixed compilation with Xcode 26.4, and made two larger statements: it dropped support for Xcode below 26, and prebuilt binaries are no longer code signed because the project is no longer officially distributed by MongoDB.

That second clause is the one to sit with. An unsigned framework distribution changes what you can ship. Code signing is what lets an app pass distribution checks and, in some configurations, what lets an on-device install work at all for other people on your device. With no vendor signature attached to the binaries, you are either signing the product yourself as part of your own build, or building from source.

`v20.0.5` on 2026-06-14 is narrower: it fixes compilation with Xcode 27, and it changes how the `where` property on some SwiftUI helpers is defined, described as a workaround for backtick-escaped names not working in macro expansions. The release says the new definition appears API-compatible and asks you to report cases where it is not, which is the correct way to ship a change whose blast radius you cannot fully enumerate.

The compatibility tables are specific and useful. For v20.0.5: Carthage release built with Xcode 26.5, CocoaPods 1.10 or later, Xcode 26.1 through 27. For v20.0.4: Carthage built with Xcode 26.3, same CocoaPods floor, Xcode 26.1 through 26.4. Internally, v20.0.5 upgraded realm-core from 20.1.4 to 20.1.5.

Read together, three releases in nine months is a project still doing maintenance work against a moving toolchain, with a clear willingness to break compatibility when Apple moves. That is a different risk profile from abandonment, and a different one from a well-resourced product team.

## Community branch, MongoDB references, and who is actually maintaining this

The default branch on this repository is `community`. That single fact reframes everything else in the README, including the parts that still point at MongoDB.

The README's help section sends general discussion to the MongoDB Community Forum under the realm-sdks path, and the Code of Conduct section is the MongoDB Code of Conduct with a `community-conduct@mongodb.com` address. The license section states that the Objective-C and Swift SDKs are published under the Apache 2.0 license and that Realm Core is separately available at `github.com/realm/realm-core`, also Apache 2.0.

None of that is false, and all of it is institutional residue from when the project was distributed by MongoDB. Combined with the v20.0.4 signing note and the `community` branch, the picture is a codebase under community stewardship rather than a MongoDB product. The last push was on 2026-09-20, so work is landing, and 499 open issues against 16,610 stars is a ratio consistent with a large installed base and a small maintainer group.

Two categories of issue will resolve quickly and two will not, and it is worth being blunt about which is which. Build failures against a specific Xcode version have a track record of being fixed within weeks, as the v20.0.5 Xcode 27 note shows. A feature request that requires MongoDB to fund or prioritise it may not be resolved at all, and the open issue tracker is a better signal of that than the README is.

The support surface in the repository matches: a `SUPPORT.md`, a `CONTRIBUTING.md`, a `CHANGELOG.md`, and a Stack Overflow tag for code questions. The README asks bug reporters to include the version, a full log, the realm file, and a reproducing project. For a database, that request is reasonable and it is also the tell that debuggability on your side matters more here than on a pure library.

## Conclusion

realm-swift is in an unusual position: the code is alive and the stewardship is not what it was. Version 20.0.5 shipped on 2026-06-14 with an Xcode 27 compilation fix and a note that the `where` property on some SwiftUI helpers is now defined differently, with an explicit invitation to report breakage. Version 20.0.4 earlier dropped Xcode below 26 and stopped code signing the prebuilt binaries. The default branch is `community`, not `master`, which tells you the shape of the project before any of its documentation does. Technically the pitch has not moved: `@Persisted` properties, live objects that update on write, `@ObservedResults` for SwiftUI, and a 64-byte encryption key through `Realm.Configuration`. What has moved is who signs the binaries, and that is the question to answer before you build an app on it. If you need a compiled XCFramework with a vendor signature, you now build from source with `sh build.sh build` on Xcode 15.3 or newer, or you pick a different local store.

## FAQ

### What is Realm database?

It is a mobile database that runs directly inside phones, tablets or wearables, and this repository holds the source for the iOS, macOS, tvOS and watchOS versions of the Swift and Objective-C SDKs. Models are ordinary Swift classes inheriting from `Object` with properties marked `@Persisted`, and writes go through a write transaction on a `Realm` instance.

### What is a good database for Swift?

The comparison that matters is against the local-store options you already have. Against Core Data, the argument is that models are Swift classes with `@Persisted` properties rather than a separate model file plus accessors, and that `@ObservedResults` gives a SwiftUI view a live collection with `move`, `remove` and `append` bound to it. Against SQLite, the argument is that you write against the object model instead of composing SQL strings. The README states the positioning, and the compatibility table plus the code signing change are the practical details to weigh.

### How do I encrypt a local Realm database?

Generate a random 64-byte key, fill it with `SecRandomCopyBytes(kSecRandomDefault, 64, baseAddress)`, and pass it as `Realm.Configuration(encryptionKey: key)` when you open the realm. The key is a fixed-length random value rather than a passphrase, so it has to be stored somewhere safe, and the file cannot be read without it.

### Why are the realm-swift prebuilt binaries no longer code signed?

The v20.0.4 release notes on 2026-02-23 say prebuilt binaries are no longer code signed because the project is no longer officially distributed by MongoDB. The same release dropped support for Xcode below 26. If you need a signed framework, build from source with `sh build.sh build` on Xcode 15.3 or newer, which produces `Realm.xcframework` and `RealmSwift.xcframework` in `build/Release/`.

## Sources

- [License: Apache-2.0](https://github.com/realm/realm-swift/blob/community/LICENSE)
- [Project website](https://realm.io)
- [README](https://github.com/realm/realm-swift/blob/community/README.md)
- [realm/realm-swift on GitHub](https://github.com/realm/realm-swift)
- [Releases](https://github.com/realm/realm-swift/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/realm-realm-swift
