---
title: "Documentation"
description: "How to open, validate, search and cite SPDF files in Rust, TypeScript, Python, Swift, Kotlin, Go, C#, PHP, Ruby, R, Julia and C."
url: https://spdf.joseluissaorin.com/docs
markdown: https://spdf.joseluissaorin.com/docs.md
lang: en
alternate_es: https://spdf.joseluissaorin.com/es/documentacion.md
updated: 2026-10-07
author: José Luis Saorín Ferrer (https://joseluissaorin.com)
license: CC-BY-4.0
---

# Documentation

> How to open, validate, search and cite SPDF files in Rust, TypeScript, Python, Swift, Kotlin, Go, C#, PHP, Ruby, R, Julia and C.

Every implementation offers the same operations with the names and habits of its language. Pick yours; each page has the install line, a first example and the full README of the library.

- [Rust](https://spdf.joseluissaorin.com/docs/rust.md): `cargo add spdf`. Reference implementation; also provides the C ABI.
- [TypeScript](https://spdf.joseluissaorin.com/docs/js.md): `npm install spdf-format`. Node (node:sqlite), Bun and the browser (sqlite-wasm). Powers the validator on this site.
- [Python](https://spdf.joseluissaorin.com/docs/python.md): `pip install spdf-format`. Standard library sqlite3 only; imported as spdf.
- [Swift](https://spdf.joseluissaorin.com/docs/swift.md): `.package(url: "https://github.com/joseluissaorin/spdf", from: "5.0.0")`. Swift Package Manager, from the repository. Apple platforms and Linux.
- [Kotlin / JVM](https://spdf.joseluissaorin.com/docs/kotlin.md): `implementation("io.github.joseluissaorin:spdf:5.0.0")`. Kotlin and Java on the JVM and Android.
- [Go](https://spdf.joseluissaorin.com/docs/go.md): `go get github.com/joseluissaorin/spdf/go`. Go module in the monorepo.
- [C# / .NET](https://spdf.joseluissaorin.com/docs/dotnet.md): `dotnet add package Spdf.Format`. .NET with Microsoft.Data.Sqlite.
- [PHP](https://spdf.joseluissaorin.com/docs/php.md): `composer require joseluissaorin/spdf`. PDO SQLite.
- [Ruby](https://spdf.joseluissaorin.com/docs/ruby.md): `gem install spdf-format`. On the sqlite3 gem.
- [R](https://spdf.joseluissaorin.com/docs/r.md): `remotes::install_github("joseluissaorin/spdf", subdir = "r")`. On RSQLite; fragments as data frames.
- [Julia](https://spdf.joseluissaorin.com/docs/julia.md): `pkg> add SPDF`. On SQLite.jl.
- [C](https://spdf.joseluissaorin.com/docs/c.md): `#include "spdf.h"  /* link with -lspdf */`. C ABI over the Rust core, for C, C++ and any FFI.

## The same operations everywhere

| Operation | What it returns |
| --- | --- |
| open | A read-only handle on a 5.0 or legacy 4.x file, opened safely |
| validate | `{valid, version, profile, errors, warnings}` with the codes of the specification |
| dump | The canonical JSON of the file (RFC 8785) |
| search (lexical, vector, hybrid) | `{fragment_id, score, via, anchor, anchor_uri}` items |
| anchor URI | Format and parse `spdf:` URIs, byte for byte |
| cite | `(Family, Year, locator)` in English or Spanish |
| export | CSL-JSON and BibTeX |
| write | A new, valid SPDF built from your own data |

## Without any library

An SPDF file is a SQLite database. Any tool that speaks SQLite reads it; only the safety rules and the anchors need care.

```sh
sqlite3 -readonly darwin-origin.spdf "SELECT key, value FROM spdf_meta"
sqlite3 -readonly darwin-origin.spdf \
  "SELECT f.id, u.printed, substr(f.text, 1, 80)
     FROM fragments_fts JOIN fragments f ON f.n = fragments_fts.rowid
     JOIN units u ON u.id = f.unit
    WHERE fragments_fts MATCH 'selection' LIMIT 5"
```

Legacy 4.x files from Scholaris are gzip-wrapped: `gzip -dc old.spdf > old.sqlite` first.
