A storage-independent database built on top of plain key-value operations.
Keep lets you define schemas with typed fields, unique indexed keys, and nested collections — and runs them over any backend that can read, write, and delete a key. It needs no key listing, no prefix scans, and no range queries, so it works the same over the local filesystem, memory, S3-like blob stores, or anything you can wrap in a small struct of functions.
It uses a Dependency Injection pattern in which:
/pkg/lib/contains the pure library logic — it never imports concrete implementations./adapters/contains opinionated, concrete implementations of the dependency contract./pkg/deps/defines theDepsstruct of injectable functions that all adapters must satisfy.
What you get on top of that:
- Storage independent — bring your own backend by populating a small struct, or use the built-in ones (filesystem, in-memory).
- Constant-time operations — create, lookup by key, and delete each touch a fixed number of keys, no matter how many records exist.
- Unique keys — fields of type
Keyare indexed and enforced unique (case-insensitive). - Nested collections — a record can own sub-databases (e.g. a user owning its sessions).
1. Install the library:
go get github.com/MateusMoutinhoOrg/Keep@v0.0.12. Create a main.go file:
package main
import (
"fmt"
"github.com/MateusMoutinhoOrg/Keep/adapters/standard"
"github.com/MateusMoutinhoOrg/Keep/pkg/lib"
)
var Props = lib.Props{
Path: "myDatabase/",
Schemas: []lib.Schema{
{
Name: "user",
Itens: []lib.Item{
{Name: "email", Type: lib.Key, Required: true},
{Name: "username", Type: lib.Key, Required: true},
{Name: "age", Type: lib.Int, Required: true},
},
},
},
}
func main() {
// 1. Create deps via an adapter (the "opinionated" part)
deps := standard.New() // filesystem backend
// 2. Inject deps into the pure library
keep := lib.New(deps)
// 3. Use the library — it never knows which adapter is behind the scenes
db := keep.NewDatabase(Props)
users := db.GetSchema("user")
created, err := users.NewItem(map[string]any{
"email": "mateus@gmail.com",
"username": "mateus",
"age": 27,
})
if err != nil {
fmt.Println("error creating user:", err)
return
}
fmt.Println("created:", created)
found := users.FindByKey("email", "mateus@gmail.com")
fmt.Println("found:", found)
}3. Run:
go run main.goImportant
Must Read before contributing. The following documents are required reading for every developer. Do not open a pull request or make changes without first reading them:
| Document | Why it's required |
|---|---|
| Rules | The contribution rules and guidelines that must be followed for any change to be accepted. |
| Structure | The project's directory layout and the purpose of each component — needed to know where changes belong. |
| Specs | The index of every specification — needed to know how the file you are about to touch must be shaped. |
Listable material — structures, rules, specifications, and the public API.
| Name | Description |
|---|---|
| Structure.md | Reference — The project's directory layout and the purpose of each component. |
| RULES.md | Reference — The binding contribution rules and their required companion updates. |
| Specs.md | Reference — Lists every specification and the files each one governs. |
| PublicApi.md | Reference — Index of all public structs, functions, and methods with detail links. |
| RequiredApi.md | Reference — The contract each Deps function must honor to power the library. |
| Errors.md | Reference — The error types returned by operations and how to react to them. |
| TemplateFileActions.md | Reference — The action each file takes when forking or adapting: copy, create, rewrite, delete. |
How the project's mechanics and features work.
| Name | Description |
|---|---|
| DepsMechanic.md | Explanation — Choosing a backend, overwriting deps, or writing your own. |
| Schemas.md | Explanation — Defining collections, field types, and nested sub-databases. |
| Records.md | Explanation — Creating, finding, reading, updating, deleting, and listing records. |
| DenseRecordPattern.md | Explanation — The key layout and procedures behind the storage engine. |
Workflow guides, grouped by context. Each tutorial covers a single goal.
| Name | Description |
|---|---|
| LibInitialization.md | Tutorial — Install the lib, create deps via an adapter, and run a first program. |
| RunSample.md | Tutorial — Browse and run the executable samples in the examples/ directory. |
| Name | Description |
|---|---|
| DefineDatabase.md | Tutorial — Describe a database with its collections and open it in a program. |
| AddSchemaField.md | Tutorial — Add a field to a collection that already holds records. |
| AddNestedCollection.md | Tutorial — Give a record its own nested collection of sub-records. |
| Name | Description |
|---|---|
| AddLibFunction.md | Tutorial — Add a function to pkg/lib/ and wire it to the injected deps. |
| AddLibObject.md | Tutorial — Add an object created by the lib, with its deps wired in by the constructor. |
| AddDatabaseOperation.md | Tutorial — Add an engine operation without breaking the dense key layout. |
| AddDependency.md | Tutorial — Add a field to the Deps contract and implement it in every adapter. |
| AddAdapter.md | Tutorial — Create a new opinionated storage backend for the Deps contract. |
| AddSample.md | Tutorial — Create a runnable sample in examples/ and register it in the README. |
| Name | Description |
|---|---|
| AddDocument.md | Tutorial — Create or update a .md file and register it in README and Structure. |
| RenameDocument.md | Tutorial — Rename or move a .md file without leaving broken references behind. |
| DeleteDocument.md | Tutorial — Remove a .md file and clear every reference pointing to it. |
| ExposePublicApi.md | Tutorial — Publish a lib function, object, or method in the public API index. |
| Name | Description |
|---|---|
| RenameModule.md | Tutorial — Rename the Go module path and update all internal imports. |
| ForkTemplate.md | Tutorial — Use this repo as a template to start a new DI library. |
| AdaptExistingLib.md | Tutorial — Convert a pre-existing library to this DI structure. |
| Sample | Description |
|---|---|
| CreateUser | Insert a record with unique keys |
| FindUserByKey | Look a record up by a unique field |
| RetrieveUserInfo | Read individual fields of a record |
| UpdateUser | Update a plain field |
| UpdateUserKey | Update a unique indexed field (re-index) |
| DeleteUser | Remove a record and its index entries |
| ListAllUsers | Iterate every record of a collection |
| ListUsersPaginated | Paginate through a collection |
| SubInfos | Manage nested sub-database records |
This project is licensed under the MIT License.