go-sqlite: a cgo-free SQLite driver for Go, with a caveat in the dependency list
pure-Go SQLite driver for Go (SQLite embedded)
At a glance
- What is it?
- glebarez/go-sqlite is a SQLite driver for Go's database/sql package that aims to avoid cgo, so a binary can be cross-compiled without a C toolchain or a system SQLite. The dependency list complicates that story, since it pulls in modernc.org/sqlite and modernc.org/libc rather than carrying only its own embedded engine.
- Who is it for?
- Use go-sqlite when you want SQLite in a Go service that must cross-compile or build in a container without a C compiler, because the driver registers itself as sqlite in database/sql and takes its pragmas straight from the connection string.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 78 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The driver name you pass to sql.Open is sqlite
The driver plugs into Go's standard database/sql package, which means the import is blank and the driver name is a string in sql.Open. The README's example opens an in-memory database and then queries the SQLite version directly, which is a good sanity check because it confirms the engine is running rather than a stub.
package main
import (
"database/sql"
"log"
_ "github.com/glebarez/go-sqlite"
)
func main() {
// connect
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
log.Fatal(err)
}
// get SQLite version
_ := db.QueryRow("select sqlite_version()")
}The driver name is sqlite, not glebarez-sqlite or anything else carrying the repository name, which is worth memorising because it is the string that appears in every DSN in your codebase.
What the connection string can carry
The DSN syntax is the standard SQLite file path plus an optional query string. An in-memory database is the special path :memory:, an on-disk database is a plain path such as path/to/some.db, and foreign key enforcement is switched on by appending the pragma parameter, for example :memory:?_pragma=foreign_keys(1). The general form is that any SQLite pragma can be preset for a database connection using the _pragma query parameter. The README gives a journal mode example, path/to/some.db?_pragma=journal_mode(WAL), and a busy timeout example, :memory:?_pragma=busy_timeout(5000). Several pragmas can be combined with the parameter repeated, for instance path/to/some.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL). Because these are connection-level settings, a pragma applies to the connection that carries it, so a pool of connections needs the DSN applied to each one.
The go.mod list complicates the pure-Go story
The repository's own module file is where the interesting detail sits. It declares module github.com/glebarez/go-sqlite and go 1.25.0, and its direct requirements are github.com/google/pprof, golang.org/x/sys v0.46.0, modernc.org/libc v1.74.1, modernc.org/mathutil v1.7.1 and modernc.org/sqlite v1.55.0, plus indirect requirements including modernc.org/memory and github.com/ncruces/go-strftime. The README describes the driver as having a Go-based implementation of SQLite from cznic/sqlite embedded in itself, so that you do not need to install SQLite separately. Both statements can hold at once, since modernc is itself a pure-Go SQLite implementation and its presence is what removes the cgo requirement, but the practical reading is that this driver builds on another pure-Go engine rather than carrying an engine written inside this repository. The cgo-free outcome, which is the point for most adopters, still holds: nothing here needs a C compiler at build time.
A fork of cznic/sqlite reshaped for GORM
The project describes itself as a fork of cznic/sqlite with changes to make it compatible with GORM, the Go ORM. That lineage explains both the design and the constraints. A GORM dialect needs a driver that behaves in specific ways around transaction handling, connection lifetime and the way results are streamed back, and those are exactly the changes a fork carries. It also means the driver is not tracking upstream SQLite releases on its own schedule; it inherits whatever the fork has ported. The repository layout backs this up, with a compat directory for compatibility shims, a functest directory and an all_test.go at the top level, plus mutex.go, rlimit.go, rulimit.go, norlimit.go and addport.go as the kind of low-level files a from-scratch SQLite port needs. There are also embedded database files, embed.db and embed2.db, used by the test suite.
Licence handling is split across two files
The repository carries two licence files rather than one. There is a LICENSE file, and the licence field on the repository says BSD-3-Clause for the driver code itself, which is the licence of the fork's own contributions. Separately there is a SQLITE-LICENSE file, which is what you would expect for the SQLite engine code that the driver builds on, for the embedded engine code the driver builds on. The distinction is the one to keep in mind if you vendor this into a product: the Go wrapper and the embedded database engine are separately licensed, and a static binary ships both. The repository also keeps AUTHORS and CONTRIBUTORS files alongside the code.
Release dates and the moving target of the Go version
The tagged releases show a project that has slowed down considerably. Version v1.22.0 was published on 2023-12-27, v1.21.2 on 2023-07-06, and v1.21.1 on 2023-03-29 with a release note that reads upgrade to SQLite 3.41.2. The last push to the repository was on 2026-08-06, so there has been recent commit activity without a new tagged release in nearly three years. Meanwhile the module file requires go 1.25.0, which is a much newer toolchain than the one contemporary with those releases. That combination is worth reading carefully before you pin a version: the module directive and the tagged release describe different points in the project's life, and a build with a modern Go toolchain will not necessarily succeed against the 2023 tag. The badge in the README tracks the SQLite version the code carries, with a date in its label, so that is a quick way to see which engine snapshot you would be getting.
Where this driver is the wrong choice
Three situations argue against it. First, if you already depend on a cgo driver and its behaviour, switching buys you little beyond cross-compilation convenience, and the fork relationship means you inherit a different SQL surface rather than an identical one. Second, if you need SQLite features that arrived after the engine snapshot this driver carries, since the 2023 releases stopped at SQLite 3.41.2 and the modernc.org/sqlite version in go.mod is what the current code builds against. Third, if you are looking for the official driver. This is a community fork whose stated purpose is GORM compatibility, and the pure-Go space it occupies is now served by upstream modernc drivers that other projects also depend on. The pragmatic test is whether you need GORM specifically. If you do, this is a reasonable choice. If you just want database/sql to talk to SQLite without cgo, compare against the modernc driver your go.mod already references before committing to a fork.
Editorial conclusion
Use go-sqlite when you want SQLite in a Go service that must cross-compile or build in a container without a C compiler, because the driver registers itself as sqlite in database/sql and takes its pragmas straight from the connection string. Do not treat it as a drop-in replacement for a cgo driver on the grounds that its SQL dialect will differ, and check the fork relationship before adopting it, since this is a fork of cznic/sqlite with GORM compatibility changes layered on top. Verify first that your Go toolchain satisfies the go 1.25.0 directive in go.mod, that the modernc.org/sqlite and modernc.org/libc dependencies in that file match what you expected from a pure-Go driver, and whether you need the WAL journal mode, since it has to be set per connection through the _pragma parameter.
Frequently asked questions
What driver name do I pass to sql.Open with go-sqlite?
The driver registers itself as sqlite, so you call sql.Open("sqlite", ":memory:") or with a file path. The import is the blank import _ "github.com/glebarez/go-sqlite".
How do I enable foreign keys or set a journal mode in go-sqlite?
Any SQLite pragma can be preset per connection with the _pragma query parameter. Foreign keys are enabled with :memory:?_pragma=foreign_keys(1), WAL with path/to/some.db?_pragma=journal_mode(WAL), and several pragmas can be combined by repeating the parameter.
Does go-sqlite need cgo or a system SQLite install?
No. The README states the driver embeds a Go-based implementation of SQLite, so you do not need to install SQLite separately. The module file requires modernc.org/sqlite and modernc.org/libc, which are themselves pure Go.
What is the relationship between go-sqlite and GORM?
The project is a fork of cznic/sqlite with changes made to be compatible with GORM. The repository contains a compat directory, a functest directory and test database files such as embed.db and embed2.db alongside the driver sources.
What licence applies to go-sqlite?
The licence field on the repository says BSD-3-Clause for the driver code, and the repository keeps a separate SQLITE-LICENSE file for the embedded database engine, since a built binary ships both.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/glebarez-go-sqlite)Was this useful?