Realm Mobile Database

Loved by developers and more than a billion users, Realm Mobile Database is fast, easy to use, open source, and totally free.

Simple saving. Fast queries. Save weeks of development time.

Simple saving. Fast queries. Save weeks of development time.

Realm Mobile Database is an alternative to SQLite and Core Data. Thanks to its zero-copy design, Realm Mobile Database is much faster than an ORM, and often faster than raw SQLite. Get started in minutes, not hours.

Benefits of a database built for mobile

Offline-first functionality

Offline-first functionality

Make your app work as well offline as it does online.

Fast queries

Fast queries

Even complex queries take nanoseconds, and stay up to date with new data.

Safe threading

Safe threading

Access the same data concurrently from multiple threads, with no crashes.

Cross-platform apps

Cross-platform apps

Use the same database for all your apps, on any major platform.

Encryption

Encryption

Secure your data with transparent encryption and decryption.

Reactive architecture

Reactive architecture

Connect your UI to Realm, and data changes will appear automatically.

class Dog {}

Dog.schema = {
  name: 'Dog',
  properties: {
    name: 'string',
    age: 'int',
  }
};

let realm = new Realm({ schema: [Dog] });
realm.write(() => {
  realm.create('Dog', {name: 'Rex', age: 1});
});

let pups = realm.objects('Dog').filtered('age < 2');
Dog *dog = [Dog new];
dog.name = @"Rex";
dog.age = 1;

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
  [realm addObject:dog];
}];

RLMResults<Dog *> *allDogs = [Dog allObjects];
RLMResults<Dog *> *pups = [allDogs objectsWhere:@"age < 2"];
class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0
}

let dog = Dog()
dog.name = "Rex"
dog.age = 1

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

let pups = realm.objects(Dog.self).filter("age < 2")
public class Dog extends RealmObject {
  public String name;
  public int age;
}

Dog dog = new Dog();
dog.name = "Rex";
dog.age = 1;

Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.copyToRealm(dog);
realm.commitTransaction();

RealmResults<Dog> pups = realm.where(Dog.class)
                               .lessThan("age", 2)
                               .findAll();
public class Dog : RealmObject 
{
  public string Name { get; set; }
  public int Age { get; set; }
}

var realm = Realm.GetInstance();
realm.Write(() => 
{
  realm.Add(new Dog
  {
    Name = "Rex",
    Age = 1
  });
});

var pups = realm.All<Dog>().Where(d => d.Age < 2);

Simplify your code

Just subclass RealmObject to define your schema, subclass RLMObject to define your schema, define your schema, subclass Object to define your schema, subclass RealmObject to define your schema, persist with lightweight transactions, and query using fluent interfaces. NSPredicate. simple strings. NSPredicate. LINQ. Working with your data should always be this easy.

React Native executes JavaScript in a dedicated worker thread so common concurrency primitives are unavailable.
// Query and update the result in another thread
dispatch_async(dispatch_queue_create("background", 0), ^{
  Dog *theDog = [[Dog objectsWhere:@"age == 1"] firstObject];
  RLMRealm *realm = [RLMRealm defaultRealm];
  [realm beginWriteTransaction];
  theDog.age = 3;
  [realm commitWriteTransaction];
});
// Query and update from any thread
DispatchQueue(label: "background").async {
  let realm = try! Realm()
  let theDog = realm.objects(Dog.self).filter("age == 1").first
  try! realm.write {
    theDog!.age = 3
  }
}
public void onActivityCreated(Bundle savedInstanceState) {
  realm = Realm.getDefaultInstance();
  customers = realm.where(Customer.class).findAllAsync();
  changeListener = new RealmChangeListener() {
    @Override
    public void onChange(RealmResults<Customer> results) {
      listAdapter.notifyDataSetChanged(); // Update the UI
    }
  };
  customers.addChangeListener(changeListener);
}
// Query and update from any thread
Task.Run(() =>
{
  var realm = Realm.GetInstance();
  var theDog = realm.All<Dog>().First(d => d.Age == 1);
  realm.Write(() => theDog.Age = 3);
});

