> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memvid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Opening and mutating

> Using the Rust API directly

Developers embedding `memvid-core` can open `.mv2` files and mutate them directly, mirroring CLI behavior.

```rust theme={null}
use memvid_core::{Memvid, PutOptions};

let mut mv = Memvid::create("notes.mv2")?;

let opts = PutOptions::builder().track("demo").title("hello").build();
mv.put_bytes_with_options(b"hello", opts)?;

// Persist the WAL, rebuild indexes, and write a new footer snapshot.
mv.commit()?;
```

Key APIs:

* `Memvid::create(path)` – creates a new `.mv2` and takes an exclusive lock
* `Memvid::open(path)` – opens an existing `.mv2` with an exclusive lock (and performs recovery if needed)
* `Memvid::open_read_only(path)` – opens a consistent snapshot with a shared lock
* `put_bytes*` / `put_with_embedding*` – append frames (optionally with pre-computed embeddings)
* `commit()` – makes changes durable and visible to readers

Locking is handled via `FileLock` internally: writers (`create/open`) take an exclusive lock, while readers (`open_read_only`) share a lock for concurrent queries. Mutation APIs call `Memvid::ensure_writable()` and will fail if the handle is read-only.

> **Best practice**: Call `commit()` after batches. Read-only snapshots only see committed state; uncommitted changes remain in the embedded WAL until a commit or the next writer open/recovery.
