{"id":51737649,"url":"https://github.com/kiddyuchina/sqlited","last_synced_at":"2026-07-18T08:40:07.072Z","repository":{"id":366641879,"uuid":"1276347509","full_name":"kiddyuchina/sqlited","owner":"kiddyuchina","description":"Single-binary SQLite HTTP server with a Cloudflare D1-compatible API.  Turn multiple local database files into a secure RESTful API gateway.","archived":false,"fork":false,"pushed_at":"2026-06-22T17:03:57.000Z","size":24,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-07-18T08:39:51.724Z","etag":null,"topics":["backend-tools","cloudflare-d1","database","db-admin","http-api","self-hosted","sqlite","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kiddyuchina.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-21T21:38:03.000Z","updated_at":"2026-06-23T13:37:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kiddyuchina/sqlited","commit_stats":null,"previous_names":["kiddyuchina/sqlited"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kiddyuchina/sqlited","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiddyuchina%2Fsqlited","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiddyuchina%2Fsqlited/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiddyuchina%2Fsqlited/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiddyuchina%2Fsqlited/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kiddyuchina","download_url":"https://codeload.github.com/kiddyuchina/sqlited/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiddyuchina%2Fsqlited/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35612560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-18T02:00:07.223Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend-tools","cloudflare-d1","database","db-admin","http-api","self-hosted","sqlite","sqlite3"],"created_at":"2026-07-18T08:40:06.329Z","updated_at":"2026-07-18T08:40:07.060Z","avatar_url":"https://github.com/kiddyuchina.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sqlited\n\n[![CI](https://github.com/kiddyuchina/sqlited/actions/workflows/ci.yml/badge.svg)](https://github.com/kiddyuchina/sqlited/actions/workflows/ci.yml)\n[![Go Version](https://img.shields.io/badge/go-1.24%2B-blue)](https://go.dev)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\nA lightweight, single-binary HTTP daemon that exposes **one or more local SQLite\nfiles** through a **Cloudflare D1-compatible** JSON API. Download, run\n`sqlited init`, then `sqlited run` -- no cloud, no dependencies, no build step.\n\n```bash\n# 1. Download the binary from GitHub Releases\n# 2. Generate a config\nsqlited init\n# 3. Start serving all configured SQLite files\nsqlited run\n```\n\n## Features\n\n- **One binary, zero runtime dependencies** -- download and run; no package manager, no CGO, no external services.\n- **Serve multiple SQLite files at once** -- one `sqlited` process can open many databases, each reachable by its own `db_key` and route.\n- **CGO-free** -- built on the pure-Go driver [`modernc.org/sqlite`](https://pkg.go.dev/modernc.org/sqlite), so it cross-compiles anywhere.\n- **Atomic batches** -- an array of statements runs inside a single transaction and rolls back on any failure.\n- **Standard library routing** -- uses Go 1.22+ `net/http` path patterns, no web framework.\n\n## Quick Start\n\n### 1. Download a release\n\nGrab the binary for your platform from the [GitHub Releases](https://github.com/kiddyuchina/sqlited/releases) page. No installation step is required -- it is a single self-contained executable.\n\n### 2. Generate a config\n\n```bash\nsqlited init\n```\n\nThis writes `sqlited.json` to the current directory with a freshly generated,\ncryptographically random 32-character `auth_token`. It refuses to overwrite an\nexisting file.\n\n### 3. Start the server\n\n```bash\nsqlited run              # reads ./sqlited.json\nsqlited run -config /etc/sqlited.json\n```\n\n### 4. Query the API\n\n```bash\nTOKEN=$(jq -r .auth_token sqlited.json)\ncurl -s http://localhost:4567/accounts/local/d1/database/app_prod/query \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[{\"sql\":\"SELECT 1 AS n\",\"params\":[]}]'\n```\n\n## CLI Commands\n\n```\nsqlited init        Generate a sqlited.json config in the current directory\nsqlited run         Start the HTTP server\nsqlited serve       Alias for run\nsqlited help        Show help\n```\n\n## Configuration (`sqlited.json`)\n\nMap as many SQLite files as you need under `databases`. Each key becomes the\n`db_key` used in the URL:\n\n```json\n{\n  \"port\": 4567,\n  \"auth_token\": \"a-secure-random-token\",\n  \"databases\": {\n    \"app_prod\": {\n      \"path\": \"./data/app.db\",\n      \"busy_timeout_ms\": 5000,\n      \"wal_mode\": true\n    },\n    \"blog_db\": {\n      \"path\": \"./data/blog.db\",\n      \"busy_timeout_ms\": 3000,\n      \"wal_mode\": true\n    }\n  }\n}\n```\n\nWith this config, a single `sqlited run` opens both files and exposes them on\nseparate routes:\n\n```\nPOST /accounts/local/d1/database/app_prod/query\nPOST /accounts/local/d1/database/blog_db/query\n```\n\nEach database is opened with `PRAGMA busy_timeout` set to `busy_timeout_ms`\n(default `5000`) and, when `wal_mode` is `true`, `PRAGMA journal_mode=WAL` to\nmaximize concurrency and avoid \"database is locked\" errors. The parent\ndirectory of each `path` must already exist.\n\n## HTTP API\n\n### Endpoint\n\n```\nPOST /accounts/local/d1/database/{db_key}/query\nAuthorization: Bearer \u003cauth_token\u003e\nContent-Type: application/json\n```\n\n- `{db_key}` must match a key under `databases` in the config, otherwise `404`.\n- A missing or incorrect bearer token returns `401`.\n\nThere is also an unauthenticated `GET /health` liveness probe.\n\n### Request body\n\nA JSON array of statement objects (batch) or a single statement object:\n\n```json\n[\n  { \"sql\": \"INSERT INTO users (name) VALUES (?)\", \"params\": [\"Alice\"] },\n  { \"sql\": \"UPDATE stats SET count = count + 1 WHERE id = 1\", \"params\": [] }\n]\n```\n\nAlternatively, send a single object without wrapping in an array:\n\n```json\n{ \"sql\": \"SELECT 1 AS n\", \"params\": [] }\n```\n\nIf any statement in a batch fails, the transaction is rolled back and an error\nresponse is returned; otherwise it is committed.\n\n### Response body (D1 format)\n\n```json\n{\n  \"result\": [\n    {\n      \"results\": [],\n      \"success\": true,\n      \"meta\": { \"rows_read\": 0, \"rows_written\": 1 }\n    }\n  ],\n  \"success\": true,\n  \"errors\": [],\n  \"messages\": []\n}\n```\n\n`SELECT`/`PRAGMA`/`EXPLAIN`/`WITH` statements populate `results` with row\nobjects and `meta.rows_read`; write statements populate `meta.rows_written`.\n\n## Project Structure\n\n```\n.\n├── cmd/sqlited/main.go          # entry point\n├── internal/\n│   ├── d1/                      # D1 JSON types\n│   ├── config/                  # config loading \u0026 init\n│   ├── sqlite/                  # SQLite connection \u0026 batch execution\n│   └── server/                  # HTTP routing, auth, D1 handlers\n├── go.mod\n├── go.sum\n├── Makefile\n├── LICENSE\n├── .gitignore\n├── README.md\n└── .github/workflows/ci.yml\n```\n\n## Building from Source (for development)\n\nIf you want to hack on sqlited:\n\n```bash\n# Build\ngo build -o sqlited ./cmd/sqlited\n\n# Or with Make\nmake build\n\n# Tests\nmake test\nmake integration\nmake lint\n```\n\nRequires Go 1.22+ (developed and tested on Go 1.24). The project is intentionally\nCGO-free, so the default test targets do not use `-race`. Use `make test-race` if\nyou enable CGO.\n\n## Notes\n\n- The SQLite driver chosen is **`modernc.org/sqlite`** (pure Go, no CGO).\n- Errors return the D1 envelope with `success: false` and a populated `errors`\n  array.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiddyuchina%2Fsqlited","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkiddyuchina%2Fsqlited","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiddyuchina%2Fsqlited/lists"}