inGitDB is a developer-grade, schema-validated, AI-native database whose storage engine is a Git repository. Every record is a plain YAML or JSON file, every change is a commit, and every team workflow β branching, code review, pull requests β extends naturally to data. This makes inGitDB simultaneously a database, a version-control system, an event bus, and a data layer for AI agents, all with zero server infrastructure for reads.
With ingitdb installed (see Installation below):
ingitdb demo install # creates ./todo-demo, a Git repository
ingitdb select --from=lists/to-buy/items --path=todo-demo
ingitdb --path=todo-demo # browse the lists in the terminal UIThe TODO demo holds two lists, To buy and To watch, as plain YAML files with one commit of
history. It is the same demo OpenVaultDB installs with
ovdb demo install. See demo install.
We build with our own tooling:
- SpecScore β specify requirements as
SpecScore.mdartifacts - SpecStudio β author & manage specs across their lifecycle
- inGitDB β store structured data in Git where applicable
- DALgo β data access layer for Go
- cover100.dev β drive toward 100% test coverage
- DataTug β query & explore data
- Plain files, real Git. Records are YAML or JSON files you can read in any editor, diff in any
pull request, and clone with a single
git clone. No binary blobs, no proprietary format. - Full Git history for free. Branching, merging, bisect, and revert work on your data exactly as they do on your code β because the data is in your code repository.
- Schema validation built in. Collections are defined with typed column schemas in YAML. The
ingitdb validatecommand checks every record and reports violations with the collection, file path, and field name. - Zero server infrastructure for reads. There is no daemon to run. Reading data is a file-system operation on a git clone.
- Go library via DALgo.
pkg/dalgo2ingitdbimplements the DALgodal.DBinterface, so any Go program can use inGitDB as a standard database abstraction.
flowchart LR
A([YAML / JSON\nrecord files]) --> B[(Git repository\non disk)]
B --> C[ingitdb validate\nschema + data check]
C --> D[Views Builder\ngenerates $views/]
D --> E([CLI output\ningitdb query])
D --> F([Go programs\nDALgo API])
The ingitdb validate command reads .ingitdb.yaml, checks every record against its collection
schema, and rebuilds materialized views in the same pass. Validation can be scoped to a commit
range (--from-commit / --to-commit) so CI stays fast on large databases.
brew tap ingitdb/cli
brew install ingitdbyay -S ingitdb-binsnap install ingitdbbrew tap ingitdb/cli
brew install ingitdbwinget install ingitdbchoco install ingitdbscoop bucket add ingitdb https://github.com/ingitdb/scoop-bucket
scoop install ingitdbgo install github.com/ingitdb/ingitdb-cli/cmd/ingitdb@latestPre-built binaries for all platforms are available on the GitHub Releases page.
ingitdb install lists the fleet CLIs relevant to inGitDB users β datatug,
ovdb, synchestra, specscore β with their live installed status, and
ingitdb install <name>... installs them the same way ingitdb itself was
installed (Homebrew cask, or a checksum-verified direct download next to the
ingitdb binary). ingitdb upgrade is the fleet-wide counterpart:
ingitdb upgrade reports current/latest/verdict for every installed
catalog CLI plus ingitdb itself, and ingitdb upgrade --all/ingitdb upgrade <name>... applies it after one confirmation. ingitdb self-update
is exactly ingitdb upgrade ingitdb, built from the same catalog
configuration, so the two never disagree β neither has an update alias
(ingitdb update is the SQL UPDATE verb). See
spec/features/cli/install.
# Build the CLI
go build -o ingitdb ./cmd/ingitdb
# Validate a database directory (schema + records)
ingitdb validate
# Validate a specific path
ingitdb validate --path=/path/to/your/db
# Validate only collection definitions
ingitdb validate --only=definition
# Validate only records (skip schema validation)
ingitdb validate --only=records
# Validate only records changed between two commits (fast CI mode)
ingitdb validate --from-commit=abc1234 --to-commit=def5678
# List all collections
ingitdb list collections
# List collections nested under a path (regular expression)
ingitdb list collections --in='countries/(ie|gb)'
# List collections whose name contains "city"
ingitdb list collections --filter-name='*city*'
# Drop a specific collection and all its records
ingitdb drop collection countries.counties.dublin
# Delete records matching a filter within a collection
ingitdb delete --from=countries.counties --where='status==archived'
# --- Record CRUD (requires record_file.type: "map[string]any" collections) ---
# Insert a new record: the --id format is <collection-id>/<record-key>
# (collection IDs allow alphanumeric and "." only; "/" separates collection and key)
ingitdb insert --path=. --id=geo.nations/ie --data='{title: "Ireland"}'
# Select a record by ID (output format: yaml or json)
ingitdb select --path=. --id=geo.nations/ie
ingitdb select --path=. --id=geo.nations/ie --format=json
# Select records from a collection with a filter (supported operators: ==, ===, !=, !==, >=, <=, >, <)
ingitdb select --from=geo.nations --where='population>1000000'
ingitdb select --from=geo.nations --where='continent==europe' --format=json
# Update fields of an existing record (patch semantics: only listed fields change)
ingitdb update --path=. --id=geo.nations/ie --set='{title: "Ireland, Republic of"}'
# Delete a single record
ingitdb delete --path=. --id=geo.nations/ieinGitDB can read and write records in a remote Git repository without cloning it. The
--remote flag replaces --path and points the CLI at a remote Git hosting service
(GitHub today; GitLab and Bitbucket adapters are coming) over the provider's REST API.
# Select a record
ingitdb select --remote=github.com/owner/repo --id=countries/ie
# Pin to a specific branch, tag, or commit SHA
ingitdb select --remote=github.com/owner/repo@main --id=todo.tags/active
ingitdb select --remote=github.com/owner/repo@v1.2.0 --id=todo.tags/active
# List all collections
ingitdb list collections --remote=github.com/owner/repoSupply a token via a host-derived environment variable (e.g. GITHUB_TOKEN for github.com)
or the --token flag. All write operations also require a token, even for public repositories.
# Set the token once in your shell
export GITHUB_TOKEN=ghp_...
ingitdb select --remote=github.com/owner/repo --id=countries/ie
ingitdb list collections --remote=github.com/owner/repo
ingitdb insert --remote=github.com/owner/repo --id=countries/ie --data='{name: Ireland}'
ingitdb update --remote=github.com/owner/repo --id=countries/ie --set='{name: Ireland, capital: Dublin}'
ingitdb delete --remote=github.com/owner/repo --id=countries/ie
# Or pass the token inline (not recommended for scripts β it ends up in shell history)
ingitdb select --remote=github.com/owner/repo --token=ghp_... --id=countries/ieEach write operation (insert, update, delete) creates a single commit
in the remote repository. No local clone is required at any point.
See Remote Repository Access for the full reference, including authentication details, rate limit notes, and limitations.
A minimal .ingitdb.yaml at the root of your DB git repository:
rootCollections:
tasks.backlog: data/tasks/backlog
tasks.inprogress: data/tasks/in-progress
languages:
- required: enπ οΈ Commands
| Command | Status | Description |
|---|---|---|
version |
β done | Print build version, commit hash, and date |
validate |
β done | Check every record against its collection schema |
select |
β done | Read records by ID or query a collection (local or remote) |
insert |
β done | Insert a new record (single record or batch from stdin) |
update |
β done | Update fields of an existing record (local or remote) |
delete |
β done | Delete records by ID or --where filter (local or remote) |
drop |
β done | Drop a collection or view definition |
list collections |
β done | List collection IDs (local or remote) |
list views |
π‘ planned | List view definitions |
materialize |
β done | Regenerate collection READMEs and materialized views |
diff |
β done | Show record-level changes between two git refs |
pull |
β done | Pull remote changes, resolve conflicts, and rebuild views |
resolve |
π‘ planned | Interactive TUI for resolving data-file merge conflicts |
setup |
π‘ planned | Initialise a new database directory |
rebase |
β done | Rebase on top of a base ref and resolve README conflicts |
install |
β done | List and install fleet CLIs relevant to ingitdb |
upgrade |
β done | Upgrade installed fleet CLIs, including ingitdb itself |
The --id flag uses / to separate collection ID from the record key:
<collection-id>/<record-key>
Collection IDs may contain only alphanumeric characters and . (e.g. geo.nations), and must start
and end with an alphanumeric character. Use / only after the collection ID (e.g. --id=geo.nations/ie).
The longest matching collection prefix wins when ambiguous.
Only collections with record_file.type: "map[string]any" support CRUD. Collections using
[]map[string]any (list) or map[string]map[string]any (dictionary) are not yet implemented.
See the CLI reference for flags and examples.
| Document | Description |
|---|---|
| Documentation | Full docs index β start here |
| CLI reference | Every subcommand, flag, and exit code |
| Architecture | CLI component architecture and package map |
| Contributing | How to open issues and submit pull requests |
| Claude Code AI plugin | Agent skills that teach AI tools how to drive the ingitdb CLI |
Storage format, schema definitions, roadmap, and system-level feature specs are maintained in the ingitdb-specs repository.
| Document | Description |
|---|---|
| Storage Format | Directory layout, collection schema, column types, record files |
| Features | What inGitDB can do today and what is coming |
| Remote Repository Access | Read and write records in remote Git repositories (GitHub, GitLab, Bitbucket) without cloning |
| Diff | Record-level diff between two git refs with field-level detail, commit annotations, and JSON/YAML output |
| Roadmap | Nine delivery phases from Validator to GraphQL |
| Competitors | Honest feature comparison with related tools |
When working locally, ingitdb-specs is at
../ingitdb-specs/
inGitDB is small enough that every contribution makes a visible difference. The best way to start
is to point the CLI at a directory of YAML files and run ingitdb validate, then check the
Roadmap to see what is being built next.
To contribute:
- Read CONTRIBUTING.md for the pull-request workflow.
- Browse open issues to find something to work on.
- Open or comment on an issue before investing time in a large change.
Bug reports, documentation improvements, and questions are all welcome.
- DALgo β Database Abstraction Layer for Go
This project is free, open source and licensed under the MIT License. See the LICENSE file for details.
