Librius — A fast, minimalist CLI to manage your personal book collection, built in Rust.
Librius is a cross-platform command-line tool written in Rust that helps you manage your personal library.
It uses a SQLite database to store your books and a simple YAML configuration file
(librius.conf) for flexible setup.
This project aims to provide a clean, modular architecture with future extensions such as search, add/remove commands, and import/export support.
🧱 Full internal refactor — cleaner module structure
This release performs a complete restructuring of the source tree without changing any user-visible behaviour (commands, flags, output remain identical).
Key improvements:
utils/split into focused single-responsibility files:verbose.rs,print.rs,log.rs,import_helpers.rsmodels/book.rs(pure data) separated frommodels/display.rs(Tabled + i18n presentation)db/load_db.rs→db/connection.rs·db/migrate_db.rs→db/migrations.rs·db/search.rsabsorbed intodb/books.rscli/fields.rsextractsEDITABLE_FIELDSfromutils/where it did not belong- Dead code removed:
commands/add.rswrapper, duplicatecreate_schema(), deadCommandsenum lib.rsnow exposes an explicit, minimal public API (no more glob re-exports)- Duplicate
run_migrations()call inmain.rseliminated - Added
STRUCTURE.md— full documented map of the source tree
See
CHANGELOG.mdfor the complete change log.
yay -S librius
# or
paru -S libriusbrew tap umpire274/tap
brew install libriuscargo install rtimelogger| Feature | Command | Description |
|---|---|---|
| List | librius list |
Display all books stored in the local database, in full or compact view |
| Search | librius search <query> |
Full-text search across title, author, editor, genre, and language fields; supports --short for compact view |
| Add book | librius add book --isbn <ISBN> |
Add new books using ISBN lookup via Google Books API |
| Edit book | librius edit book <ID/ISBN> |
Edit existing records by ID or ISBN; dynamic field generation, language conversion, and plural-aware messages |
| Delete book | del <ID/ISBN> |
Delete books by ID or ISBN, with interactive confirmation, --force flag, and logged deletions |
| Config management | librius config |
Manage YAML configuration via --print, --init, --edit, --editor |
| Database management | librius db |
DB Management via --init, --reset, --copy -f|--file <name new file> |
| Backup | librius backup |
Create plain or compressed database backups (.sqlite, .zip, .tar.gz) |
| Export | librius export |
Export data in CSV, JSON, or XLSX format |
| Import | librius import |
Import data from CSV or JSON files (duplicate-safe via ISBN) |
| Database migrations | (automatic) | Automatic schema upgrades and integrity checks at startup |
| Logging system | (internal) | Records all operations and migrations in an internal log table |
| Multilanguage (i18n) | librius --lang <code> |
Fully localized CLI (commands, help, messages); --lang flag and config key |
| Dynamic help system | librius help <command> |
Ordered and grouped help output using display_order() and next_help_heading() |
List all books or a specific book by ID.
$ librius list [--short] [--id <ID>] [--details] [--compact]Options:
--shortCompact view--idShow book by ID--detailsShow extended metadata (requires--id)--compactCompact list view (requires--details)--helpShow command help
Search for books by title, author, editor, genre, or language.
$ librius search <query> [--short]Options:
--shortShow compact view (ID, Title, Author, Editor, Year, ISBN)<query>Search term--helpShow command help
Add a new book using its ISBN.
$ librius add book --isbn <ISBN>Options:
--isbn <ISBN>ISBN of the book to add--helpShow command help
Edit an existing book by ID or ISBN.
$ librius edit book <ID/ISBN> [--title <TITLE>] [--author <AUTHOR>] [--editor <EDITOR>] [--year <YEAR>] [--genre <GENRE>] [--language <LANGUAGE>] [--isbn <ISBN>]Options:
<ID/ISBN>ID or ISBN of the book to edit--title <TITLE>New title--author <AUTHOR>New author--editor <EDITOR>New editor--year <YEAR>New publication year--genre <GENRE>New genre--language <LANGUAGE>New language--isbn <ISBN>New ISBN--helpShow command help
Delete a book by ID or ISBN.
$ librius del <ID/ISBN> [--force]Options:
<ID/ISBN>ID or ISBN of the book to delete--forceSkip confirmation prompt--helpShow command help
Manage application configuration.
$ librius config [--print] [--init] [--edit] [--editor <EDITOR>]Options:
--printPrint current configuration--initCreate default config file--editOpen config file in editor--editor <EDITOR>Specify editor (default:$EDITORornano--helpShow command help
Manage the Librius database lifecycle and backups.
librius db [--init] [--reset] [--copy -f|--file <NEW_FILE>]Options:
--initInitialize a new database--resetReset the database (deletes all data)--copy -f|--file <NEW_FILE>Copy the database to a new file--helpShow command help
Create a backup of the database.
$ librius backup [--compress]Options:
--compressCreate a compressed backup (.zipor.tar.gz)--helpShow command help
Export library data to CSV, JSON, or XLSX.
$ librius export [--csv | --json | --xlsx] [-o|--output <FILE>]Options:
--csvExport as CSV (default)--jsonExport as JSON--xlsxExport as XLSX-o, --output <FILE>Specify output file path--helpShow command help
Import library data from CSV or JSON.
$ librius import --file <FILE> [--json] [--csv] [-d|--delimiter <CHAR>]Options:
--file <FILE>Path to input file--jsonSpecify if the input file is JSON (default is CSV)--csvSpecify if the input file is CSV-d, --delimiter <CHAR>Specify CSV delimiter (default:,)--helpShow command help
- Every command is fully localized in english (default) and italian.
Librius now supports a multilingual interface.
| Source | Description |
|---|---|
| 🇬🇧 en.json | Default English messages |
| 🇮🇹 it.json | Italian translation |
| 📄 README.md | Located in src/i18n/locales/, describes key naming conventions |
- On startup, Librius loads the language defined in:
- CLI argument --lang / -l
- Configuration file language:
- Fallback to English (en)
- All user-visible messages (print_info, print_err, etc.) are translated dynamically.
- Missing keys automatically fall back to their key name or English equivalent.
# Default (English)
librius list
# Force Italian interface
librius --lang it list# librius.conf
database: "C:/Users/YourName/AppData/Roaming/librius/librius.sqlite"
language: "it" # Set default language to ItalianAll translations are stored in:
src/i18n/locales/
├── en.json
├── it.json
└── README.mdEach .json file contains key–value pairs like:
{
"app.config.loading": "Loading configuration...",
"db.init.ok": "Database created successfully.",
"book.add.ok": "Book '{title}' added successfully!"
}Variables can be inserted at runtime:
tr_with!("db.path.open_existing", & [("path", & db_path)]);Full details in
STRUCTURE.md.
src/
├── main.rs # binary entry-point
├── lib.rs # library root — explicit public API
│
├── cli/
│ ├── args.rs # clap command tree (localised)
│ ├── dispatch.rs # subcommand → handler routing
│ ├── fields.rs # EDITABLE_FIELDS (CLI concern)
│ └── mod.rs
│
├── commands/ # one handle_* function per command
│ ├── add_book.rs · backup.rs · config.rs · db.rs
│ ├── del_book.rs · edit_book.rs · export.rs
│ ├── import.rs · list.rs · search_book.rs
│ └── mod.rs
│
├── config/
│ ├── load_config.rs # AppConfig, YAML load/save
│ ├── migrate_config.rs
│ └── mod.rs
│
├── db/
│ ├── connection.rs # open / init / ensure_schema
│ ├── migrations.rs # incremental patch system
│ ├── books.rs # CRUD + search_books
│ └── mod.rs
│
├── i18n/
│ ├── loader.rs # tr / tr_s / tr_with
│ ├── mod.rs
│ └── locales/ # en.json · it.json
│
├── models/
│ ├── book.rs # Book struct — pure data + Serde
│ ├── display.rs # BookFull / BookShort (Tabled + i18n)
│ └── mod.rs
│
└── utils/
├── verbose.rs # set_verbose / is_verbose
├── print.rs # icons + print_ok/err/warn/info
├── log.rs # write_log / now_str
├── import_helpers.rs
├── isbn.rs · lang.rs · table.rs
└── mod.rs
See CHANGELOG.md for a detailed list of changes and updates.
Librius now supports full data import/export functionality.
You can export your library to multiple formats:
librius export --csv # CSV (default)
librius export --json # JSON
librius export --xlsx # Excel (XLSX)Exports are automatically saved in your user data directory
(e.g. ~/.config/librius/exports or %APPDATA%\librius\exports).
Import books from CSV or JSON files:
librius import --file examples/books.csv
librius import --file examples/books.json --jsonFeatures:
- Automatic detection of duplicate records via unique
isbn - Skips duplicates gracefully (no interruption)
- Transaction-safe import
- Verbose mode logs skipped ISBNs
Example output:
📘 Skipped duplicate ISBN: 978-0-345-33968-3
✅ Imported 6 records from CSV file.git clone https://github.com/umpire274/librius.git
cd libriuscargo build
cargo run -- listIf this is the first launch, Librius will automatically create:
- The config file at
~/.config/librius/librius.conf - A SQLite database at
~/.config/librius/librius.sqlite
$ librius list
📚 Your Library
- The Hobbit (J.R.R. Tolkien) [1937]
- Foundation (Isaac Asimov) [1951]
- Dune (Frank Herbert) [1965]
# librius.conf
database: "C:/Users/YourName/AppData/Roaming/librius/librius.sqlite"
language: "en"- Configuration file is automatically migrated if fields are missing or renamed.
- Default path:
- macOS/Linux → $HOME/.librius/librius.conf
- Windows → %APPDATA%\Roaming\librius\librius.conf
Librius follows a strict single-responsibility module structure:
- Each
.rsfile has one cohesive concern (data, display, log, print, …). lib.rsexposes only an explicit, minimal public API — no wildcard re-exports.- Internal modules always use full
crate::x::ypaths; no implicit crate-root shortcuts. - DB migrations run exactly once, inside
db::connection::start_db().
use librius::config::AppConfig;
use librius::db;
use librius::commands::handle_list;
use librius::utils::isbn::normalize_isbn;
use librius::i18n::tr;The API and user-facing documentation for Librius is available on docs.rs:
- Online: https://docs.rs/librius
To generate and view the documentation locally run:
cargo doc --no-deps --openThis will build the documentation and open it in your default browser.
- clap — Command-line argument parsing
- rusqlite — SQLite database integration
- serde / serde_json — Serialization/deserialization
- serde_yaml — YAML config parsing
- umya-spreadsheet — XLSX file creation
- csv — CSV import/export
- colored — Colored terminal output
- chrono — Date and time utilities
Librius automatically verifies and upgrades the SQLite database schema at startup.
The latest migration adds a unique index on isbn to guarantee
that duplicate imports are ignored safely.
CREATE UNIQUE INDEX IF NOT EXISTS idx_books_isbn ON books (isbn);
- On first launch → creates books table.
- On subsequent launches → runs pending migrations silently.
- Migration results are recorded in the log table.
Each migration patch (PATCH_001, PATCH_002, …) is applied once and recorded in the internal log table.
The process is fully idempotent — no duplicate operations are ever performed.
📘 Applying database patch: PATCH_002
✅ All pending migrations applied.
✅ Database schema is up-to-date.| id | date | operation | target | message |
|---|---|---|---|---|
| 1 | 2025-10-13T21:45:12+02:00 | DB_CREATED | DB | Created new database |
| 2 | 2025-10-13T21:45:13+02:00 | DB_MIGRATION_OK | DB | Schema updated successfully |
🔍 Verbose mode
Run Librius in diagnostic mode to display all internal initialization steps:
librius --verbose listOutput example:
📘 Loading configuration...
📘 Opening existing database at: C:\Users\A.Maestri\AppData\Roaming\librius\librius.db
✅ Database schema is up-to-date.
✅ Configuration verified.
📚 Your LibraryIn normal mode, only command output is displayed.
cargo run -- listRUST_LOG=debug cargo run -- add "Neuromancer"cargo fmt
cargo clippy- Add optional TUI (Text UI) with
ratatui - Web dashboard sync
docs.rsfull documentation coverage
Umpire274 GitHub: @umpire274
This project is licensed under the MIT License — see the LICENSE
Contributions, feature requests, and ideas are welcome! If you’d like to contribute, please open a pull request or start a discussion.
If you enjoy this project, please ⭐ star the repository — it helps visibility and development motivation!