RepoPilotOpen in app →

groue/GRDB.swift

A toolkit for SQLite databases, with a focus on application development

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 7w ago
  • 7 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 74% of recent commits

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.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/groue/grdb.swift)](https://repopilot.app/r/groue/grdb.swift)

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/groue/grdb.swift on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: groue/GRDB.swift

Generated by RepoPilot · 2026-05-10 · 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:

  1. 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.
  2. 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.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/groue/GRDB.swift 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 the board

  • Last commit 7w ago
  • 7 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 74% of recent commits

<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 groue/GRDB.swift repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/groue/GRDB.swift.

What it runs against: a local clone of groue/GRDB.swift — 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 groue/GRDB.swift | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 82 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>groue/GRDB.swift</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of groue/GRDB.swift. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/groue/GRDB.swift.git
#   cd GRDB.swift
#
# 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 groue/GRDB.swift and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "groue/GRDB.swift(\\.git)?\\b" \\
  && ok "origin remote is groue/GRDB.swift" \\
  || miss "origin remote is not groue/GRDB.swift (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Sources/GRDB/Core/Database.swift" \\
  && ok "Sources/GRDB/Core/Database.swift" \\
  || miss "missing critical file: Sources/GRDB/Core/Database.swift"
test -f "Sources/GRDB/Core/DatabasePool.swift" \\
  && ok "Sources/GRDB/Core/DatabasePool.swift" \\
  || miss "missing critical file: Sources/GRDB/Core/DatabasePool.swift"
test -f "Sources/GRDB/QueryInterface/QueryInterface.swift" \\
  && ok "Sources/GRDB/QueryInterface/QueryInterface.swift" \\
  || miss "missing critical file: Sources/GRDB/QueryInterface/QueryInterface.swift"
test -f "Sources/GRDB/Record/Record.swift" \\
  && ok "Sources/GRDB/Record/Record.swift" \\
  || miss "missing critical file: Sources/GRDB/Record/Record.swift"
test -f "Sources/GRDB/FTS/FTS.swift" \\
  && ok "Sources/GRDB/FTS/FTS.swift" \\
  || miss "missing critical file: Sources/GRDB/FTS/FTS.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 82 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~52d)"
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/groue/GRDB.swift"
  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).

</details>

TL;DR

GRDB.swift is a SQLite database toolkit for Swift that lets iOS/macOS developers persist application data without writing raw SQL. It provides type-safe query builders, automatic schema migrations, database observation for reactive updates, and robust multi-threaded concurrency via SQLite WAL mode—bridging the gap between high-level ORM convenience and low-level SQLite power. Single-package SPM structure: core GRDB library in Swift (7.7MB codebase), supplemented by Documentation/ with feature guides (Combine.md, Concurrency.md, Associations.md), DemoApps/ with runnable examples (GRDBDemo.xcodeproj), and build tooling (Makefile, CI workflows). Tests likely in Tests/ directory (not shown but standard for SPM).

👥Who it's for

Swift/iOS developers (iOS 13+, macOS 10.15+) building production apps that need persistent local storage. They range from developers wanting an ORM-like abstraction layer to advanced SQLite users leveraging custom SQL and pragmas for performance tuning.

🌱Maturity & risk

Highly mature and production-ready. Active development since 2015 with 7.10.0 released February 2026, comprehensive CI setup (.github/workflows/CI.yml), extensive documentation in Documentation/, demo apps, and a large Swift community presence. Actively maintained with Swift 6.1 support.

Low risk: established project with maintained CI, versioned releases (see CHANGELOG.md), and strong community. Single maintainer (groue) is a known risk vector, but the library is stable enough that infrequent updates are acceptable. No obvious breaking changes in recent releases based on migration guide structure.

Active areas of work

Active development visible through version 7.10.0 (Feb 2026), Swift 6.1 adoption, concurrency improvements (Concurrency.md documented), and ongoing database observation enhancements. Dependabot enabled (.github/dependabot.yml) for dependency tracking.

🚀Get running

