RepoPilotOpen in app →

stephencelis/SQLite.swift

A type-safe, Swift-language layer over SQLite3.

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 2w ago
  • 13 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/stephencelis/sqlite.swift)](https://repopilot.app/r/stephencelis/sqlite.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/stephencelis/sqlite.swift on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: stephencelis/SQLite.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/stephencelis/SQLite.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 2w ago
  • 13 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 stephencelis/SQLite.swift repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/stephencelis/SQLite.swift.

What it runs against: a local clone of stephencelis/SQLite.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 stephencelis/SQLite.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 ≤ 42 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "stephencelis/SQLite.swift(\\.git)?\\b" \\
  && ok "origin remote is stephencelis/SQLite.swift" \\
  || miss "origin remote is not stephencelis/SQLite.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/SQLite/Core/Connection.swift" \\
  && ok "Sources/SQLite/Core/Connection.swift" \\
  || miss "missing critical file: Sources/SQLite/Core/Connection.swift"
test -f "Sources/SQLite/Typed/Expression.swift" \\
  && ok "Sources/SQLite/Typed/Expression.swift" \\
  || miss "missing critical file: Sources/SQLite/Typed/Expression.swift"
test -f "Sources/SQLite/Typed/Query.swift" \\
  && ok "Sources/SQLite/Typed/Query.swift" \\
  || miss "missing critical file: Sources/SQLite/Typed/Query.swift"
test -f "Sources/SQLite/Core/Statement.swift" \\
  && ok "Sources/SQLite/Core/Statement.swift" \\
  || miss "missing critical file: Sources/SQLite/Core/Statement.swift"
test -f "Sources/SQLite/Typed/Schema.swift" \\
  && ok "Sources/SQLite/Typed/Schema.swift" \\
  || miss "missing critical file: Sources/SQLite/Typed/Schema.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 42 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~12d)"
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/stephencelis/SQLite.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

SQLite.swift is a type-safe Swift wrapper around SQLite3 that eliminates SQL injection vulnerabilities and syntax errors at compile-time by building queries through a Swift expression DSL. It provides a chainable, lazy-executing query API with automatic type binding, so you write users.filter(id == 1).update(email <- "new@example.com") instead of manually constructing SQL strings and managing type conversions. Single-package structure: Sources/SQLite/Core/ contains the core types (Connection.swift, Statement.swift, Table/Expression builders, Errors.swift, Value.swift), with optional modules for Aggregation, Attach, and Pragmas in separate extension files. The playgrounds (SQLite.playground/) and test suite live in parallel. Swift Package Manager (Package.swift) and CocoaPods (SQLite.swift.podspec) are both supported.

👥Who it's for

Swift developers (iOS, macOS, tvOS, watchOS, visionOS, and Linux) who need embedded SQL database access without runtime SQL string errors. Specifically: mobile app developers avoiding database bugs before release, and backend engineers building Swift servers with SQLite persistence.

🌱Maturity & risk

Production-ready and actively maintained. The project has 8.9k+ GitHub stars, extensive test coverage across Sources/SQLite with CI via .github/workflows/build.yml, and Documentation/Index.md shows comprehensive feature parity with SQLite3. Recent commits and active issue response indicate ongoing support, though it's a single-maintainer project (stephencelis).

Low to moderate risk. Single maintainer (stephencelis) is the main concern for long-term continuity. The codebase has minimal external dependencies (wraps SQLite3 directly), reducing supply-chain risk. No breaking changes are evident in recent history based on CHANGELOG.md structure, but you should pin versions for stability. The Linux support (Documentation/Linux.md) has documented limitations.

Active areas of work

The project maintains active support for new Apple platforms (visionOS scheme visible in xcschemes/), WAL mode and journaling enhancements are complete, and SQLCipher support via SPM is available. No major refactors are evident; effort is focused on compatibility, documentation, and incremental platform support.

🚀Get running

git clone https://github.com/stephencelis/SQLite.swift.git
cd SQLite.swift
# For development with SPM:
swift build
swift test
# Or open the Xcode project:
open SQLite.xcodeproj

Daily commands: Development: swift build && swift test. To open playground demos: open SQLite.playground. To run on a specific platform: swift build -Xswiftc -target -Xswiftc arm64-apple-macos13.3 (example). macOS/iOS: open in Xcode and run schemes 'SQLite Mac' or 'SQLite iOS'.

🗺️Map of the codebase

  • Sources/SQLite/Core/Connection.swift — Core database connection management and statement execution—the primary entry point for all SQL operations.
  • Sources/SQLite/Typed/Expression.swift — Type-safe SQL expression builder enabling compile-time syntax validation and type checking for queries.
  • Sources/SQLite/Typed/Query.swift — Chainable, lazy-executing query DSL that builds and executes SELECT/INSERT/UPDATE/DELETE statements with type safety.
  • Sources/SQLite/Core/Statement.swift — Low-level SQLite statement wrapper handling parameter binding, execution, and result row iteration.
  • Sources/SQLite/Typed/Schema.swift — Type-safe schema definition and table creation API, foundational for structured database interactions.
  • Sources/SQLite/Core/Value.swift — Value type wrapping SQLite's dynamic typing system, enabling type-safe data coercion and storage.
  • Sources/SQLite/Typed/Operators.swift — SQL operator overloads and expression combinators (WHERE, AND, OR, comparisons) for query building.

🛠️How to make changes

Add a Custom SQL Function

  1. Define the Swift function logic that will be called from SQL (Sources/SQLite/Typed/CustomFunctions.swift)
  2. Register it with the Connection using createFunction() or createAggregate() (Sources/SQLite/Core/Connection.swift)
  3. Use it in type-safe expressions by wrapping in Expression<ReturnType> (Sources/SQLite/Typed/Expression.swift)

Add a New Type-Safe Table & Query

  1. Define table columns using Column<T> expressions in Schema.swift pattern (Sources/SQLite/Typed/Schema.swift)
  2. Build queries using Query.from(table).select().where() chainable API (Sources/SQLite/Typed/Query.swift)
  3. Use Expression operators for WHERE clauses and type-safe filtering (Sources/SQLite/Typed/Operators.swift)
  4. Execute via connection.prepare().run()/scalar()/allRows() (Sources/SQLite/Core/Statement.swift)

Implement Full-Text Search on a Table

  1. Create an FTS5 virtual table using create() on a Connection with FTS5 module loaded (Sources/SQLite/Extensions/FTS5.swift)
  2. Define FTS5 columns and configure ranking, content tables, and trigger logic (Sources/SQLite/Extensions/FTS5.swift)
  3. Query using MATCH operator with type-safe Expression syntax (Sources/SQLite/Typed/Expression.swift)

Perform Safe Schema Migration

  1. Read current schema using Connection.schema property to inspect existing tables/columns (Sources/SQLite/Schema/SchemaReader.swift)
  2. Use SchemaChanger API to safely modify columns, rename tables, or add indexes (Sources/SQLite/Schema/SchemaChanger.swift)
  3. Execute within a transaction for atomicity: connection.transaction { try changeSchema() } (Sources/SQLite/Core/Connection.swift)

🔧Why these technologies

  • Swift only (no Objective-C interop) — Pure-Swift layer ensures compile-time type safety and seamless integration with modern Swift features (Codable, async/await, generics)
  • Expression builder with operator overloading — Enables intuitive, SQL-like syntax at compile time (e.g., user.id == 5) while preventing SQL injection and syntax errors
  • Lazy-executing queries — Defers SQL compilation and execution until terminal operation, reducing overhead and enabling query optimization
  • Generic Column<T> and Expression<T> — Enforces type safety across the entire query pipeline—mismatched types fail at compile time, not runtime
  • Low-level Statement wrapper over sqlite3_stmt — Provides fine-grained control over parameter binding, result iteration, and memory management while exposing C API cleanly

⚖️Trade-offs already made

  • No ORM/Model generation—manual table definitions

    • Why: Keeps library lightweight, avoids code generation, and gives developers explicit control
    • Consequence: Slightly more boilerplate than some ORMs, but higher transparency and easier debugging
  • Type-safe queries require upfront Column<T> declarations

    • Why: Enables compile-time validation and prevents type mismatches
    • Consequence: Cannot execute completely dynamic SQL; queries must be structured at compile time
  • Lazy Result evaluation instead

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

  1. Type inference surprises: Expression<String> vs Expression<String?> are distinct types; mixing them in filters requires explicit casting. 2. Thread safety: Connection is NOT thread-safe by default; use serial DispatchQueues or connection pooling for concurrent access. 3. SQLite memory mode: default is file-based; :memory: databases are fully in-process but lost on close. 4. FTS column metadata: FTS tables require explicit schema definition; auto-mirroring from regular table schema is not automatic. 5. Custom collations: if you register custom collations in C, they must remain valid for the Connection lifetime.

🏗️Architecture

💡Concepts to learn

  • Type-safe SQL expression builders — This repo's core innovation: using Swift's type system and operator overloading to construct SQL at compile-time, preventing injection and syntax errors impossible in string-based queries
  • Lazy query evaluation — Queries (Table.filter(), select()) build expression trees without executing SQL until .prepare() or .run() are called, enabling composition and optimization
  • SQLite affinity and type coercion — SQLite uses dynamic affinity (TEXT, NUMERIC, INTEGER, REAL, BLOB); SQLite.swift's Value.swift layer maps this to Swift's static types via Binding protocol
  • Prepared statements and parameter binding — Statement.swift wraps sqlite3_stmt for efficient parameterized queries; prevents SQL injection and enables statement reuse and caching
  • Write-Ahead Logging (WAL) mode — SQLite's WAL mode (enabled via Connection constructor and walCheckpoint API) improves concurrency and recovery; documented in Connection+Pragmas.swift
  • Full-text search (FTS5) — SQLite's FTS virtual table allows efficient text indexing and phrase queries; SQLite.swift provides a Table builder for FTS without raw SQL
  • Operator overloading for DSLs — SQLite.swift overloads <-, ==, &&, || to build filters and updates as expressions; foundational to its fluent API design
  • groue/GRDB.swift — Alternative type-safe SQLite wrapper with emphasis on Codable integration and reactive query streams; more feature-rich but higher learning curve
  • vapor/fluent — ORM for Vapor web framework; builds on SQLite.swift patterns for server-side Swift and adds migrations/relations
  • pointfreeco/swift-tagged — Provides NewType-like safety primitives used in advanced SQLite.swift codebases to prevent id/foreign-key mix-ups
  • apple/swift-async-algorithms — Async/await utilities applicable to wrapping SQLite.swift queries as AsyncSequence for concurrent app integration
  • stephencelis/SQLite.swift-ReactiveCocoa — Optional reactive binding layer (archived but reference) showing patterns for signal-driven database updates

🪄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 unit tests for Sources/SQLite/Schema/SchemaReader.swift

The schema module (SchemaReader.swift, SchemaChanger.swift, SchemaDefinitions.swift) provides critical functionality for querying and migrating database schemas, but there's no visible dedicated test file in the repository structure. Given the complexity of schema introspection and the potential for bugs in ALTER TABLE operations, this needs robust test coverage including edge cases like constraint validation, column modifications, and table renaming.

  • [ ] Create Tests/SQLite/Schema/SchemaReaderTests.swift with test cases for reading tables, columns, indexes, and constraints
  • [ ] Add test cases for SchemaChanger.swift covering table renames, column additions/modifications, and constraint handling
  • [ ] Test schema reader behavior with SQLite pragma statements (table_info, index_info, foreign_key_list)
  • [ ] Verify tests run in build.yml GitHub Actions workflow

Add visionOS platform CI workflow in .github/workflows/build.yml

The project explicitly supports visionOS (see SQLite visionOS.xcscheme in xcshareddata), but the GitHub Actions build.yml likely only tests macOS, iOS, tvOS, and watchOS. visionOS is an emerging platform with unique constraints, and native CI validation would catch platform-specific regressions early. This is a low-effort, high-value addition given the scheme already exists.

  • [ ] Examine current .github/workflows/build.yml to identify existing platform test matrix
  • [ ] Add visionOS to the build matrix (likely requires Xcode 15+ runner)
  • [ ] Test build against SQLite visionOS.xcscheme
  • [ ] Verify workflow runs successfully on PR

Document and add comprehensive tests for Sources/SQLite/Extensions/FTS5.swift integration

Full-text search (FTS5) is mentioned as a key feature in README.md, but there's no visible FTS5-specific documentation in Documentation/ folder and likely minimal test coverage. FTS5 has complex ranking, tokenization, and query syntax that often surprises users. Adding dedicated documentation and tests would reduce support burden and improve adoption.

  • [ ] Create Documentation/FullTextSearch.md covering FTS5 table creation, ranking functions, and query syntax with examples
  • [ ] Create Tests/SQLite/Extensions/FTS5Tests.swift with test cases for: table creation, basic searches, phrase queries, MATCH syntax, custom tokenizers
  • [ ] Add test cases for FTS5-specific features like bm25() ranking and virtual table quirks
  • [ ] Cross-reference FTS5 documentation in main Documentation/Index.md

🌿Good first issues

  • Add type-safe builder for ATTACH DATABASE statements: the Connection+Attach.swift exists but lacks a fluent DSL like try db.attach("other.db", as: "other") — could mirror the table builder pattern.
  • Document best practices for prepared statement reuse in Connection: Statement.swift supports reuse via sqlite3_reset, but no guidance exists in Documentation/Index.md on when/how to cache for performance.
  • Add missing Codable support example to playground: SQLite.playground/Contents.swift shows manual mapping but not how to encode/decode with Foundation's Codable for rapid prototyping.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • a4b606f — Merge pull request #1359 from dyikai/master (jberkel)
  • 4d991a4 — Merge pull request #1360 from stephencelis/fix-tests (jberkel)
  • ee2db92 — Disable tuist test (jberkel)
  • 970f6e2 — Update homebrew (jberkel)
  • 991c1b2 — Fix build (jberkel)
  • 6e3d402 — Add WAL journal mode support (dyikai)
  • 3771f4a — Merge pull request #1358 from stephencelis/dependabot/bundler/addressable-2.9.0 (Branden Russell)
  • 2a7f315 — Bump addressable from 2.8.8 to 2.9.0 (dependabot[bot])
  • 964c300 — Merge pull request #1353 from stephencelis/prepare-0.16.0 (jberkel)
  • a26a5f2 — Merge pull request #1354 from R4N/sqlcipher-linker-settings (jberkel)

🔒Security observations

SQLite.swift demonstrates good security fundamentals through its type-safe SQL expression builder design, which mitigates common SQL injection risks at the language level. However, the project has moderate security concerns: (1) potential SQL injection through raw query APIs if misused, (2) dependency management gaps for SQLCipher integration, (3) missing security documentation and guidelines, and (4) limited visibility into security-focused testing. The codebase is well-structured and maintained, but would benefit from explicit security hardening documentation, automated dependency scanning, and enhanced security testing. No hardcoded credentials or critical infrastructure misconfigurations were identified.

  • High · SQL Injection Risk in Query Building — Sources/SQLite/Core/Statement.swift, Sources/SQLite/Core/Connection.swift, Sources/SQLite/Typed/CustomFunctions.swift. While the codebase provides type-safe SQL expression builders, the presence of raw SQL execution capabilities (Statement.swift, Connection.swift) combined with custom function support (CustomFunctions.swift) could allow SQL injection if developers bypass the type-safe layer and pass unsanitized user input directly to raw query methods. Fix: Ensure all documentation and examples strongly emphasize using parameterized queries and the type-safe expression builders. Add runtime validation warnings when raw SQL is used. Provide security guidelines in CONTRIBUTING.md and documentation.
  • Medium · Potential Cipher Extension Security Dependency — Sources/SQLite/Extensions/Cipher.swift, SQLite.swift.podspec, Package.swift. The codebase includes optional SQLCipher support (Sources/SQLite/Extensions/Cipher.swift) which relies on external encryption. If SQLCipher dependency is not properly pinned or validated, it could introduce security vulnerabilities through supply chain attacks or outdated cryptographic implementations. Fix: Implement strict version pinning for SQLCipher dependency. Document minimum version requirements with known security patches. Add security advisories to CHANGELOG.md for dependency updates. Consider adding dependency scanning in CI/CD pipeline.
  • Medium · Missing SBOM and Dependency Tracking — Package.swift, SQLite.swift.podspec. No Software Bill of Materials (SBOM) or detailed dependency manifest is visible. The project depends on SQLite3 system library and potentially SQLCipher, but there's no clear documentation of all transitive dependencies and their security status. Fix: Generate and maintain an SBOM using tools like SPDX. Document all direct and transitive dependencies with versions. Implement automated dependency vulnerability scanning in CI/CD pipeline (using tools like Dependabot or Snyk).
  • Medium · Blob Handling Security Considerations — Sources/SQLite/Core/Blob.swift. The Blob.swift module handles binary data. If not properly managed, large blobs or malformed blob data could lead to memory exhaustion or buffer overflow vulnerabilities, especially when reading into memory without size constraints. Fix: Implement maximum size limits for blob operations. Add memory-safe bounds checking. Document blob size limitations in API documentation. Add tests for large blob handling and memory usage.
  • Low · Limited Security-Focused Documentation — Documentation/ folder. While the project has comprehensive documentation, there's no dedicated security guidelines document (SECURITY.md) for developers on how to use the library securely and report vulnerabilities. Fix: Create SECURITY.md file documenting: secure coding practices when using SQLite.swift, how to report security vulnerabilities, secure parameter binding patterns, and common pitfalls to avoid. Include examples of secure vs. insecure usage.
  • Low · No Security-Focused Testing Visible — Tests/. While tests exist, the provided file structure doesn't show dedicated security or injection testing modules (e.g., test cases for SQL injection prevention, parameter binding validation). Fix: Add dedicated security test suite covering: SQL injection prevention, parameter binding validation, cipher functionality verification, and edge cases with malformed input. Consider adding fuzzing tests for query builders.

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.