Work across threads

To start work on a new thread, just get a new reference to your Realm, and everything else just works. Each thread always has a consistent view of the data, which means illegal states are impossible.

let key = new Int8Array(64);  // pupulate with a secure key

let realm = new Realm({ schema: [Dog], encryptionKey: key });

let dogs = realm.objects('Dog').filtered('name CONTAINS "Fido"');
// Generate a random encryption key
NSMutableData *key = [NSMutableData dataWithLength:64];
(void)SecRandomCopyBytes(kSecRandomDefault, key.length, (uint8_t *)key.mutableBytes);

// Open the encrypted Realm file
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.encryptionKey = key;
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
// Use the Realm as normal
RLMResults<Dog *> *dogs = [Dog objectsInRealm:realm where:@"name contains 'Fido'"];
// Generate a random encryption key
var key = Data(count: 64)
_ = key.withUnsafeMutableBytes { bytes in
  SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
}

// Open the encrypted Realm file
let realm = try! Realm(configuration: Realm.Configuration(encryptionKey: key))
// Use the Realm as normal
let dogs = realm.objects(Dog.self).filter("name contains 'Fido'")
// Generate a random encryption key
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);

// Open the encrypted Realm file
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
        .encryptionKey(key)
        .build();

// Use the Realm as normal
Realm realm = Realm.getInstance(config);
RealmResults<Dog> results = realm.where(Dog.class).contains("name", "Fido").findAll();
// Generate a random encryption key
var random = new Random();
var key = new Byte[64];
rnd.NextBytes(key);
var config = new RealmConfiguration("Mine.realm");
config.EncryptionKey = key;

// Open the encrypted Realm file
var realm = Realm.GetInstance(config);
// Use the Realm as normal
var dogs = realm.All<Dog>().Where(d => d.Name.Contains("Fido"));

Encrypt everything

Keep your users’ data safe with AES-256 encryption, strong enough for global financial institutions.

let realm = new Realm({ schema: [Person] });
realm.addListener((sender, name) => {
  if (name === 'change') {
    this.setState({ source: sender.objects('Dog') });
  }
});
self.notificationToken = [[Dog objectsWhere:@"age > 5"]
                            addNotificationBlock:^(RLMResults<Dog *> *results,
                                                   RLMCollectionChange *change,
                                                   NSError *error) {
  if (error) {
    // handle error
    return;
  } else if (!changes) {
    [self.tableView reloadData];
    return;
  }

  // Update table view to animate deletions, insertions and modifications
  [tableView beginUpdates];
  [tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
    withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
    withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
    withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView endUpdates];
}];
let realm = try! Realm()
notificationToken = realm.objects(Dog.self).filter("age > 5").addNotificationBlock { changes in
  switch changes {
  case .initial:
    tableView.reloadData()
    break
  case .update(_, let deletions, let insertions, let modifications):
    // Update table view to animate deletions, insertions and modifications
    break
  case .error(let error):
    // handle error
    break
  }
}
Realm realm = Realm.getDefaultInstance();

// Query in the background
RealmResults<Dog> results = realm.where(Dog.class)
  .greaterThan("age", 5)
  .findAllAsync();

// Use ChangeListeners to be notified about updates
results.addChangeListener(new RealmChangeListener<RealmResults<Dog>() {
  @Override
  public void onChange(RealmResults<Dog> results) {
    // Update UI
  }
});

// Or RxJava
Observable<RealmResults<Dog>> obs = results.asObservable();
// To bind a ListView to results of a query
public partial class DogsPage : ContentPage
{
  internal Realm realm;
  internal IEnumerable<Dog> Entries { get; }