git clone https://github.com/groue/GRDB.swift.git && cd GRDB.swift && open .swiftpm/xcode/package.xcworkspace (Xcode 16.3+) or use Swift Package Manager directly: swift build

Daily commands: open .swiftpm/xcode/package.xcworkspace in Xcode 16.3+ and build, or: swift build for CLI. Run demo app: open Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj

🗺️Map of the codebase

  • Sources/GRDB/Core/Database.swift — Entry point for all database operations; defines the Database class that manages SQLite connections and transactions
  • Sources/GRDB/Core/DatabasePool.swift — Implements concurrent read/write access patterns; critical for understanding GRDB's concurrency model
  • Sources/GRDB/QueryInterface/QueryInterface.swift — Core query builder abstraction; foundational for understanding how GRDB constructs SQL queries
  • Sources/GRDB/Record/Record.swift — Base protocol for ORM-style record types; essential for understanding how models interact with the database
  • Sources/GRDB/FTS/FTS.swift — Full-text search implementation; demonstrates integration of SQLite FTS5 features
  • Documentation/README.md — Comprehensive guide to GRDB features, architecture patterns, and best practices
  • CHANGELOG.md — Version history and breaking changes; essential for understanding API evolution

🛠️How to make changes

Add a new Record model

  1. Create a struct or class conforming to Codable and PersistableRecord (or MutablePersistableRecord for mutability) (Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/Models/Player.swift)
  2. Implement databaseTableName() and define column mappings using CodingKeys if needed (Sources/GRDB/Record/Record.swift)
  3. Add migration in AppDatabase to create the table schema (Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/AppDatabase.swift)
  4. Define associations (belongsTo, hasMany, etc.) using the Association API in your record type (Sources/GRDB/Record/Association.swift)

Add a database query

  1. Use the query interface builder starting from Table("tableName") or Model.all() (Sources/GRDB/QueryInterface/QueryInterface.swift)
  2. Chain filter(), select(), order(), limit() and other modifiers to compose the query (Sources/GRDB/QueryInterface/TableRequest.swift)
  3. Execute with fetch(), fetchOne(), fetchAll(), or count() on a database reader (Sources/GRDB/Core/Database.swift)
  4. For complex SQL, use raw SQL with safe interpolation via SQL string interpolation (Sources/GRDB/QueryInterface/SQLInterpolation.swift)

Observe database changes reactively

  1. For Combine: use db.publisher(request) or Model.all().publisher(in: db) to get a Publisher<[Model], Never> (Sources/GRDB/Combine/Combine.swift)
  2. Alternatively, use FetchedRecordsController to maintain a sorted/filtered list with change notifications (Sources/GRDB/Core/FetchedRecordsController.swift)
  3. Subscribe to the publisher or controller delegate in your view model or SwiftUI @StateObject (Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerListModel.swift)

Set up migrations

  1. Create Migration instances defining each schema version with identifier and migrations block (Sources/GRDB/Migration/Migration.swift)
  2. Register migrations in order using migrator.register() in AppDatabase setup (Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/AppDatabase.swift)
  3. Call migrator.migrate(db) during app startup to run pending migrations (Sources/GRDB/Migration/Migrations.swift)

🔧Why these technologies

  • SQLite — Embedded, ACID-compliant relational database with zero configuration; ideal for mobile and desktop apps where external server dependency is undesirable
  • Swift Concurrency (async/await, actors) — Modern structured concurrency model for safe database access; prevents data races in multi-threaded environments
  • Combine Publishers — Reactive database observations integrated with SwiftUI's Observable protocol; enables declarative UI updates on data changes
  • Codable — Swift's native serialization protocol for transparent mapping between records and database rows
  • FTS5 (Full-Text Search) — SQLite's built-in full-text search index for performant text queries without external search engines

