# Contributing to Dynoxide
Thanks for considering a contribution. Dynoxide is a DynamoDB-compatible
engine in Rust backed by SQLite, and behaves like AWS DynamoDB by
design. That guides most of what follows.
If you are using an AI coding tool (Codex, Cursor, Aider, Claude Code,
or similar), please also read [AGENTS.md](AGENTS.md); it covers the
same ground in a form those tools pick up automatically.
## Before you start
- Open a GitHub issue describing the change if it is more than a small
bug fix or obvious cleanup. A short paragraph is enough. This catches
direction questions before a PR round-trips.
- The storage layer is mid-refactor. A `StorageBackend` trait now lives
in `src/storage_backend/` and the native rusqlite-backed `Storage`
implements it. Nothing dynamic dispatches the trait yet; `Database`
and the action handlers still operate against `Storage` directly. The
`Storage::conn()` and `Storage::conn_mut()` escape hatches are not on
the trait and folding them in is the next pass. Please open an issue
before submitting changes to `src/storage.rs`, `src/storage_backend/`,
or call sites that use `conn()` directly so we can advise whether your
change fits the current shape or is better held until the next pass.
- If you want to add a new dependency, open an issue so we can weigh
binary size, build time, and licence.
## When you need an RFC or an ADR
Bigger changes get a short [RFC](docs/rfcs/) before they are built:
anything touching the DynamoDB wire contract, the `StorageBackend`
trait, SigV4 auth, the on-disk format, or the CLI and config surface,
plus large new features. It is a lightweight process, and it overlaps
with the "open an issue first" note above. [ADRs](docs/adr/) record the
decisions that come out of it. Bug fixes, refactors that keep behaviour
the same, docs, and tests need neither.
## The compatibility principle
Dynoxide exists to behave like AWS DynamoDB. If a PR would make
Dynoxide's observable behaviour diverge from real DynamoDB, the PR
description needs to say so explicitly and cite the AWS documentation
or behaviour note that motivates the change. Cleaner ergonomics or
"nicer" API shapes are not a reason on their own.
## Local setup
- Rust 2024 edition, MSRV 1.88 (both declared in `Cargo.toml`). The crate
builds on 1.88, but the test suite's AWS SDK dev-dependencies need Rust
1.94.1 or later, so use a recent stable toolchain to run the tests.
- `cargo build` to compile, `cargo test` to run the test suite.
- `cargo fmt --check` and `cargo clippy -- -D warnings` must pass
before a PR is merge-ready; CI enforces both, in the root crate and
in the separate `benchmarks/` package.
## Tests
- New behaviour ships with tests. Bug fixes ship with a regression
test that fails before the fix.
- Tests live in `tests/` and as inline `#[cfg(test)]` modules.
- The external conformance suite
(<https://github.com/paritysuite/dynamodb-conformance>) runs in CI for
release candidates. Running it locally is optional but useful when
you change request or response shapes.
## Benchmarks
The PR benchmark check has two layers, and neither blocks a merge.
Criterion wall-clock numbers run on shared CI runners and are
advisory; they can swing by up to roughly 3x on a noisy neighbour.
iai-callgrind runs on the same PR and is deterministic, but it reports
instruction counts without a stored baseline, so it does not fail on a
regression by itself, and CI keeps no counts from `main`. If Criterion
looks red, run `cargo bench --bench iai_core --features iai-callgrind`
in `benchmarks/` on `main` and on your branch, on the same Linux
machine or container; if the counts match, re-run the workflow before
worrying. `AGENTS.md` has the short version of this.
## Commit style
Short subject, lower-case, imperative where possible. A Conventional
Commits-style prefix (`feat:`, `fix:`, `docs:`, `refactor:`, `chore:`,
`ci:`) is preferred when one fits but is not a gate; a plain short
subject is fine if no prefix fits. Bodies are welcome for anything
non-obvious.
## Licensing of contributions
Dynoxide is dual-licensed under the MIT License and the Apache License,
Version 2.0. By contributing, you agree that your contribution is
offered under those same terms, and that you have the right to submit
it.
## Where to ask
GitHub Issues: <https://github.com/nubo-db/dynoxide/issues>.
Discussions are not currently enabled.