8 releases (4 breaking)
Uses new Rust 2024
| 0.5.2 | Jan 12, 2026 |
|---|---|
| 0.5.1 | Jan 11, 2026 |
| 0.4.0 | Jan 11, 2026 |
| 0.3.0 | Jan 10, 2026 |
| 0.1.1 | Jan 7, 2026 |
#60 in Development tools
87KB
2.5K
SLoC
Elaine
An opinionated, local-first, CLI reference manager for LaTeX / BibTeX users.
Deterministic metadata. Explicit libraries. Local documents, on your terms.
Elaine — CLI Reference Management for Researchers
Elaine is a lightweight command-line reference manager designed for researchers, engineers, and writers who:
- write LaTeX directly
- want deterministic BibTeX
- want full local ownership
- want references to behave like code and data
Elaine does not try to be a PDF library, a cloud sync tool, or a PDF hoarder.
It focuses on one thing: managing references cleanly and compiling reliable .bib files.
Why Elaine exists
Most reference managers:
- Store PDFs you don’t need
- Depend on cloud sync
- Hide metadata behind GUIs
- Produce noisy or unstable BibTeX
Elaine takes a different approach:
- References are atomic YAML files
- Libraries are explicit collections
- BibTeX output is deterministic
- Everything is local, transparent, and versionable
Core ideas
Reference atoms
Each reference is a single YAML file:
.elaine/refs/<reference-id>.yaml
References are:
- atomic
- editable
- diffable
- reusable across libraries
Each reference has:
- a semantic ID (human-readable, derived)
- an opaque SID (UUID v4, stable and collision-free)
Libraries
Libraries are explicit collections of references:
.elaine/libraries/<library>.yaml
A reference can belong to multiple libraries without duplication.
Libraries also have opaque SIDs.
Selectors (IDs & SIDs)
Anywhere Elaine expects a reference or library, you may use:
- full ID
- full SID
- unique prefix of either
Examples:
eln edit rush1988
eln open 55b3ed28
eln pin 9c2128b9 crystal
eln lib ef67
eln lib crystal
eln lib --delete d084
Ambiguous prefixes are rejected explicitly.
Attachments (PDFs, local artifacts)
Elaine supports linking local documents (e.g. PDFs) to references.
Attachments are:
- filesystem paths (absolute or relative)
- never copied, moved, or synced
- optional and explicit
Attach a document
eln attach <ref-selector> /path/to/paper.pdf
Open an attachment
eln open <ref-selector>
Opens the first attachment using the system default viewer.
Detach attachments
eln detach <ref-selector> # remove first attachment
eln detach <ref-selector> 2 # remove attachment at index
eln detach <ref-selector> --all # remove all attachments
In verbose status output, references with attachments are marked:
📄
Installation
From crates.io
cargo install elaine-cli
From source
cargo install --path . --force
Project layout
.elaine/
├── index.yaml # active library pointer
├── libraries/
│ └── <library>.yaml
└── refs/
└── <ref-id>.yaml
Everything is plain text (YAML).
Core commands
Initialize
eln init
Add references
BibTeX (stdin)
eln add < references.bib
Elaine parses, validates, and stores references atomically.
Manual
eln add "The Satanic Verses" "Rushdie, Salman" 1988
Interactive
eln add -i
Edit references
eln edit <ref-selector>
Interactive editing with safe ID reconciliation.
Libraries
eln lib <library>
eln lib
eln lib --delete <library-selector>
Deleting a library never deletes references.
Rename libraries
Libraries can be renamed safely without losing references:
eln lib --rename new_name
Renaming:
- updates the library file
- preserves the opaque SID
- keeps all references intact
- updates the active library pointer automatically
Status
eln status
eln status -v
eln status -vv
eln status --sort year
Status provides a hierarchical view of all libraries and their references.
Verbosity levels:
-
eln status- libraries, reference counts, active marker
-
eln status -v- reference IDs
- short SIDs
- attachment indicators (
📄)
-
eln status -vv- title
- first author
- year
- attachments
Sorting:
eln status --sort id
eln status --sort title
eln status --sort author
eln status --sort year
Sorting affects reference order within each library.
Pin / unpin
eln pin <ref> [library]
eln unpin <ref> [library]
Unpinned references become orphaned, never auto-deleted.
Remove references
eln rm <ref>
Elaine prompts before deleting globally unused references.
Search (external lookup)
eln search <ref>
Search hierarchy:
- DOI
- Stored URL
- Semantic Scholar
- General web search
Results are links, not imports.
Print bibliography
1. Active library
eln printed
Generates a deterministic BibTeX file for the active library:
<library>_references.bib
The same content is also printed to stdout.
2. Multiple libraries (set union)
eln printed libraryA libraryB
Generates a single BibTeX file containing the union of references across the specified libraries:
libraryA+libraryB_references.bib
If the same reference appears in multiple libraries, it is emitted once.
3. Global bibliography
eln printed --all
Generates a global bibliography containing all references across all libraries:
global_references.bib
This file is always named explicitly to avoid overwriting curated library-level bibliographies.
Example Workflow
eln init
eln lib machine_learning
eln add < references.bib
eln add "No Free Lunch Theorems" "Wolpert, D.H. and Macready, W.G." 1997
eln add -i
eln status
eln printed
# Multi-library bibliography
eln printed machine_learning background
# Global bibliography (all libraries)
eln printed --all
Design principles
Elaine is built around a few non-negotiables:
- Local-first — no cloud, no accounts
- Deterministic output — same input, same
.bib - Opinionated parsing — explicit rules, no silent failure
- Minimal surface area — fewer commands, fewer flags
- Researcher-friendly — works with Git, LaTeX, and editors
- Explicit scope — global and multi-library actions are always opt-in
- No hidden state — orphaned references are surfaced explicitly
Roadmap
- Attachment metadata (page count, checksum)
$EDITORintegration- Validation / linting (
eln check) - Reference listing / filtering
- Optional metadata enrichment
License
MIT License
Dependencies
~5–17MB
~177K SLoC