realm/realm-java
Realm is a mobile database: a replacement for SQLite & ORMs
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 8mo ago
- ✓16 active contributors
- ✓Distributed ownership (top contributor 36% of recent commits)
Show all 7 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
- ⚠Slowing — last commit 8mo ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/realm/realm-java)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/realm/realm-java on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: realm/realm-java
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/realm/realm-java shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 8mo ago
- 16 active contributors
- Distributed ownership (top contributor 36% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Slowing — last commit 8mo ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live realm/realm-java
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/realm/realm-java.
What it runs against: a local clone of realm/realm-java — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in realm/realm-java | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 265 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of realm/realm-java. If you don't
# have one yet, run these first:
#
# git clone https://github.com/realm/realm-java.git
# cd realm-java
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of realm/realm-java and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "realm/realm-java(\\.git)?\\b" \\
&& ok "origin remote is realm/realm-java" \\
|| miss "origin remote is not realm/realm-java (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "build.gradle" \\
&& ok "build.gradle" \\
|| miss "missing critical file: build.gradle"
test -f "CHANGELOG.md" \\
&& ok "CHANGELOG.md" \\
|| miss "missing critical file: CHANGELOG.md"
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "CONTRIBUTING.md" \\
&& ok "CONTRIBUTING.md" \\
|| miss "missing critical file: CONTRIBUTING.md"
test -f "version.txt" \\
&& ok "version.txt" \\
|| miss "missing critical file: version.txt"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 265 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~235d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/realm/realm-java"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Realm Java is an embedded mobile database for Android that replaces SQLite and traditional ORMs by exposing data directly as queryable objects. It provides thread-safe, encrypted persistence with real-time sync capabilities via Atlas Device Sync, and is optimized for mobile-first use cases with better performance than raw SQLite while maintaining a minimal API surface. Hybrid monorepo: Java/Kotlin layer in root providing public API (likely realm-java-core modules), C++/CMake native bindings in a submodule (referenced via .gitmodules), comprehensive gradle-based build system with buildscript configuration in build.gradle and dependencies.list, extensive docs in docs/guides/ covering CRUD, threading, data types, and schema migration.
👥Who it's for
Android developers building mobile apps who need local data persistence without SQLite complexity or ORM boilerplate. Typically teams using Java/Kotlin on Android who want encrypted, queryable objects with optional cloud synchronization through MongoDB Atlas.
🌱Maturity & risk
Production-ready but in deprecation phase: Realm Java is mature and widely deployed, with comprehensive CI/CD via GitHub Actions (workflows in .github/workflows/), extensive documentation, and clear changelog tracking. However, MongoDB announced SDK deprecation in September 2024 in favor of Realm Kotlin; new projects should target realm-kotlin instead per the README.
Moderate risk due to deprecation status and multi-language complexity. The codebase includes 712KB of C++ native code requiring NDK compilation, complex gradle property passing for native builds (buildTargetABIs, coreSourcePath), and dependency on external core library. Last active development is unclear but deprecation means fewer feature updates and eventual maintenance mode.
Active areas of work
The repo is in maintenance/deprecation mode post-September 2024 announcement. Automated workflows monitor issues (Issue-Needs-Attention.yml), validate PRs (check-pr-title.yml, check-changelog.yml), and manage community engagement (auto-assign.yml, lock-threads.yml). Focus appears to be on stability and documentation rather than new features.
🚀Get running
git clone https://github.com/realm/realm-java.git && cd realm-java && ./gradlew build (gradlew script inferred from standard Android gradle setup). Requires Android SDK, NDK for native compilation, and Java 8+. See docs/guides/quick-start-local.md for project integration instructions.
Daily commands: No traditional 'dev server'; this is a library. Run tests with ./gradlew test or ./gradlew connectedAndroidTest for device/emulator tests. Integration into Android project: add Maven Central dependency io.realm:realm-gradle-plugin and apply gradle plugin per docs/guides/install.md.
🗺️Map of the codebase
build.gradle— Root build configuration defining version management, dependencies, and Gradle plugin setup; all contributors must understand the build system to compile and test RealmCHANGELOG.md— Complete record of version changes, bug fixes, and feature additions; essential reading to understand what has changed and current state of the libraryREADME.md— Project overview, deprecation notice (Device Sync), and direction toward Realm Kotlin SDK; critical for understanding project status and scopeCONTRIBUTING.md— Contribution guidelines and development workflow; every contributor must follow these conventionsversion.txt— Current release version referenced by build.gradle; governs all published artifacts and versioning.github/workflows— CI/CD pipeline definitions (auto-assign, check-pr-title, check-changelog); shows how code is validated before mergeJenkinsfile— Jenkins build pipeline for integration testing and deployment; defines the production build and release process
🧩Components & responsibilities
- Realm Core (Native) (C++, SQLite-compatible storage format) — ACID-compliant embedded database engine; handles persistence, indexing, query execution, and concurrency control
🛠️How to make changes
Define a new Realm object model
- Create a new Java class extending RealmObject in your model package (
examples/architectureComponentsExample/src/main/java/io/realm/examples/arch/model/Person.java) - Annotate fields with @PrimaryKey, @Ignore, @Index as needed; follow naming and type conventions from docs/guides/model-data/data-types/field-types.md (
docs/guides/model-data/data-types/field-types.md) - Define relationships using RealmList<T> or RealmObject references as shown in relationship documentation (
docs/guides/model-data/relationships.md) - If migrating schema, follow schema modification patterns documented in modify-an-object-schema.md (
docs/guides/model-data/modify-an-object-schema.md)
Integrate Realm into an Android Activity/Fragment
- Add realm-gradle-plugin to build.gradle and apply it to your app module (see architecture example setup) (
build.gradle) - Open a Realm instance using Realm.getDefaultInstance() or with configuration options from open-and-close-a-realm.md (
docs/guides/realm-files/open-and-close-a-realm.md) - For reactive updates, wrap results in LiveRealmResults or use async API as shown in the architecture example (
examples/architectureComponentsExample/src/main/java/io/realm/examples/arch/livemodel/LiveRealmResults.java) - Execute CRUD operations (create, read, filter, update, delete) following the guides in docs/guides/crud/ (
docs/guides/crud/create.md) - Close the Realm instance in onDestroy() to ensure cleanup (
docs/guides/realm-files/open-and-close-a-realm.md)
Add a new example or test application
- Create a new module under examples/ directory following the structure of architectureComponentsExample (
examples/architectureComponentsExample) - Add a build.gradle for the new module with Realm dependency and required AndroidX/Architecture component versions from dependencies.list (
dependencies.list) - Define model classes extending RealmObject in a model package (
examples/architectureComponentsExample/src/main/java/io/realm/examples/arch/model/Person.java) - Implement Activities/Fragments that initialize Realm and perform operations as shown in the existing example (
examples/architectureComponentsExample/src/main/java/io/realm/examples/arch/ArchExampleActivity.java)
🔧Why these technologies
- Android & Java — Realm Java is designed specifically for Android apps; leverages Android Framework APIs, lifecycle awareness, and native Java language features
- Gradle & Maven Central — Standard Android build system; enables dependency management, plugin architecture, and seamless library distribution
- SQLite (underlying storage) — Mobile-optimized embedded database providing ACID guarantees, query efficiency, and zero external dependencies
- Architecture Components (LiveData, ViewModel) — Example app demonstrates integration with modern Android lifecycle patterns for reactive UI updates
⚖️Trade-offs already made
-
Deprecated in favor of Realm Kotlin SDK
- Why: Kotlin Multiplatform support, better coroutine integration, and modern language features
- Consequence: New projects should use Realm Kotlin; this repo is in maintenance mode with no new features planned
-
Android-only (no pure Java backend support)
- Why: Optimized for mobile constraints: battery, storage, threading model
- Consequence: Cannot be used in server-side Java applications; Desktop or backend use requires Realm Core directly
-
Synchronous and async dual APIs
- Why: Support both blocking queries (simple cases) and non-blocking async (Android main thread safety)
- Consequence: Developers must choose API appropriately; async API more complex but prevents ANRs
🚫Non-goals (don't propose these)
- Backend synchronization with MongoDB Atlas (Device Sync is deprecated as of Sept 2024)
- Pure Java/Kotlin Multiplatform support (Realm Kotlin SDK is the recommended successor)
- Windows Phone, Blackberry, or legacy Android versions (only modern Android supported)
- Full ORM features like automatic lazy loading of relationships (design favors explicit control)
🪤Traps & gotchas
Native compilation requires Android NDK and coreSourcePath property pointing to external Realm core repo (submodule). Gradle property copyProperties block silently propagates buildTargetABIs, enableLTO, and signBuild—missing these causes cryptic compilation failures. Device Sync features deprecated as of September 2024—code paths may bitrot. Maven Central publishing requires s3cfg credentials. Tests must run via connectedAndroidTest on real device/emulator, not unit test runner.
🏗️Architecture
💡Concepts to learn
- Memory-mapped I/O — Realm's performance advantage over SQLite comes from mapping the database file directly to process memory via native code; understanding this explains why Realm is faster for reads and why threading must be carefully managed
- ACID Transactions with WAL (Write-Ahead Logging) — Realm uses WAL for crash-safety and concurrency control; this is why you see transaction blocks in CRUD examples and why certain operations must be within write transactions
- JNI (Java Native Interface) — Realm Java's C++ core is wrapped via JNI bindings; understanding method signatures, object marshalling, and GC interactions is critical for debugging native crashes
- CRDT (Conflict-free Replicated Data Type) — Device Sync uses CRDTs to merge offline changes from multiple clients without manual conflict resolution; understanding this explains sync behavior in docs/guides/async-api.md
- Thread-confined Realm Instances — Realm objects are bound to the thread that created them and cannot be shared across threads; this is why docs/guides/crud/threading.md exists and why it's the #1 error in Realm development
- Lazy Query Evaluation — Realm queries are lazy and only materialize results when accessed; this enables efficient filtering on large datasets but means query logic doesn't execute immediately (see docs/guides/crud/filter-data.md)
- Encryption at Rest (Realm Encryption Key) — Realm supports optional AES encryption via a user-provided key; critical for apps handling sensitive data, configured at database open time
🔗Related repos
realm/realm-kotlin— Official successor to realm-java; Kotlin Multiplatform implementation with Android + iOS support; MongoDB recommends this for new projectsrealm/realm-core— The C++ engine powering realm-java via JNI bindings; referenced as submodule; contains storage and query enginemongodb/mongodb-realm— Device Sync backend service; realm-java apps syncing data connect to this Atlas infrastructuresquare/sqlbrite— Alternative reactive SQLite wrapper for Android; direct competitor showing the problem realm solves (ORM boilerplate)greenrobot/greenDAO— Legacy Android ORM that realm replaced; demonstrates why direct object queries were needed
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive testing for RealmSet and RealmDictionary data types
The docs directory contains detailed guides for RealmSet (docs/guides/model-data/data-types/realmset.md) and RealmDictionary (docs/guides/model-data/data-types/realmdictionary.md), but there's no indication of corresponding unit test coverage in the examples or test directories. These are complex collection types that deserve dedicated test suites covering edge cases, thread safety, and lifecycle management.
- [ ] Create src/test/java/io/realm/RealmSetTest.java with tests for add/remove/contains/iteration operations
- [ ] Create src/test/java/io/realm/RealmDictionaryTest.java with tests for put/get/remove/keySet operations
- [ ] Add thread-safety tests for concurrent access patterns to both data types
- [ ] Add tests for behavior when RealmSet/RealmDictionary are used with nested RealmObjects
- [ ] Reference the existing collection tests pattern (if any) to maintain consistency
Create GitHub Action workflow for automated documentation validation
The repo has docs/guides with extensive Markdown documentation covering features like async-api, crud operations, and encryption. Currently there's check-changelog.yml and check-pr-title.yml workflows, but no workflow to validate that code examples in documentation are syntactically correct or that documentation links are not broken. This would catch stale docs before merge.
- [ ] Create .github/workflows/validate-docs.yml that runs on PRs modifying docs/
- [ ] Add logic to extract and validate Kotlin/Java code blocks from all .md files in docs/guides/
- [ ] Add markdown link validation to ensure references to docs/guides/* files exist
- [ ] Include a check to ensure new features in CHANGELOG.md are documented in corresponding docs/ files
- [ ] Document the workflow requirements in CONTRIBUTING.md
Add integration tests for encryption and realm file operations
The docs directory contains dedicated guides for encryption (docs/guides/realm-files/encryption.md) and realm file management (docs/guides/realm-files/open-and-close-a-realm.md), but the file structure suggests limited test coverage for these critical security and file-handling features. These deserve dedicated integration test suites.
- [ ] Create src/test/java/io/realm/RealmEncryptionTest.java with tests for opening/closing encrypted realms
- [ ] Add tests for encryption key rotation and migration scenarios
- [ ] Create src/test/java/io/realm/RealmFileOperationsTest.java for bundle, backup, and restore operations
- [ ] Add tests for cross-thread access to encrypted realm files
- [ ] Add error-case tests for corrupted/incompatible encryption keys and file corruption recovery
🌿Good first issues
- Add missing documentation example in docs/guides/model-data/data-types/ for RealmDictionary usage patterns (file exists but may lack concrete examples). 2. Create a GitHub Action workflow to run consistency checks on CHANGELOG.md format (check-changelog.yml exists but could validate version ordering). 3. Add Java interop tests in a new test suite for Kotlin extensions to ensure seamless cross-language usage (realm-kotlin compatibility bridge).
⭐Top contributors
Click to expand
Top contributors
- [@Christian Melchior](https://github.com/Christian Melchior) — 36 commits
- @rorbech — 21 commits
- @clementetb — 7 commits
- @nhachicha — 6 commits
- @geragray — 6 commits
📝Recent commits
Click to expand
Recent commits
e5f4caa— Merge pull request #7910 from cbullinger/DOCSP-53341-add-java-sdk-docs (cbullinger)9b3e835— Update docs/README.md (cbullinger)660d13f— Remove links to SDK docs from main README (cbullinger)da0a9b3— Add markdown docs to docs/ dir for community access (cbullinger)6a02481— Merge pull request #7906 from realm/tkaye407-patch-1 (tkaye407)f273237— Update README.md with deprecation notice (tkaye407)677f2c4— Prepare next dev iteration (nhachicha)d38cc2b— Fixes (nhachicha)0ab8d69— Release 10.19.0 (nhachicha)bf428f2— Add missing obfuscation configuration (#7887) (rorbech)
🔒Security observations
The Realm Java repository shows moderate security posture with several areas requiring attention. Critical issues include incomplete gradle configuration and potential property injection risks. High-priority concerns involve lack of version pinning in Docker and missing dependency vulnerability scanning in CI/CD. The codebase appears well-structured with GitHub security workflows in place (auto-assign,
- High · Incomplete Gradle Build Configuration —
build.gradle (line with 'signBuild' property). The build.gradle file shows a truncated property definition at the end ('signBuild'). This incomplete configuration could lead to unintended build behavior or security properties not being applied correctly. The file appears to be cut off mid-way through a property assignment. Fix: Complete the build.gradle file and ensure all property definitions are properly closed and validated. Review the entire configuration for syntax errors. - High · Potential Unvalidated Property Injection —
build.gradle (getPropertyValueOrThrow and copyProperties functions). The build.gradle uses dynamic property loading via getPropertyValueOrThrow() and copyProperties without apparent validation of property values before passing them to startParameter.projectProperties. This could allow injection of malicious property values if environment variables or gradle properties are compromised. Fix: Implement whitelist validation for all dynamic properties before passing them to build parameters. Sanitize and validate all environment variables and gradle properties. - Medium · Gradle Wrapper Validation Not Verified —
.github/workflows/gradle-wrapper-validation.yml and gradle wrapper configuration. While there is a gradle-wrapper-validation workflow in .github/workflows/gradle-wrapper-validation.yml, the actual gradle wrapper checksums and configuration are not visible in the provided file structure. The gradle-wrapper.jar could be vulnerable if not properly validated. Fix: Ensure gradle-wrapper.jar is validated against known good checksums. Keep gradle wrapper updated to latest secure version. Consider using gradle wrapper verification flag. - Medium · Docker Base Image Without Explicit Version —
Dockerfile (RUN apt-get install commands). The Dockerfile uses 'ubuntu:22.04' which is acceptable, but package installations don't specify versions (e.g., 'apt-get install -y locales'). This can lead to non-deterministic builds and potential installation of vulnerable package versions. Fix: Pin all package versions in apt-get install commands. Example: 'apt-get install -y locales=2.35-0ubuntu1'. Use specific version tags for base images. - Medium · Missing Security Scanning in CI/CD —
.github/workflows/. The provided GitHub workflows do not show evidence of SAST (Static Application Security Testing), dependency vulnerability scanning, or container image scanning in the CI/CD pipeline. Fix: Implement GitHub security features: enable Dependabot, GHSA scanning, and CodeQL analysis. Add tools like Snyk or Trivy for dependency and container scanning. - Medium · Environment Variable Management in Docker —
Dockerfile (ENV declarations). The Dockerfile sets multiple sensitive environment variables (ANDROID_HOME, ANDROID_NDK_HOME, JAVA_HOME paths) without clear documentation of which are sensitive. This could lead to information disclosure if container images are shared. Fix: Document which environment variables are sensitive. Use Docker build arguments instead of hardcoded ENV for sensitive paths. Implement proper secret management for credential-bearing environment variables. - Low · Missing .gitignore Coverage Verification —
.gitignore. While a .gitignore file exists, its contents are not provided. Common sensitive files (credentials, private keys, .gradle caches with tokens) might not be properly excluded. Fix: Verify .gitignore includes: *.keystore, *.jks, local.properties, .gradle/gradle.properties, *.pem, *.p8, and other credential/token files. - Low · Git Submodules Without Hash Verification —
.gitmodules. The .gitmodules file exists indicating use of git submodules, but without visibility into the content, there's no assurance of security best practices (pinned commits, signature verification). Fix: Use signed commits for submodule references. Pin submodules to specific commit hashes rather than branches. Regularly audit submodule sources and update their security.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.