RepoPilotOpen in app →

jmoiron/sqlx

general purpose extensions to golang's database/sql

Mixed

Stale — last commit 2y ago

worst of 4 axes
Use as dependencyMixed

last commit was 2y ago; no tests detected…

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-isMixed

last commit was 2y ago; no CI workflows detected

  • 29+ active contributors
  • MIT licensed
  • Stale — last commit 2y ago
Show 3 more →
  • Concentrated ownership — top contributor handles 57% of recent commits
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days; add a test suite
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

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 "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/jmoiron/sqlx?axis=fork)](https://repopilot.app/r/jmoiron/sqlx)

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/jmoiron/sqlx on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: jmoiron/sqlx

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:

  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/jmoiron/sqlx 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

WAIT — Stale — last commit 2y ago

  • 29+ active contributors
  • MIT licensed
  • ⚠ Stale — last commit 2y ago
  • ⚠ Concentrated ownership — top contributor handles 57% of recent commits
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

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

What it runs against: a local clone of jmoiron/sqlx — 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 jmoiron/sqlx | 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 ≤ 662 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jmoiron/sqlx(\\.git)?\\b" \\
  && ok "origin remote is jmoiron/sqlx" \\
  || miss "origin remote is not jmoiron/sqlx (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 "sqlx.go" \\
  && ok "sqlx.go" \\
  || miss "missing critical file: sqlx.go"
test -f "bind.go" \\
  && ok "bind.go" \\
  || miss "missing critical file: bind.go"
test -f "named.go" \\
  && ok "named.go" \\
  || miss "missing critical file: named.go"
test -f "reflectx/reflect.go" \\
  && ok "reflectx/reflect.go" \\
  || miss "missing critical file: reflectx/reflect.go"
test -f "sqlx_context.go" \\
  && ok "sqlx_context.go" \\
  || miss "missing critical file: sqlx_context.go"

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

sqlx is a Go library that extends the standard database/sql package with convenient methods for marshaling query results directly into structs, maps, and slices, plus named parameter support and prepared statement binding. It wraps sql.DB, sql.Tx, sql.Stmt, and related types while preserving their interfaces, making it a drop-in enhancement for Go database applications that need less boilerplate around row scanning. Single-package monorepo structure: core sqlx functions in root-level files (sqlx.go, named.go, bind.go), context-aware variants in *_context.go files, reflection utilities factored into a reflectx/ subpackage, and SQL type utilities in a types/ subpackage. Tests are colocated with source (sqlx_test.go next to sqlx.go), and a Makefile handles common tasks.

👥Who it's for

Go backend engineers and data access layer developers who want to eliminate repetitive rows.Scan() boilerplate and use struct field tags (like db:"column_name") to automatically unmarshal database rows, especially those working with SQL queries that benefit from named parameters instead of positional ? placeholders.

🌱Maturity & risk

Production-ready and actively maintained. The library has solid test coverage (separate *_test.go files in the root and subdirectories), CircleCI CI/CD configured in .circleci/config.yml, and recent changes documented (v1.3.0 features like DB.Connx() and BindDriver() are current). Requires Go 1.10+, indicating long-term stability focus.

Low risk for production use. Dependencies are minimal and stable—only three driver packages (go-sql-driver/mysql, lib/pq, mattn/go-sqlite3)—and the codebase is purely Go with no external runtime dependencies. Single maintainer (jmoiron) is a known risk factor, but the API surface is stable and the library has been widely adopted. No breaking changes are mentioned in recent releases.

Active areas of work

Recent development added context support (sqlx_context.go, named_context.go, named_context_test.go), the ability to control driver-specific bind variable syntax via BindDriver(), batch insertion support for []map[string]interface{}, and performance optimizations in sqlx.In(). The v1.3.0 release introduced DB.Connx() to work with the sql.Conn pooling interface added in Go 1.10.

🚀Get running

git clone https://github.com/jmoiron/sqlx.git
cd sqlx
go mod download
make test

Daily commands: This is a library, not a runnable application. To verify the build: make test runs the test suite against configured databases. Individual test files (sqlx_test.go, bind_test.go, named_test.go, etc.) can be run with go test ./...

