Realm est une base de données NoSQL orientée objet pour mobile, développée comme alternative à SQLite et Core Data pour iOS et Android. Les données sont stockées dans un format propriétaire avec un accès direct aux objets en mémoire, offrant une vitesse de lecture et d'écriture élevée. Grâce aux notifications réactives, à la synchronisation automatique via Realm Sync et à un modèle de données multiplateforme, Realm est utilisé sur plus d'un milliard d'appareils (données MongoDB, 2025).
Points clés
Realm est une base de données orientée objet créée spécialement pour les applications mobiles. Contrairement à SQLite, Realm n'utilise ni SQL ni modèle relationnel — les données sont stockées sous forme d'objets vivants (Live Objects), accessibles directement sans couche ORM intermédiaire. Le développeur travaille avec des objets normaux du langage (Swift, Kotlin, Dart) qui sont automatiquement sauvegardés dans la base de données.
Realm est apparu en 2014 en tant que startup Realm Inc., et a été acquis en 2019 par MongoDB Inc. Depuis lors, Realm est développé sous le nom de MongoDB Realm — faisant partie de la plateforme unifiée Atlas Device Sync pour la synchronisation de données mobiles. La base de données locale de base de Realm reste gratuite et open source (licence Apache 2.0), tandis que Realm Sync (synchronisation cloud) est distribué par abonnement.
Selon le MongoDB Developer Report (2025), Realm est utilisé dans 15 % des applications mobiles comme stockage local principal. Les principaux cas d'utilisation sont les applications avec mode hors ligne, des modèles d'objets complexes et un besoin de synchronisation entre appareils, où Realm surpasse SQLite en vitesse de développement et en facilité de travail avec les objets.
Live Objects — chaque objet Realm est lié au disque via un fichier mappé en mémoire (memory-mapped file). Modifier un objet dans n'importe quel thread se reflète immédiatement dans tous les autres threads sans notification manuelle. L'interface utilisateur se redessine automatiquement lors des modifications de données via les notifications Realm. Zero-copy — Realm ne copie pas les données de la base de données vers les objets ; les objets sont les données en mémoire.
Le noyau de Realm est écrit en C++ et utilise B+ Tree pour l'indexation des données. Contrairement à SQLite, où chaque ligne est un enregistrement dans une table relationnelle, Realm stocke les objets comme des nœuds dans une structure de graphe avec des références directes entre eux (forward pointers). Les relations entre objets ne sont pas des clés étrangères mais des pointeurs directs, ce qui élimine le besoin d'opérations JOIN.
Les fichiers Realm (extension .realm) sont mappés en mémoire (memory-mapped) — le système d'exploitation gère lui-même le chargement des pages du fichier en mémoire au fur et à mesure des accès. Cela permet à Realm de travailler avec des bases de données plus grandes que la RAM disponible et offre une latence de lecture au niveau des structures de données natives du langage (Swift Array ou Kotlin List) pour les données qui tiennent dans la RAM.
Fichiers mappés en mémoire — la technologie clé de Realm. Au lieu de copier les données du fichier de base de données vers les objets du langage (comme le fait SQLite via sqlite3_step + sqlite3_column_*), Realm mappe le fichier de base de données directement dans l'espace d'adressage du processus. Les objets du langage sont simplement des pointeurs vers les données dans la mémoire mappée. Modifier un objet modifie la base de données sur le disque sans appel save séparé.
| Caractéristique | Realm (zero-copy) | SQLite (copie) |
|---|---|---|
| Lecture | Accès direct à la mémoire (nanosecondes) | Copie vers objet (microsecondes) |
| Écriture | Écriture immédiate dans le fichier memory-mapped | save() avec transaction SQL INSERT/UPDATE |
| Relations | Pointeurs directs (forward pointers) | Clé étrangère + JOIN |
| Consommation mémoire | Fichier + cache de pages OS | Objets + cache de pages SQLite |
| Objets vivants | Oui (mise à jour automatique) | Non (nouvelle requête nécessaire) |
La consommation mémoire est plus élevée dans Realm lors de la lecture active (tout le fichier ou une grande partie est mappée en mémoire), mais plus faible lors des opérations d'écriture car aucune allocation mémoire pour les copies d'objets n'est nécessaire. Pour les bases de données jusqu'à 1 Go sur les appareils mobiles, l'approche memory-mapped offre de meilleures performances globales que SQLite avec sa copie intermédiaire.
SQLite est un SGBD relationnel avec SQL et transactions ACID. Realm est une base de données NoSQL orientée objet avec accès memory-mapped. Core Data est la couche ORM d'Apple au-dessus de SQLite. Chacune des trois approches a son propre domaine d'application et ses points forts. Realm excelle en vitesse d'accès direct aux objets et réactivité, SQLite en polyvalence et maturité, Core Data en intégration avec l'écosystème Apple.
Les performances de lecture de Realm sont 10 à 50 % supérieures à celles de SQLite grâce à l'accès zero-copy. Realm est également plus rapide en écriture en raison de l'absence d'analyse syntaxique SQL et de la modification directe des pages memory-mapped. Cependant, Realm peut consommer plus de RAM lors du travail avec de grandes bases de données (>500 Mo), car le fichier est entièrement mappé dans l'espace d'adressage.
| Critère | Realm | SQLite | Core Data |
|---|---|---|---|
| Type | BD NoSQL orientée objet | SGBD relationnel (SQL) | ORM sur SQLite |
| Vitesse de lecture | Élevée (zero-copy) | Moyenne | Moyenne (surcharge ORM) |
| Réactivité | Live Objects (intégrée) | Nécessite un wrapper (Room/GRDB) | NSFetchedResultsController |
| Synchronisation | Realm Sync (MongoDB Atlas) | Implémentation personnalisée requise | NSPersistentCloudKitContainer |
| Plateformes | iOS, Android, Flutter, RN, Node.js | iOS, Android, Web, Desktop | iOS/macOS uniquement |
| Taille de bibliothèque | ~4 Mo | ~600 Ko | Intégré au SDK |
Le choix entre Realm et SQLite se résume souvent à des priorités : vitesse de développement et réactivité (Realm) contre contrôle et polyvalence (SQLite). Realm est particulièrement adapté aux MVP et prototypes où le modèle de données change fréquemment et où il est important d'obtenir rapidement des mises à jour d'interface en direct. SQLite/Room est préférable pour les produits matures avec de gros volumes de données et des requêtes analytiques complexes.
Realm Kotlin SDK est la bibliothèque officielle pour Android, écrite en Kotlin (pas un wrapper au-dessus de Java SDK). Le modèle de données est défini via des classes héritant de RealmObject, avec l'annotation @PrimaryKey pour un identifiant unique. Realm Kotlin prend en charge Kotlin Coroutines, Flow et KSP (Kotlin Symbol Processing) pour la génération de code à la compilation.
RealmQuery fournit une API type-safe pour le filtrage sans SQL. Les requêtes sont construites par chaînage de méthodes : query → filter → sort → find. Le résultat peut être retourné sous forme de liste (chargée en mémoire) ou de Flow (flux réactif se mettant à jour lors des modifications de données). Realm Kotlin prend également en charge les objets imbriqués et les listes (RealmList).
Modèle de données Realm est défini comme une classe de données implémentant l'interface RealmObject. Le champ _id est marqué avec @PrimaryKey pour une identification unique. La relation un-à-plusieurs est implémentée via RealmList — une liste d'autres RealmObject. Toutes les opérations d'écriture (création, mise à jour, suppression) sont effectuées dans un bloc de transaction write.
class Project : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var name: String = ""
var tasks: RealmList<Task> = realmListOf()
}
class Task : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var title: String = ""
var isComplete: Boolean = false
}
val config = Realm.Configuration.Builder(
schema = setOf(Project::class, Task::class)
).build()
val realm = Realm.open(config)
realm.write { transactionRealm ->
val project = copyToRealm(Project().apply {
name = "Mobile App"
})
project.tasks.add(copyToRealm(Task().apply {
title = "Design UI"
}))
}
val projects: Flow<RealmResults<Project>> =
realm.query<Project>()
.sort(Project::name, Sort.ASCENDING)
.asFlow()
Une requête retournant Flow émet automatiquement de nouveaux résultats lors de toute modification de données dans Realm : ajout, mise à jour ou suppression d'un Project ou Task. L'approche Flow s'associe parfaitement avec Compose : collectAsState() dans ViewModel recompose automatiquement l'UI lors des modifications de données sans mise à jour manuelle des adaptateurs de liste ni utilisation de LiveData.
Realm Swift SDK fournit une API Swift native avec prise en charge d'async/await, Combine Publishers et Swift Concurrency. Les modèles de données sont définis comme des classes héritant de Object, en utilisant @Persisted pour les propriétés. Realm Swift met automatiquement à jour les objets lors des modifications, et les notifications (NotificationToken) permettent de s'abonner aux modifications d'objets ou de collections individuelles.
@ObservedRealmObject et @ObservedResults sont des Property Wrappers pour SwiftUI qui redessinent automatiquement la vue lors des modifications des données Realm. @ObservedResults fonctionne avec les résultats de requête, @ObservedRealmObject avec un objet spécifique. Les deux propriétés annulent l'abonnement lors de la désinitialisation de la vue.
Intégration SwiftUI Realm est l'un des points forts du SDK. Le Property Wrapper @ObservedResults lie une requête Realm à l'affichage dans SwiftUI. Lorsqu'une tâche change, SwiftUI recompose automatiquement la liste. realm.writeAsync exécute les transactions sur un thread d'arrière-plan sans bloquer l'UI.
import RealmSwift
class TaskItem: Object, Identifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var title: String = ""
@Persisted var isDone: Bool = false
@Persisted var priority: Int = 0
}
struct TaskListView: View {
@ObservedResults(TaskItem.self,
sortDescriptor: SortDescriptor(["priority"]))
var tasks
var body: some View {
List {
ForEach(tasks) { task in
TaskRow(task: task)
}
}
Button("Add Task") {
let realm = try! Realm()
try! realm.write {
realm.add(TaskItem(value: ["title": "New task"]))
}
}
}
}
@ObservedResults gère automatiquement le cycle de vie de la requête Realm : lors de la création de la vue, un abonnement aux modifications est créé ; lors de la destruction, il est annulé. Le Property Wrapper accepte un prédicat optionnel (NSPredicate) et un descripteur de tri. Cela élimine le besoin d'écrire manuellement des requêtes fetch, de créer des ViewModels et de s'abonner aux notifications Realm.
Applications hors ligne — Realm est idéal pour les scénarios où les données doivent être disponibles sans Internet. La synchronisation intégrée (Realm Sync avec MongoDB Atlas) résout automatiquement les conflits lors de la connexion au réseau. L'application continue de fonctionner avec les données locales, et la synchronisation en arrière-plan les met à jour lorsqu'une connexion est disponible.
Interfaces réactives — Live Objects et les notifications Flow/Combine font de Realm un choix pratique pour les applications avec des données fréquemment mises à jour : chats, flux de tâches, documents collaboratifs. L'UI se met automatiquement à jour lors de l'ajout, de la modification ou de la suppression de données sans appel manuel à reloadData ou invalidate.
Projets multiplateformes — Realm prend en charge Kotlin Multiplatform (KMP), Flutter, React Native et Xamarin. Le modèle de données est défini une fois et utilisé sur toutes les plateformes. Cela réduit la duplication de code et garantit la cohérence du schéma entre les applications iOS et Android avec une logique métier partagée.
Realm Sync est un service cloud intégré à MongoDB Atlas. L'application synchronise automatiquement les données entre les appareils de l'utilisateur et le serveur. Les conflits sont résolus par la stratégie « last write wins » ou via des fonctions personnalisées de résolution de conflits sur le serveur. Realm Sync prend en charge la synchronisation partielle (sous-ensemble de données) pour réduire le trafic.
class SyncRepository {
private val app = App(
AppConfiguration(
appId = "my-realm-app-id"
)
)
suspend fun syncData() {
val user = app.login(Credentials.anonymous())
val config = SyncConfiguration.Builder(
user, setOf(Project::class)
).build()
val syncedRealm = Realm.open(config)
// La synchronisation automatique est active
}
}
SyncConfiguration configure la connexion à MongoDB Atlas et définit l'ensemble des modèles à synchroniser. Après l'authentification de l'utilisateur, Realm charge automatiquement les données du cloud et les fusionne avec les modifications locales. La synchronisation s'exécute sur un thread d'arrière-plan et ne nécessite pas d'appels manuels — il suffit de créer une instance Realm avec SyncConfiguration.
Foire aux questions
Oui, la base de données locale Realm est entièrement gratuite (licence Apache 2.0). Realm Sync (synchronisation cloud) via MongoDB Atlas est un service payant inclus dans l'abonnement Atlas Device Sync. Le niveau gratuit d'Atlas comprend les premiers 500 Mo de données et 1 million d'opérations par mois.
Oui, la migration est possible en exportant les données de SQLite vers JSON et en les important dans Realm au premier chargement de l'application. Pour les gros volumes, utilisez la migration en continu : écrivez les données dans les deux bases en parallèle pendant que les utilisateurs passent à la nouvelle version de l'application, puis supprimez le fichier SQLite.
Realm Sync utilise par défaut la stratégie « last write wins » — la dernière écriture écrase la précédente. Pour les conflits complexes, configurez des fonctions personnalisées de résolution de conflits sur le serveur MongoDB Atlas qui fusionnent les modifications de différents appareils selon la logique métier de l'application (par exemple, fusionner les valeurs au lieu de les remplacer).
Realm ne prend pas en charge les agrégations SQL (SUM, AVG, GROUP BY) au niveau de la base de données. Pour les requêtes analytiques, il est recommandé d'exporter les données de Realm vers MongoDB Atlas via Realm Sync et d'exécuter les agrégations via le MongoDB Aggregation Pipeline. Pour les comptages simples, utilisez realm.query<T>().count().
Realm ne chiffre pas les données par défaut. Pour le chiffrement, fournissez une clé de 64 octets dans la configuration : Realm.Configuration(encryptionKey: key). Le chiffrement utilise AES-256 + SHA-2 HMAC et augmente la surcharge des opérations de 10 à 20 %. Sans chiffrement, le fichier .realm peut être lu par tout processus ayant accès au système de fichiers.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi