A local-first desktop application for discovering, managing, and visualizing academic papers from arXiv and other sources. It bundles a native Rust backend (bundled SQLite storage, arXiv/OpenAlex/CrossRef sources, PDF text extraction, BibTeX/Obsidian export) with a React + TypeScript frontend and an interactive paper–author graph, all wrapped in a Tauri v2 desktop shell.
Upload your PDFs, create projects, manage notes, tags, and annotations to organize your library; all locally. linXiv aims to be a one-stop shop for researchers managing their literature, with the near-term goal of extending to research groups who want to share knowledge without going to the web.
Development status: Pre-1.0 (
0.5.x). The schema is still evolving, but migration structure is in-place.
Licensing: linXiv, including the vendored
linxiv-p2psubmodule (src-tauri/crates/p2p), is licensed under Apache-2.0.
Prebuilt installers for Linux, macOS, and Windows are on the releases page — latest release: v0.5.1:
| Platform | Download |
|---|---|
| Linux | .deb, .rpm, or .AppImage |
| macOS (Apple silicon) | .dmg (arm64) |
| macOS (Intel) | raw app binary (x86_64, no .dmg) |
| Windows | .exe (NSIS) or .msi |
The macOS and Windows builds are unsigned.
macOS: On macOS 15 (Sequoia) and later, Apple removed the right-click → Open Gatekeeper bypass. The first launch will say "linXiv is damaged and can't be opened." This is not a broken download; it's Gatekeeper blocking an unsigned app. To open it:
xattr -cr /Applications/linXiv.app in a terminal to strip the quarantine attribute, then launch normally.On macOS 14 and earlier, right-click the app → Open still works to get past Gatekeeper the first time.
Windows: click More info → Run anyway on the SmartScreen prompt.
You can install linxiv via pip! It ships with a small API to programatically control your database in python and can be installedi as such
pip install linxiv # everything below
pip install "linxiv[app]" # same, extras are opt-in markers only
pip install "linxiv[cli]"
To build from source instead, start at Clone.
This repo has git submodules (docs/adr, src-tauri/crates/p2p). The npm scripts that touch Rust (tauri, dev:api, build:all) init them for you, so a plain git clone is fine if you build through npm. Cloning with submodules up front is still the fastest path, and is required if you run cargo directly inside src-tauri/:
git clone --recurse-submodules https://github.com/linxiv-dev/linXiv.git
# already cloned without --recurse-submodules?
git submodule update --init --recursive
linxiv paper fetch-source / index-sources), or the fetch_full_text MCP tool; library search then matches the paper's body, not just its metadata..lxproj archives, import BibTeX (.bib), and export projects to BibTeX, Obsidian-flavored Markdown, or Zotero CSL JSON. Zotero CSL JSON import is CLI- and MCP-only (linxiv zotero import / the import_zotero MCP tool).linxiv CLI and an linxiv-mcp MCP server expose the same library over the terminal and to LLM clients such as Claude.linXiv is a Tauri v2 app. The frontend is React 19 + TypeScript (Vite); the backend is native Rust and runs in-process inside the app: the webview calls it through a single api Tauri command over IPC, and streams PDF bytes over a custom linxiv:// scheme. SQLite (bundled, FTS5) and PDF extraction (native libpdfium) are compiled in; see docs/architecture.md for the full workspace layout.
See docs/requirements.md for the copy-pasteable install commands per OS, exact version reasoning, and what to do when pkg-config reports gdk-3.0 missing.
npm install # frontend dependencies
bash scripts/fetch_pdfium.sh # native libpdfium (PDF import/extraction; also a bundled Tauri resource, see below)
bash scripts/stage_rust_bins.sh # builds + stages the linxiv/linxiv-mcp sidecars (see below)
Rust crates are fetched automatically on first cargo/tauri build.
Both scripts above are required before
cargo check/cargo build/tauri devwill even compile, not just for a fulltauri build(they stage gitignored paths thattauri-buildvalidates at compile time). See docs/build.md if you hit aresource path ... doesn't existerror.
Native desktop window (recommended: runs the in-process Rust backend, hot-reloads the frontend):
npm run tauri dev
Browser-only dev loop (no native window; uses a dev-only HTTP shim that serves the backend over /api):
# terminal 1 — dev backend (linxiv-dev-server, HTTP shim over the Rust core)
npm run dev:api
# terminal 2 — Vite dev server on :5180 (proxies /api to the shim)
npm run dev
The linxiv (CLI) and linxiv-mcp (MCP server) binaries ship inside the app as Tauri sidecars.
Fresh checkout, "just give me an installer":
npm run build:all # = build:sidecar + tauri build
build:all is only a convenience wrapper. The steps under it are
independently re-runnable, and most of them are one-time setup — a repeat
build usually only needs npm run tauri build:
| Command | What it does | When you need it |
|---|---|---|
bash scripts/fetch_pdfium.sh |
downloads the pinned native libpdfium into src-tauri/vendor/pdfium/ |
once per machine/OS; again only when the pin in the script changes |
bash scripts/stage_rust_bins.sh |
builds linxiv-cli + linxiv-mcp and stages them into src-tauri/binaries/ |
after changing the CLI/MCP crates — otherwise the previously staged sidecars ship as-is |
npm run build:sidecar |
both of the above | fresh checkout / new host |
npm run tauri build |
builds and bundles the app | always — this is the actual build |
npm run build:arch |
builds an Arch Linux pacman package | only when packaging for Arch |
The installer/bundle is written to src-tauri/target/release/bundle/.
After installing the app, open Settings to:
linxiv binary to ~/.local/bin/linxiv (Linux/macOS) or writes a PATH shim on Windows.The linxiv binary is a headless interface to the same library the app uses. In a checkout you can run it without installing:
# from src-tauri/
cargo run -p linxiv-cli -- --help
Installed (via the app's Install CLI, or a staged/bundled build), invoke it directly as linxiv. All commands print JSON to stdout; pass --help to any command or subcommand for full options.
linxiv --version
linxiv search "attention is all you need" --max 5
linxiv fetch 2204.12985
linxiv paper get 2204.12985
Covers papers, tags, projects, notes, PDF annotations, PDFs, DOI resolution, the arXiv RSS home feed, authors, ORCID backfill, BibTeX import, Zotero import/export, arXiv version monitoring, trash, and library maintenance; see docs/cli_ref/ for the full command reference.
linxiv-mcp is a stdio MCP server exposing ~75 tools (search, fetch, papers, projects, tags, notes, annotations, PDFs, trash, authors, import/export, settings, stats) so an MCP client like Claude can drive your library directly. paper_ref returns a citation handle linxiv://paper/{source_fk}?v={version} pinned to a stored version; paste it into notes and pass handles to resolve_refs to check each one is still current, stale, or unknown.
The simplest path is to install the desktop app and use Settings → Integrations, which registers the bundled server with a detected client.
To register manually with the Claude Code CLI, point it at the built or bundled binary:
claude mcp add linxiv -- /path/to/linxiv-mcp
Or add it to a client's MCP config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"linxiv": {
"command": "/path/to/linxiv-mcp"
}
}
}
In a checkout you can run it straight from source with cargo run -p linxiv-mcp (from src-tauri/).
linxiv-headless runs the full backend — the complete /api/* surface,
the iroh share peer, and background sync — with no window, for a
self-hosted or containerized always-on node. Run it from source
(cargo run -p linxiv-server --bin linxiv-headless from src-tauri/) or
build the repo's Dockerfile; a bearer token gates the API when it
binds beyond loopback, and GET /admin serves a small management page.
Setup steps, a ready-made compose file, the environment reference, and
relay configuration: docs/headless.
Papers and authors make up a force-directed network: papers link to their authors and tags, laid out by a d3-force simulation and drawn with Cytoscape. The control panel gives you real-time sliders to steer how the nodes and links work together, plus filters over categories, dates, tags and projects. Everything — the graph libraries, MathJax and the UI font — is bundled locally, so the graph works offline like the rest of the app.
The database (papers.db), managed PDFs, and the Obsidian vault live in the per-user app data directory for com.linxiv.app (e.g. ~/.local/share/com.linxiv.app on Linux, ~/Library/Application Support/com.linxiv.app on macOS). Set the LINXIV_DATA_DIR environment variable to override the location; the app, CLI, and MCP server all honor it, so they share one library.
See CONTRIBUTING.md for branch naming, commit messages, and how PRs reach a release.
Thank you to arXiv for use of its open access interoperability!
PDF text and metadata extraction is currently powered by PDFium (Google's PDF rendering library) via the pdfium-render Rust bindings.