🗺️Map of the codebase

  • sqlx.go — Core entry point defining DB, TX, Rows, and Stmt wrapper types that extend database/sql with Get/Select functionality.
  • bind.go — Implements named parameter binding and query argument interpolation, essential for the library's parameter substitution feature.
  • named.go — Handles named query parsing and execution without context support, a foundational pattern for the library's query model.
  • reflectx/reflect.go — Core reflection utilities for mapping database columns to struct fields and marshaling rows into Go types.
  • sqlx_context.go — Context-aware variants of core DB operations (QueryContext, ExecContext, etc.) required for modern Go database patterns.
  • types/types.go — Custom type wrappers (NullInt64, NullString, JSONText) for safe nullable and JSON column handling.
  • go.mod — Declares minimal external dependencies (MySQL, PostgreSQL, SQLite drivers) and Go version baseline.

🧩Components & responsibilities

  • sqlx.DB / sqlx.TX / sqlx.Stmt (Go reflection, database/sql) — Wrapper types that extend database/sql with Get/Select convenience methods; manage underlying sql.DB/TX/Stmt handles.
    • Failure mode: If underlying driver connection fails, queries return driver errors; wrapper is transparent to error handling.
  • bind (Parameter Binding Layer) (String parsing, regex) — Parses named parameters (:name) and converts to dialect-specific positional syntax; interpolates arguments into query.
    • Failure mode: Malformed named queries (unmatched colons, missing args) cause bind errors; passed through to caller.
  • reflectx (Reflection & Mapping) (Go reflect package) — Inspects Go struct tags (db:"columnname"), discovers fields, matches database columns, and scans Rows into struct instances.
    • Failure mode: Type mismatch (e.g., string column to int field) causes sql.Scan error; missing columns silently map to zero values.
  • types (Custom Nullable Types) (Go interface conformance, JSON marshaling) — Provides NullInt64, NullString, NullTime, JSONText with sql.Scanner and driver.Valuer implementations for NULL-safe operations.
    • Failure mode: Invalid JSON in JSONText field causes Scan error; NULL values safely populate Valid=false.

🔀Data flow

  • Application Codesqlx.DB — User calls Get/Select with context, query string, struct pointer, and named args
  • sqlx.DBbind — Query string and args passed to Bind() to interpolate named parameters into driver-specific syntax
  • bindsqlx. — undefined

🛠️How to make changes

Add support for a new database driver

  1. Add driver to go.mod dependencies and import in test files (go.mod)
  2. Add dialect-specific binding tests in bind_test.go to ensure named parameter syntax matches the new driver (bind_test.go)
  3. If driver has unique type mapping needs, extend types/types.go with custom Scanner/Valuer implementations (types/types.go)
  4. Test end-to-end with sqlx_test.go to verify Get/Select work correctly on new driver (sqlx_test.go)

Add a new custom nullable type

  1. Define struct type in types/types.go with Valid flag and SQL driver Scanner/Valuer methods (types/types.go)
  2. Write unit tests in types/types_test.go covering nil, zero, and valid values (types/types_test.go)
  3. Document usage in types/README.md with examples (types/README.md)

Add a new query convenience method to DB/TX

  1. Implement method on sqlx.DB or sqlx.TX in sqlx.go following Get/Select pattern (sqlx.go)
  2. Add context-aware variant in sqlx_context.go with ...Context suffix (sqlx_context.go)
  3. Add integration tests in sqlx_test.go and sqlx_context_test.go (sqlx_test.go)

Improve struct-to-column mapping behavior

  1. Understand current tag parsing and field discovery in reflectx/reflect.go (reflectx/reflect.go)
  2. Add test cases in reflectx/reflect_test.go for new mapping scenarios (nested structs, custom types, etc.) (reflectx/reflect_test.go)
  3. Implement mapping logic in reflectx/reflect.go, then verify with sqlx_test.go Get/Select tests (reflectx/reflect.go)

🔧Why these technologies

  • Go reflection (reflect package + custom reflectx) — Enables automatic marshaling of arbitrary database rows into user-defined structs without code generation at runtime.
  • database/sql driver interface extensions — Maintains 100% compatibility with Go's standard database/sql by wrapping rather than replacing, allowing gradual adoption.
  • Named parameter interpolation (bind.go) — Provides ergonomic alternative to positional ? or $N parameters; handles dialect differences (MySQL ?, PostgreSQL $1, SQLite ?) transparently.
  • Support for multiple SQL drivers (MySQL, PostgreSQL, SQLite) — Library must abstract over driver-specific syntax and type handling to serve as a general-purpose database/sql extension.

