arxiv-dl

Ruby gem to download papers and metadata from arxiv.org for offline archives.

For each paper it produces a self-contained per-paper folder with:

  • The PDF
  • The single-page abstract HTML
  • The full HTML version (with images and a deduplicated, cross-paper shared assets cache)
  • The TeX/LaTeX source tarball, extracted
  • Four sidecar metadata files: metadata.md, metadata.yaml, metadata.json, metadata.bib

Installation

gem install arxiv-dl

Or in a Gemfile:

gem 'arxiv-dl'

CLI usage

arxiv-dl <ARXIV_ID_OR_URL> [<ARXIV_ID_OR_URL>...]

Accepted input forms:

Form Example
Bare ID 2508.16190
Prefixed ID arXiv:2508.16190
Legacy ID cs/0002001, alg-geom/9708001
Versioned ID 2508.16190v1
Abstract URL https://arxiv.org/abs/2508.16190
PDF URL https://arxiv.org/pdf/2508.16190.pdf
HTML URL https://arxiv.org/html/2508.16190

Flags

Flag Description
-p PATH, --path PATH Root download directory
--rate-limit SECONDS Seconds between HTTP requests; 0 disables throttling
-v, --verbose Print step lines and per-request URL/byte logs to stdout
-q, --quiet Print nothing; success/failure conveyed via exit code
--version Print the gem version and exit
-h, --help Print help and exit

-v and -q are mutually exclusive.

Environment variables

Variable Effect
ARXIV_DOWNLOAD_PATH Root download directory (default: $HOME/Downloads/ArXiv_Papers)
ARXIV_RATE_LIMIT Seconds between HTTP requests (default: 3, per arxiv etiquette; 0 disables)

Precedence: CLI flag > ENV var > default.

Examples

Download a single paper to the default location:

arxiv-dl 2508.16190

Download to a custom directory:

arxiv-dl --path ~/Archives/arxiv 2508.16190

Download multiple papers, verbose:

arxiv-dl -v 2508.16190 1207.7214 cs/0002001

Disable rate limiting (when running against a local mirror, etc):

arxiv-dl --rate-limit 0 2508.16190

Output layout

$ARXIV_DOWNLOAD_PATH/                   # default: $HOME/Downloads/ArXiv_Papers
  _shared/                              # cross-paper deduplicated static assets
    arxiv.org/static/...
    cdn.jsdelivr.net/...
  YYYY/MM/DD/<primary_category>/<arxiv-id>-<slug>/
    <arxiv-id>.pdf
    <arxiv-id>-abstract.html
    metadata.md                         # YAML frontmatter + Markdown body
    metadata.yaml
    metadata.json
    metadata.bib                        # upstream BibTeX, falls back to synthesized
    html/
      <arxiv-id>.html                   # path-rewritten to local assets
      x1.png, x2.png, ...               # paper-specific images
    src/
      *.tex, *.bbl, ...                 # extracted from /src/<id> tarball

YYYY/MM/DD is the original submission date. <primary_category> is from the paper's metadata (cs.CL, math.NT, etc). <slug> is derived from the paper title (Unicode → ASCII, hyphenated, truncated to 80 chars at a word boundary).

For legacy IDs containing / (e.g. cs/0002001), the slash is replaced with - in the directory name (cs-0002001-...).

Library usage

require 'arxiv/downloader'

identifier = Arxiv::Downloader::Identifier.new '2508.16190'
client     = Arxiv::Downloader::Client.new                # 3-second rate limit by default
path       = Arxiv::Downloader::Archive.new(identifier, root: '/tmp/papers', client: client).run
# => "/tmp/papers/2025/08/22/cs.CL/2508.16190-comicscene154-a-scene-dataset-for-comic-analysis"

Development

script/setup    # install dependencies
script/test     # run specs and rubocop
script/console  # interactive prompt

License

MIT — see LICENSE.md.

Code of Conduct

See CODE_OF_CONDUCT.md.