Skip to content
SimonWaldherrPublic

About

a lightweight, educational SQL database engine written in pure Go. It implements a comprehensive subset of SQL features using only Go's standard library, making it perfect for learning database internals.

Topics

Resources

Stars

12 stars

Watchers

0 watching

Forks

Latest commit

 

History

450 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tinySQL

CI Go Reference DOI

tinySQL is an embeddable SQL database engine written in Go. It is useful for learning database internals, local tools, tests, browser/WASM applications, and single-process services that need SQL without operating a database server.

Browser playground · map demo · video

tinySQL is not a drop-in replacement for PostgreSQL, MySQL, or a clustered production database. Review limitations before using it for critical workloads.

Start here

tinySQL requires Go 1.26.5+.

go get github.com/SimonWaldherr/tinySQL@latest

Create an in-memory database and run SQL:

package main

import (
	"context"
	"fmt"

	tinysql "github.com/SimonWaldherr/tinySQL"
)

func main() {
	ctx := context.Background()
	db := tinysql.NewDB()
	defer db.Close()

	if _, err := tinysql.ExecScript(ctx, db, "default", `
		CREATE TABLE users (id INT PRIMARY KEY, name TEXT);
		INSERT INTO users VALUES (1, 'Ada'), (2, 'Grace');`); err != nil {
		panic(err)
	}

	// Bind values with ?, $1 or :1 instead of formatting SQL text.
	result, err := tinysql.ExecSQLArgs(ctx, db, "default",
		"SELECT id, name FROM users WHERE id >= ? ORDER BY id", 1)
	if err != nil {
		panic(err)
	}
	for _, row := range result.Rows {
		fmt.Println(row["id"], row["name"])
	}
}

For database/sql, streaming, columnar results, transactions, and the query builder, see developer integration and the driver package.

Rust, Python, Swift and C

The same engine embeds into other languages through one C ABI (bindings/c); see the language bindings guide.

import tinysql                                   # make -C bindings/python build
with tinysql.connect("./data", mode="wal") as conn:
    conn.execute("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name TEXT)")
    conn.executemany("INSERT INTO users VALUES (?, ?)", [(1, "Ada"), (2, "Grace")])
    print(conn.execute("SELECT name FROM users WHERE id = ?", (2,)).fetchone())
let db = tinysql::Database::open_in_memory()?;   // tinysql = { path = "bindings/rust" }
db.execute_script("CREATE TABLE users (id INT PRIMARY KEY, name TEXT)")?;
db.execute("INSERT INTO users VALUES (?, ?)", tinysql::params![1, "Ada"])?;

Choose a workflow

Goal Start with
Explore tinySQL interactively demo, repl, or tinysql
Query files or migrate data query_files, fsql, or migrate
Embed a local SQL service server or tinysqld
Build a browser app query_files_wasm, wasm_browser, or wasm_node
Embed in a Swift / Xcode app Swift package and Apple XCFramework for macOS, iOS and iPadOS
Embed in Rust, Python or C Rust crate, Python package, C ABI
Use AI tooling or local RAG tinysql-mcp-server and the RAG guide
Browse every runnable program command index

Capabilities

Area Includes
SQL DDL/DML, CTEs, joins, grouping, windows, views, triggers, table-valued functions, stored procedures, jobs, and common SQLite-compatible PRAGMAs
Data CSV/TSV, JSON/NDJSON, XML, YAML, Excel, GeoJSON, TopoJSON, KML, OSM XML, routing graphs, Shapefiles, GeoPackage, and MBTiles
Search Full-text, vector, hybrid search, RAG helpers, regex, JSON, URL, HTML, date, math, bitmap, and hash functions
Deployment Pure-Go embedded API, database/sql driver, Rust/Python/Swift/C bindings, CLI, HTTP/gRPC server, browser/WASM builds, and multiple storage backends

The complete SQL function reference is FUNCTIONS.sql. Runnable feature examples are in example_showcase.sql.

GIS, routing, and tiles

Geometry is stored as GeoJSON or validated GEOMETRY; tinySQL includes measurement, predicates, editing, spatial search, choropleth classification, WKT/WKB, geohash, and Web Mercator helpers. Use the geospatial standards guide for formats, CRS profiles, coordinate conventions, and interoperability limits.

Routing functions run Dijkstra or coordinate-guided A* over ordinary edge tables. The OSM routing guide explains graph import, profiles, turn restrictions, and the HTTP demo.

For tiles, the TILE_, MBTILES_, and TILE_COVER functions support Web Mercator and OGC TileMatrix workflows. tinysqld -tiles can publish an MBTiles-shaped table; see its README and the storage guide for durable artifacts.

Retrieval and RAG

Vector, full-text, and hybrid retrieval can be combined with metadata filters and reranking. RAG_WARM and ROUTE_WARM prepare derived serving structures before traffic. The RAG guide covers schema design, ingestion, evaluation, tuning, caching, and context expansion.