⚖️Trade-offs already made

  • Reflection-based marshaling instead of code generation (sqlc-style)

    • Why: Avoid build-time complexity and tool overhead; enable dynamic query execution.
    • Consequence: Slightly lower runtime performance (~5–10%) but much simpler integration and easier debugging; no DSL or code generator required.
  • Leave underlying sql.DB/TX/Rows/Stmt interfaces untouched; compose rather than inherit

    • Why: Ensure sqlx types are a strict superset of database/sql, allowing seamless drop-in replacement.
    • Consequence: Must wrap types and duplicate some boilerplate methods, but zero breaking changes or surprise behavior.
  • Named parameters as syntactic sugar over positional arguments via bind layer

    • Why: Avoid modifying SQL string semantics; keep queries compatible with raw database/sql.
    • Consequence: Slight overhead in query pre-processing, but no dependency on custom SQL parser or type system.
  • Custom nullable types (NullInt64, etc.) in types/ subpackage rather than in core

    • Why: Keep core lean; users opt-in to extended type support only if needed.
    • Consequence: Requires extra import; not all nullable use cases covered by types/ alone.

🚫Non-goals (don't propose these)

  • Does not provide query builder or ORM abstraction—focus is on mapping and convenience, not schema or relationship management.
  • Does not handle database migrations or schema versioning.
  • Does not provide connection pooling beyond what database/sql offers.
  • Does not support non-SQL databases or custom SQL dialects beyond MySQL, PostgreSQL, SQLite.
  • Does not provide query validation or static type checking at compile time.

🪤Traps & gotchas

Named parameters require explicit :name syntax; positional ? placeholders are ignored when using Named(). Driver binding type is auto-detected from dsl.Open() but may fail for custom/wrapped drivers—use BindDriver() to register manually. The reflectx tag parser requires exact field names and case sensitivity; misspelled or missing tags silently skip columns. Tests expect SQLX_* environment variables or local SQLite for CI—see .circleci/config.yml for the actual test database setup. Column name ambiguity from duplicate names in joins is a known limitation mentioned in README; use AS aliases or manual Scan().

🏗️Architecture

💡Concepts to learn

  • uptrace/bun — Modern Go ORM built on sqlx principles but adds a query builder and relationships; alternative if you need more abstraction
  • upper/db — Similar database abstraction library for Go with struct mapping and query building; direct competitor with similar goals
  • jmoiron/modl — By the same author; a lightweight ORM that builds on top of sqlx for entities and relationships
  • lib/pq — PostgreSQL driver for Go used by sqlx in its test suite and a key dependency for PG support
  • go-sql-driver/mysql — MySQL driver for Go; another core dependency that sqlx wraps and binds for

🪄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 context deadline/timeout handling tests in sqlx_context_test.go

The repo has sqlx_context.go and sqlx_context_test.go for context support, but testing context cancellation and deadline scenarios is critical for production use. This PR would add tests for query timeout handling, connection pool behavior under deadline pressure, and proper context propagation across nested operations—gaps that could cause subtle bugs in real applications.

  • [ ] Review existing tests in sqlx_context_test.go and identify missing context deadline scenarios
  • [ ] Add test cases for context.WithCancel, context.WithTimeout, and context.WithDeadline across Query, Exec, and transaction methods
  • [ ] Add test case for context deadline propagation through nested transactions
  • [ ] Verify tests pass against all three database drivers (MySQL, PostgreSQL, SQLite) in Makefile/CircleCI config

Add missing bind parameter validation tests in bind_test.go

The bind.go file handles parameter binding for multiple SQL dialects, but bind_test.go likely lacks comprehensive edge cases. This PR would add tests for malformed queries, invalid parameter counts, SQL injection attempts with named parameters, and edge cases like empty strings or nil values—ensuring robustness across MySQL, PostgreSQL, and SQLite dialects.

  • [ ] Audit bind.go for different binding strategies (?, :name, $n, etc.)
  • [ ] Add test cases in bind_test.go for mismatched parameter counts vs actual arguments
  • [ ] Add test cases for special characters and edge values (nil, empty strings, unicode) in named parameters
  • [ ] Add test cases verifying SQL injection is not possible through the binding layer
  • [ ] Run tests to verify all three driver variants work correctly

Add reflectx caching and performance benchmark tests in reflectx/reflect_test.go

The reflectx package is core to sqlx's row marshaling, but reflect_test.go may lack benchmarks and caching validation tests. This PR would add BenchmarkScan tests, verify struct field caching is working correctly (avoiding repeated reflection), and test performance with large struct hierarchies—critical for identifying bottlenecks in high-throughput database applications.

  • [ ] Review reflectx/reflect.go for any caching mechanisms in place
  • [ ] Add Benchmark functions (BenchmarkScan, BenchmarkMapRowToStruct) in reflect_test.go with various struct complexities
  • [ ] Add tests verifying reflection cache hits (if applicable) to ensure repeated scans don't re-reflect
  • [ ] Add test cases for deeply nested struct hierarchies and struct tags with edge cases
  • [ ] Document benchmark baseline and expected performance characteristics in reflectx/README.md

🌿Good first issues

  • Add missing tests for context cancellation behavior in sqlx_context.go—the file exists but sqlx_context_test.go may have incomplete coverage for deadline exceeded and cancellation scenarios: Context support is a core feature in Go; ensuring it works end-to-end with query timeouts is critical
  • Expand bind_test.go to cover Oracle bind syntax (:1, :2 positional) if not already present—only MySQL (?) and PostgreSQL ($1) may be fully exercised: The BindDriver() feature added in v1.3.0 claims to support any driver, but the test suite may not validate all major databases
  • Document the reflectx.FieldInfo caching strategy and its interaction with goroutines in reflectx/README.md—clarify whether the cache is safe for concurrent use: Field introspection is called on every struct scan; understanding cache thread-safety is vital for production code

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 41dac16 — Merge pull request #927 from ninjadq/add_azuresql_driver_bind (dlsniper)
  • 25a5113 — Add azuresql driver bind (Qian Deng)
  • bc91699 — Upgrade dependencies (#909) (dlsniper)
  • dcafbc9 — Introduce CircleCI (#922) (dlsniper)
  • 28212d4 — Merge pull request #767 from liftoffio/gpark.sqlx.reset-slice (jmoiron)
  • 421d1cd — Make Select reset slice length (gayoungpark)
  • a62bc60 — Merge pull request #728 from s7v7nislands/update_mysql_version (jmoiron)
  • 92bfa36 — Merge pull request #734 from QuangTung97/fix/named-exec-values (jmoiron)
  • e6cd7ae — Merge pull request #731 from 2403905/godror (jmoiron)
  • 4b6b69e — Multiline indented query test case (QuangTung97)

🔒Security observations

The sqlx codebase appears to be a well-structured database abstraction library with generally sound security design principles. However, the project uses a Go version from 2018 (1.10), which is a significant concern due to accumulated security patches in newer versions. The library itself promotes parameterized queries which help prevent SQL injection, but developer misuse remains a risk. The absence of a security policy and lack of recent dependency updates are additional minor concerns. Overall security posture is moderate; immediate action should be taken to update the Go version.

  • Medium · Outdated Go Version — go.mod. The project specifies 'go 1.10' in go.mod, which is extremely outdated (released in February 2018). This version lacks numerous security patches and bug fixes from subsequent Go releases, potentially exposing the codebase to known vulnerabilities in the Go standard library. Fix: Update to the latest stable Go version (1.21 or later). Modify 'go 1.10' to 'go 1.21' or the latest available version, and regenerate go.sum with 'go mod tidy'.
  • Medium · Potential SQL Injection via Dynamic Query Construction — bind.go, named.go, sqlx.go. As a database abstraction library, sqlx provides functions like bind.go and named.go that handle SQL query construction. Without careful use, developers could construct dynamic SQL queries vulnerable to injection attacks if user input is not properly parameterized. The library itself appears to support parameterized queries, but misuse is possible. Fix: Ensure all documentation emphasizes parameterized queries and prepared statements. Review code examples to demonstrate safe patterns. Consider adding warnings in function documentation about SQL injection risks when building queries dynamically.
  • Low · Missing Security Policy — Repository root. No SECURITY.md file is present in the repository to provide security reporting guidelines or vulnerability disclosure procedures. This makes it harder for security researchers to responsibly report vulnerabilities. Fix: Create a SECURITY.md file with clear instructions for reporting security vulnerabilities privately (e.g., via GitHub Security Advisory or email), estimated response times, and supported versions receiving security updates.
  • Low · Database Driver Dependencies May Have Vulnerabilities — go.mod. The project depends on specific versions of database drivers (mysql v1.8.1, pq v1.10.9, sqlite3 v1.14.22). While these appear to be reasonably recent versions, they should be regularly scanned for known vulnerabilities. Fix: Regularly run 'go list -json -m all | nancy sleuth' or 'go list -m all | nancy sleuth' to check for known vulnerabilities in dependencies. Consider enabling Dependabot or similar automated dependency scanning on the GitHub repository.

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.

Mixed signals · jmoiron/sqlx — RepoPilot