⚖️Trade-offs already made

  • DatabasePool with reader/writer separation vs. single DatabaseQueue

    • Why: Support concurrent read transactions while serializing writes prevents lock contention and improves read throughput
    • Consequence: Added complexity in managing writer serialization; eventual consistency for read-your-writes patterns
  • Type-safe query builder (QueryInterface) vs. raw SQL only

    • Why: Catches SQL errors at compile-time and improves IDE autocomplete without sacrificing expressive power
    • Consequence: Query builder learning curve; some advanced SQL features require raw SQL fallback
  • Synchronous fetch operations by default with opt-in async

    • Why: Simpler API for common cases; async/await added gradually to support modern concurrency
    • Consequence: Must explicitly use async APIs to avoid blocking threads; older code may not leverage concurrency
  • Eager loading of associations vs. lazy loading

    • Why: Explicit control over N+1 queries via preloadAssociations prevents hidden performance pitfalls
    • Consequence: Requires conscious query planning; developers must request associations explicitly

🚫Non-goals (don't propose these)

  • Does not provide automatic query optimization or execution planning beyond SQLite

🪤Traps & gotchas

SQLite version constraint: requires SQLite 3.20.0+ (check via sqlite3 --version on target device). WAL mode requires specific app group container setup (see Documentation/AppGroupContainers.md). Thread-safety: GRDB enforces serial access to DatabaseQueue but concurrent access to DatabasePool—mixing these incorrectly causes crashes. Codable decoding: custom Decodable implementations may not work without FetchableRecord conformance. Memory: observe transactions can retain strong references; use weak self in observation closures to avoid cycles.

🏗️Architecture

💡Concepts to learn

  • realm/realm-swift — Alternative object-oriented persistence layer; users often compare GRDB's SQL-first approach vs Realm's schema-driven ORM
  • apple/swift-driver — Shares Swift concurrency patterns (async/await, actors) that GRDB implements for safe database access
  • pointfreeco/swift-composable-architecture — Popular state management framework often paired with GRDB for reactive database observations in Redux-style apps
  • firebase/firebase-ios-sdk — Competitor for persistence in iOS apps; GRDB users choose it for offline-first local-only scenarios
  • groue/Combine — Complementary Combine reactive patterns guide; GRDB's Combine.md integrates with Publisher/Subscriber abstractions

🪄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 tests for Concurrency.md documented patterns

The Documentation/Concurrency.md file exists but there's no evidence of dedicated test suite validating the concurrency patterns it documents. GRDB.swift targets modern Swift with async/await support, making this critical. A new contributor could create Tests/GRDBTests/Concurrency/ with tests for actor-isolated database access, MainActor integration, and concurrent read scenarios.

  • [ ] Review Documentation/Concurrency.md to identify all documented patterns
  • [ ] Create Tests/GRDBTests/Concurrency/ConcurrencyTests.swift
  • [ ] Add tests for actor-isolated database instances and thread-safety
  • [ ] Add tests for MainActor-annotated database operations
  • [ ] Add tests for concurrent read vs write scenarios
  • [ ] Ensure tests validate documented async/await examples work correctly

Add integration tests for FTS5 Tokenizers documented in Documentation/FTS5Tokenizers.md

FTS5Tokenizers.md documents a feature but specific integration tests validating custom tokenizers with real queries appear to be missing. This is a specialized feature that needs thorough testing given SQLite's complexity.

  • [ ] Review Documentation/FTS5Tokenizers.md to extract all tokenizer examples
  • [ ] Create Tests/GRDBTests/FullTextSearch/FTS5TokenizersTests.swift
  • [ ] Add tests for built-in tokenizers (porter, unicode61, etc.)
  • [ ] Add tests for custom tokenizer registration and usage
  • [ ] Add tests for tokenizer configuration with special characters
  • [ ] Add tests for tokenizer edge cases (empty strings, special encoding)

Add CI workflow for testing on multiple Swift versions (5.9, 6.0, 6.1)

README shows support for Swift 6.1, but .github/workflows/CI.yml likely only tests one version. The repo should validate compatibility across the Swift versions it claims to support, especially given breaking changes between major Swift versions.

  • [ ] Review current .github/workflows/CI.yml configuration
  • [ ] Expand matrix to include swift-version: ['5.9', '6.0', '6.1']
  • [ ] Add separate test job for each Swift version
  • [ ] Validate Package.swift swiftLanguageVersions if version-specific code exists
  • [ ] Test both Debug and Release build configurations for each Swift version
  • [ ] Document any version-specific workarounds in CI config comments

🌿Good first issues

  • Add documentation examples for CommonTableExpressions.md showing practical recursive CTE patterns (docs exist but lack runnable code snippets like GRDBDemo provides)
  • Extend GRDBDemo app with a many-to-many association example (currently has Player model but lacks full relationship demo matching AssociationsBasics.md)
  • Create typed migration builder tests—Documentation/Migrations exists but repo structure suggests test coverage for custom migration DSL improvements could be broader

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 36e30a6 — Merge branch 'development' (groue)
  • 368514c — v7.10.0 (groue)
  • 21b1322 — Fix Swiftlint warnings (groue)
  • 819f457 — Merge pull request #1852 from groue/dev/upsert-strategy (groue)
  • 7b01c9b — Let the user choose between the two possible update strategies for upsert (groue)
  • 7f9d150 — Merge pull request #1850 from swift-everywhere/platform-fixes (groue)
  • 1456763 — Android and Windows platform import/conditional accommodation (marcprux)
  • 205387d — Merge pull request #1849 from marcprux/patch-1 (groue)
  • c8f0328 — Add Sendable conformance to DispatchQueueExecutor for Android and Windows (marcprux)
  • e784b10 — Merge pull request #1845 from R4N/sqlcipher-spm-upstream (groue)

🔒Security observations

GRDB.swift is a mature SQLite toolkit with a reasonable security posture. The primary concerns are typical of database libraries: SQL injection risks from improper query construction and the need for clear security guidance to users. The codebase appears well-maintained with proper version control and CI/CD practices. However, the lack of an explicit security policy, limited visibility into supply chain security (dependencies), and absence of documented security scanning in the CI/CD pipeline are moderate concerns. The library's design with parameterized query support and abstraction layers is security-conscious, but users must follow best practices. Recommendations include establishing a security.md policy, implementing automated security scanning, and enhancing documentation with security guidelines.

  • Medium · SQLite SQL Injection Risk in Database Abstraction Layer — Core GRDB library - database query execution layer. GRDB.swift is a SQLite toolkit that provides query building and execution. While the library appears to use parameterized queries, any dynamic SQL construction in user code or improper use of raw query APIs could expose applications to SQL injection. The presence of raw SQL execution capabilities requires careful validation of all inputs. Fix: Ensure all user-facing documentation emphasizes parameterized queries and prepared statements. Audit code paths that accept raw SQL strings and validate all external inputs. Consider adding security warnings in documentation about SQL injection risks.
  • Low · Potential Information Disclosure via Demo Applications — Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/. The repository contains demo applications (GRDBDemo) in the Documentation folder with example databases and models. If these examples include realistic sensitive data or hardcoded credentials, they could serve as a template for insecure development patterns. Fix: Review demo application code to ensure no sensitive data examples are included. Use placeholder/sanitized data in examples. Include security best practices in demo code comments.
  • Low · No Explicit Security Policy File — Repository root. While CODE_OF_CONDUCT.md exists, there is no visible SECURITY.md or security policy file for responsible disclosure of vulnerabilities. This makes it harder for security researchers to report issues privately. Fix: Create a SECURITY.md file that includes: responsible disclosure policy, supported versions, security contact information, and expected response times for security reports. Consider adding security scanning to CI/CD.
  • Low · CI/CD Configuration Lacks Explicit Security Scanning — .github/workflows/CI.yml. The .github/workflows/CI.yml file is present but cannot be fully analyzed from the provided structure. Without visibility into the CI/CD pipeline, security scanning (dependency checks, SAST) may not be enforced. Fix: Implement automated security scanning in CI/CD including: dependency vulnerability scanning (e.g., Swift Package Index security reports), static analysis tools, and automated testing. Consider using tools like SwiftLint with security rules.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.