  public DogsPage()
  {
    InitializeComponent();
    realm = Realm.GetInstance();

    // Results from queries will automatically notify the Binding
    // and update the ListView accordingly
    Entries = realm.All<Dog>().Where(d => d.Age > 5)
    DogsList.ItemsSource = Entries;
  }

<ListView x:Name="DogsList">
  <ListView.ItemTemplate>
    <DataTemplate>
      <TextCell Text="{Binding Name}" 
        Detail="{Binding Age, StringFormat='is {0:#}'}" /> 
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

Build reactive apps

Realm objects are always live, which means that they always have the latest data. Subscribe to notifications to get updates when data changes, then update your UI. Your app will never be out of date again.

// Authenticating the User
Realm.Sync.User.registerWithProvider('http://realm.example.co:9080', 'google', googleAccessToken, (error, user) => {
  if (!error) {
    // Opening a remote Realm
    var realm = new Realm({
      sync: {
        user: user,
        url: 'realm://realm.example.co:9080/~/userRealm',
      }
    });
    // Any changes made to this Realm will be synced across all devices!
  }
})
// Authenticating the User
[RLMSyncUser logInWithCredentials:[RLMSyncCredentials credentialsWithGoogleToken:@"google token"]
                    authServerURL:[NSURL URLWithString:@"http://realm.example.com:9080"]
                     onCompletion:^(RLMSyncUser *user, NSError *error) {
  if (user) {
    // Opening a remote Realm
    NSURL *realmURL = [NSURL URLWithString:@"realm://realm.example.com:9080/~/userRealm"];
    RLMRealmConfiguration *config = [[RLMRealmConfiguration alloc] init];
    config.syncConfiguration = [[RLMSyncConfiguration alloc] initWithUser:user realmURL:realmURL];
    RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
    // Any changes made to this Realm will be synced across all devices!
  } else if (error) {
    // handle error
  }
}];
// Authenticating the User
SyncUser.logIn(with: .google(token: "google token"),
               server: URL(string: "http://realm.example.com:9080")!) { user, error in
  if let user = user {
    // Opening a remote Realm
    let realmURL = URL(string: "realm://realm.example.com:9080/~/userRealm")!
    let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: realmURL))
    let realm = try! Realm(configuration: config)
    // Any changes made to this Realm will be synced across all devices!
  } else if let error = error {
    // handle error
  }
}
// Authenticating the User
User user = User.login(Credentials.google("google token"),
                       "http://realm.example.com:9080/auth");
// Opening a remote Realm
String realmURL = "realm://realm.example.com:9080/~/userRealm";
SyncConfiguration config = new SyncConfiguration.Builder(user,
                                                         realmURL).build();
Realm realm = Realm.getInstance(config);
// Any changes made to this Realm will be synced across all devices!
var user = await User.LoginAsync(Credentials.Google("google token"),
                                 new Uri("http://realm.example.com:9080"));

var realmUrl = new Uri("realm://realm.example.com:9080/~/userRealm");
var config = new SyncConfiguration(user, realmUrl);

var realm = Realm.GetInstance(config);
// Any changes made to this Realm will be synced across all devices!

Sync data seamlessly

With the Realm Mobile Platform extensions, the Realm Mobile Database works perfectly with the Realm Object Server. All you need to do is set your Realm Object Server’s URL; everything else stays exactly the same. Data sync will automatically happen whenever you save, with no work from you.

Available for Realm Java, Realm Objective‑C, Realm Swift, Realm JavaScript, and Realm Xamarin.

Proudly open source

The Realm Mobile Database is developed in the open. Thousands of developers work with us on GitHub, plus hundreds more write add-ons that work with the Realm Mobile Database. The 25,000 stars on our repos speak for themselves.

Stay up to date on the latest mobile development news

Get the best talks and articles from around the world delivered straight to your inbox. See what we've posted already on our blog.



Trusted by Fortune 500 mainstays, innovative startups, and #1-ranked app store successes

Get started in 5 minutes, for free