DataStore is Android's modern answer to SharedPreferences. It stores data asynchronously with coroutines and exposes it as a Flow, avoiding the blocking, error-prone API of the old preferences system. It comes in two flavors — Preferences and Typed (Proto) — for different needs.

Key takeaways

  • DataStore is async and transactional, unlike the blocking SharedPreferences API.
  • Preferences DataStore stores key-value pairs; Proto DataStore stores typed objects.
  • Reads are a Flow, so the UI reacts to changes automatically.

Why not SharedPreferences

SharedPreferences exposes synchronous reads and writes that can block the main thread and silently swallow errors. DataStore performs work on a background dispatcher, surfaces errors, and guarantees consistency, which matters for anything you read at startup.

Preferences vs Proto

Preferences DataStore is a drop-in for simple key-value settings — flags, tokens, last-screen. Proto DataStore stores strongly-typed objects defined by a schema, which is safer when your persisted data has structure and you want compile-time guarantees.

Reading as a Flow

DataStore exposes stored values as a Flow, so collecting it in a ViewModel keeps the UI in sync as values change — a natural fit alongside coroutines and Compose. Writes happen in a transactional edit block.