Storage and optional imports

Open persistent databases with OpenDB and a StorageConfig:

Mode Best fit
ModeMemory Tests, browser/WASM, and temporary data
ModeWAL In-memory tables with write-ahead-log recovery
ModeDisk Per-table GOB files with lazy loading
ModeJSON Human-readable, diffable per-table JSON
ModeIndex / ModeHybrid Disk-backed tables with bounded caching
ModePagedIndex Large equality lookups such as MBTiles
ModeSQLite A .sqlite file interoperable with SQLite tools; requires sqliteimport

For example, ModeJSON persists each table as readable JSON:

db, err := tinysql.OpenDB(tinysql.StorageConfig{
	Mode: tinysql.ModeJSON,
	Path: "./data",
})
if err != nil {
	panic(err)
}
defer db.Close()

The core has no SQLite or Shapefile runtime dependency. Build optional file support only when needed:

go build -tags=sqliteimport ./...          # SQLite, GeoPackage, MBTiles
go build -tags=shapefile ./...             # ESRI Shapefile and ZIP imports
go build -tags=sqliteimport,shapefile ./...

For size-sensitive embeddings such as browser WASM bundles, the tinysql_minimal tag drops optional features that pull in large dependencies: the SQL HTTP() function (net/http, crypto/tls), HTML_TEMPLATE() (html/template, whose reflection use also keeps otherwise unused methods alive), standards.WriteProblem, and YAML imports (gopkg.in/yaml.v3). The SQL functions and YAML imports return an error; standards.WriteProblem is excluded from the API. HTML_ESCAPE(), core SQL, the database/sql driver and the other importers are unchanged. With Go 1.27 this shrinks the browser bundle from about 27.46 MB to 15.56 MB (43%) before wasm-opt with stripped symbols; sizes vary with the toolchain. -tags no_http removes only the HTTP() function.

GOOS=js GOARCH=wasm go build -tags=tinysql_minimal -trimpath -ldflags='-s -w' -o tinySQL.wasm ./cmd/wasm_browser

Browser and Node build scripts select WASM_PROFILE=minimal by default; use WASM_PROFILE=full to include optional features. make wasm-smoke checks both profiles for dependency exclusions, size reduction and JavaScript API behavior, including transactions and browser snapshot imports.

See the storage guide for DSNs, persistence, read-only serving, backups, encryption scope, and large datasets.

Services and operations

server provides HTTP and gRPC APIs, optional TLS and bearer authentication, plus asynchronous read-only replicas. The cluster guide includes a primary/replica deployment and recovery workflow. tinysqld is the durable DBMS entry point with health, scheduler, and optional tile endpoints.

Both are deliberately smaller than a general-purpose distributed database: replication is asynchronous, and automatic failover, multi-primary writes, and distributed transactions are not implemented.

Guides

Guide Use it for
Developer integration Go API, database/sql, streaming, and browser embedding
Language bindings Rust, Python, Swift and C: types, transactions, persistence, performance
CLI guide Shells, servers, and file-query tools
Storage guide Backends, DSNs, read-only mode, and large artifacts
RAG guide Vector, hybrid retrieval, reranking, and context
Geospatial standards GIS formats, CRS profiles, and interoperability
SQL feature gaps Supported SQL and current gaps
Architecture Parser, executor, storage, and invariants
Development guide Tests, Make targets, and release workflow
API stability Compatibility guarantees and upgrades

Develop

go test ./...
go vet ./...
make test-bindings   # C ABI, Python package and Rust crate

The browser playground build lives in cmd/query_files_wasm:

cd cmd/query_files_wasm
./build.sh --build-only

Limitations

  • tinySQL is embedded and single-process. The server offers asynchronous primary/replica reads, not sharding, automatic failover, multi-primary writes, or distributed transactions.
  • Composite primary/foreign keys, CHECK, target-bearing ON CONFLICT DO UPDATE, SAVEPOINT, ATTACH/DETACH, VACUUM, partial indexes, generated columns, and persistent ANN index files are not available.
  • Secondary indexes accelerate equality/prefix seeks and numeric ranges. Use GEO_SEARCH for indexed point-column bbox/radius queries; ordinary WHERE GEO_DWITHIN(...) predicates are not planner-accelerated.
  • GIS validity is structural rather than full topology validation. GEO_DISSOLVE/GEO_UNION_AGG require clean, vertex-aligned adjacent polygons; they are not general polygon-boolean union operations.
  • RBAC is coarse and single-table oriented. Encryption does not cover WAL-backed modes or metadata files.

tinySQL is primarily an educational and embeddable engine. It keeps the parser, planner, executor, storage backends, and practical extensions easy to inspect, test, and adapt.

About

a lightweight, educational SQL database engine written in pure Go. It implements a comprehensive subset of SQL features using only Go's standard library, making it perfect for learning database internals.

Topics

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages