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 is GPLv3. The vendored
linxiv-p2psubmodule (src-tauri/crates/p2p) is licensed separately 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:
- Try launching the app once (it will fail with the "damaged" message), then go to System Settings → Privacy & Security and click Open Anyway next to the linXiv block notice, or
- Run
xattr -cr /Applications/linXiv.appin 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- Install
- Clone
- Features
- Architecture
- Setup
- Building the desktop app
- CLI
- MCP server
- Headless server
- Graph visualization
- Data location
- Acknowledgements
- Paper search & fetch — Search arXiv, OpenAlex, or CrossRef by keyword; fetch by ID; resolve by DOI (arXiv → Semantic Scholar → CrossRef fallback). Results are saved to a local SQLite database with per-paper version tracking.
- Projects — Organize papers into projects; scope notes and highlight annotations to a paper within a project; archive, restore, and trash with soft-delete.
- Notes & PDF annotations — Attach freeform notes and PDF highlight annotations to papers, optionally scoped to a project.
- Tags — Tag papers and projects; list and manage the full tag set.
- PDF management — Download PDFs, import local PDFs (with first-page text and metadata extraction via native PDFium), and track total storage usage.
- Full-text search — Pull an arXiv paper's TeX source into a local SQLite FTS5 index, from the paper page, the CLI (
linxiv paper fetch-source/index-sources), or thefetch_full_textMCP tool; library search then matches the paper's body, not just its metadata. - Import / export — Import and export projects as
.lxprojarchives, import BibTeX (.bib), and export projects to BibTeX or Obsidian-flavored Markdown. - Interactive graph — Force-directed network of papers, authors and tags (Cytoscape rendering a d3-force layout), with real-time force controls and filter panels.
- TeX rendering — MathJax renders LaTeX math in titles and abstracts, bundled locally for full offline use.
- CLI & MCP server — A headless
linxivCLI and anlinxiv-mcpMCP server expose the same library over the terminal and to LLM clients such as Claude. - Peer-to-peer project sharing — Share a project over iroh (QUIC + node tickets, no relay server to run) with end-to-end encrypted sync via keyhive + beelay CRDTs; you're the Hoster or a Reader of a share, and a Hoster can invite members as Editor or Viewer; join with a pasted ticket, mirror shared projects into your local library, and sync on your own schedule.
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.
- Rust toolchain (stable, 1.85+) — builds the backend, CLI, MCP server, and Tauri shell
- Node.js 20.16+ (22+ recommended) — frontend / Tauri tooling
- System libraries — GTK 3, WebKit2GTK 4.1, and GLib on Linux; Xcode Command Line Tools on macOS; Microsoft C++ Build Tools on Windows
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 devBrowser-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 devThe 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 buildbuild: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:
- Install CLI — symlinks the bundled
linxivbinary to~/.local/bin/linxiv(Linux/macOS) or writes a PATH shim on Windows. - Integrations — register the bundled MCP server with a detected client (Claude Desktop, Claude Code, and others) by writing its config file.
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 -- --helpInstalled (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.12985Covers papers, tags, projects, notes, PDF annotations, PDFs, DOI resolution, authors, BibTeX import, 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.
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-mcpOr 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.
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.
