Android equivalent of NSUserDefaults in iOS
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If you come from iOS, the closest traditional Android equivalent to NSUserDefaults is SharedPreferences. Both store small pieces of application data as key-value pairs. In modern Android code, though, it is worth knowing that Jetpack DataStore is now often preferred for new work because it offers a cleaner async API and fewer consistency issues.
The Direct Mapping: SharedPreferences
NSUserDefaults is commonly used for settings such as theme choice, last login flag, or a saved username. On Android, SharedPreferences serves the same role.
A basic example in Kotlin looks like this:
The pattern is familiar if you have used defaults on iOS:
- choose a key
- write a primitive value
- read it later with a fallback default
This is appropriate for small user preferences and lightweight app state.
apply() vs commit()
When writing preferences, Android gives you two main choices.
apply() updates the in-memory value immediately and writes to disk asynchronously. It is usually the right default for UI code.
commit() writes synchronously and returns a success flag. That can be useful when you absolutely need to know the write finished, but it blocks longer and is used less often.
For most settings screens, apply() is simpler and better aligned with normal app responsiveness.
Activity-Specific vs App-Wide Preferences
Android offers more than one way to access preferences. The most common is getSharedPreferences(name, MODE_PRIVATE), which creates or opens a named file shared across the app.
If you only want data scoped to one activity, there is also getPreferences(MODE_PRIVATE). In practice, named shared preferences are usually clearer because they make the storage file explicit.
A wrapper class helps keep keys in one place:
This is easier to maintain than scattering hard-coded keys through multiple activities.
Why Many Android Apps Use DataStore Now
While SharedPreferences is the historical equivalent, new Android projects often use DataStore instead. DataStore avoids some of the old API's awkwardness and works naturally with coroutines and flows.
A minimal preferences DataStore example looks like this:
That does not change the answer to the original question. The conceptual equivalent is still SharedPreferences. It just means modern Android developers should know there is a newer option with better ergonomics.
What Kind of Data Belongs Here
Like NSUserDefaults, Android preference storage is for small configuration values, not for large structured data. Good examples include:
- theme choice
- onboarding completed flag
- selected language code
- remembered sort option
Poor examples include:
- large cached API responses
- images or files
- relational data better suited to Room or SQLite
- secrets that should be stored with stronger protection
Common Pitfalls
A common mistake is treating SharedPreferences as a general-purpose database. It is for small key-value settings, not for complex domain data.
Another issue is duplicating raw string keys all over the codebase. A wrapper class or constants object reduces typing errors and makes refactoring safer.
Developers also sometimes assume apply() means the data is immediately durable on disk. It updates memory first and writes asynchronously, which is fine for most settings but worth understanding.
Finally, if you are starting a new Android app, do not stop at the old analogy. SharedPreferences is the classic equivalent to NSUserDefaults, but DataStore may be the better implementation choice.
Summary
- The traditional Android equivalent of
NSUserDefaultsisSharedPreferences. - Use it for small key-value settings and lightweight app state.
- Prefer
apply()for most writes andcommit()only when synchronous completion matters. - Keep keys centralized instead of scattering string literals across the app.
- For new Android projects, consider DataStore as the modern alternative.

