npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

paperlint

v9.0.0

Published

A linter for scientific papers written in LaTeX: catches mistakes before you submit to a conference or journal.

Readme

paperlint

npm version Node version

Write a research paper in LaTeX from idea to camera-ready, and catch what gets it sent back before you submit. It comes in two parts:

  • ✅ A linter — a command-line tool, no AI needed. Its headline catches:

    • 📏 a paper over the page limit for its kind at your venue;
    • 🔤 the wrong font — LaTeX silently fell back to Computer Modern because a package was missing;
    • 🔗 a bad reference — a cited work that does not exist, or lists the preprint's authors.

    Smaller slips too: § for "Section", .05 for 0.05 — fixed for you.

  • 🧠 Skills for Claude Code — optional, covering the whole pipeline: the idea, the venue, the study, the draft, the reviews, submission.

⚠️ An aid, not a guarantee. A clean run does not mean your paper meets the venue's rules: presets are transcribed from calls for papers that change, and any check can miss something. Check against the venue's own call and template. Provided "as is", without warranty — see LICENSE.

Contents

🧭 The pipeline

stage           what you get                          skills  linter
1 idea          a go / no-go, with the reason         yes
2 venue         venues ranked, deadlines planned      yes
3 study         a study design, honest statistics     yes
4 draft         a first draft, then a tighter one     yes     lint
5 review        the objections, before the reviewers  yes     lint
6 submit        a PDF within the limit, recorded      yes     build, lint
7 camera-ready  the final, de-anonymised PDF          yes     build, lint
8 extend        a plan for the next paper             yes

skills: optional, with Claude Code
lint:   every edit and every CI run, once the paper exists (paperlint new)
build:  compiles and measures the PDF; lint then checks pages, fonts, references

🎯 Supported venues

A venue preset holds a venue's format and page limits. A paper's kind picks which limit applies: at AgenticDev a short paper gets 5 pages and a full one 10. You choose it once per paper.

| preset | venue | format | kinds and page limits | | --------------------------- | ------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | paperlint:acm-sigconf | any ACM conference | ACM two-column | no kinds: the format only, no page limit | | paperlint:agenticdev | AgenticDev @ ASE | ACM two-column | short 5, full 10, demo 5 pages, + 2 pages of references | | paperlint:aisec | AISec @ ACM CCS | ACM two-column | research, benchmark, position, sok: 10 pages + 2 pages of references | | paperlint:realm | REALM @ EMNLP | ACL two-column, A4 | long 8, short 4 — recorded, not checked (why) | | paperlint:ieee-conference | any IEEE conference | IEEE two-column | no kinds: the format only, no page limit | | paperlint:aidc | AIDC @ IEEE ACSAC | IEEE two-column, compsoc | regular 12, short 6, counted before the references (why); requires the «LLM Usage Statement»; double-blind | | paperlint:msr | MSR (Technical) | IEEE two-column, no compsoc | technical 10 pages, appendices included, + 2 pages of only references (why); double-blind |

Not shipped yet: USENIX, NeurIPS, Springer, IEEE venues other than AIDC and MSR, and ACL venues other than REALM. Add yours in one small file.

🚀 Getting started

A new paper

  1. Install (Node 22.13 or newer):

    npm i -D paperlint
  2. Set up. init asks three questions: where your papers live (default papers/), whether to install TeX Live now, and whether to add a CI workflow. With Claude Code it also installs the skills and three hooks (what they do).

    npx paperlint init
  3. Create a paper. --venue names its venue preset from the table above, --kind which of its page limits applies. Name the folder after the work, not the venue: a rejected paper moves to another venue and keeps its folder, so new refuses a name like aisec-2026 (--allow-venue-name when the word really is the work's):

    npx paperlint new my-paper --venue agenticdev --kind short

    It writes papers/my-paper/ (in the folder you gave init) with three files:

    • paper.tex — your paper;
    • paperlint.json — its venue preset and kind;
    • PIPELINE-STATUS.md — which stage the paper is at; the skills read and update it.
  4. Build the PDF. This needs TeX Live, a ~270 MB download (~3 min, once). If you said no in init, run npx paperlint toolchain first.

    npx paperlint build papers/my-paper
  5. Check it:

    npx paperlint lint

    On the stub from step 3 the first run already catches something (output shortened):

    papers/my-paper/paper.tex
      1:1   error    1 column(s), AgenticDev requires 2 — the wrong document class or class option   pdf/geometry
      1:1   error    no font starts with `LinLibertine` (body text of AgenticDev); the PDF has: CMR10, …   pdf/fonts
      8:4   warning  `§` instead of the word «Section» — `paperlint lint --fix` writes it              paper/section-word

    new writes a format-neutral stub in plain article, and AgenticDev wants ACM's class. Make the first line \documentclass[sigconf]{acmart}, build again, and the errors are gone.

A paper you already have

paperlint finds a paper by its folder: <papersDir>/<name>/, with the main file named paper.tex.

  1. Put the paper there — for example papers/my-paper/paper.tex, the rest of its files beside it. If your paper folders already live elsewhere, say thesis/, set papersDir instead.
  2. Run npx paperlint new my-paper --venue <preset> --kind <kind>. On an existing folder it only adds the missing paperlint.json and PIPELINE-STATUS.md; it never touches paper.tex.
  3. Build and lint, as above.

🧰 Commands

| command | what it does | | ----------------------------------------------------------- | ------------------------------------------------------------------------------ | | npx paperlint init | sets the project up | | npx paperlint new my-paper --venue <preset> --kind <kind> | creates a paper folder for that venue, or completes an existing one | | npx paperlint build <paper> | compiles paper.tex to paper.pdf, measures it, checks the references online | | npx paperlint lint | runs every check over your papers; --fix fixes what can be fixed | | npx paperlint toolchain | installs TeX Live with the packages your venues need (~270 MB, ~3 min, once) | | npx paperlint doctor | checks the setup and exits non-zero if something is miswired | | npx paperlint submission show <paper> | the paper's submission on the venue's portal, and whether it holds your build | | npx paperlint submission update <paper> | checks a new PDF/abstract against the portal; --save sends it for real | | npx paperlint --help | every command and flag |

🧠 Skills

You do not need to learn the skills' names: you ask Claude Code, and the matching skill starts. paper-pipeline walks you through the stages; any skill also starts on its own when you ask for what it does — "is this idea worth a paper?", "find me a venue for this". init installs them.

  • A go / no-go on your idea, with the reason. research-ideate
  • A ranked list of venues that fit — deadline, page limit, indexing. find-venue
  • A first draft from your results. draft-paper
  • A hostile review before the real one. paper-adversarial-review
  • A ready / not ready verdict before you submit, worst problem first. harden-paper
  • Where your paper stands, measured from the real build. paper-status
  • The PDF and abstract replaced on HotCRP, dry run first, and proof the portal holds your build. submission-portal

Every skill, by stage: docs/skills.md.

🔍 Lint and build

| | paperlint build | paperlint lint | | ------ | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | needs | Node, TeX Live, the network | Node | | does | compiles paper.tex, measures the PDF, checks each reference online (exists, right authors) | checks the source, and judges what build recorded: page limit, fonts, the reference results — offline | | writes | paper.pdf, in _build/ the measurements and the reference results, and repro/references-cache.json | nothing (--fix: the three fixable slips) |

  • If paper.pdf or the bibliography changed since the last build, lint fails and tells you to rebuild.
  • Commit repro/references-cache.json: it keeps what the citation services answered, so a build asks only about new or edited entries (and answers older than 30 days), so an unchanged bibliography usually builds without the network (docs/references.md).
  • A paper whose body is in other files (\input{sections/intro}) is linted file by file: a finding lands at the file and line it is in, and --fix edits that file. The files are the ones TeX read after \begin{document} in the last build (_build/sources.json) — not every .tex beside it, and not an included .bbl (a tool's output, read only as part of the whole paper). A paper that was not built, or changed since, is linted as paper.tex alone, and paper/sources-fresh says so.
  • Lint also checks the pipeline's own records: PIPELINE-STATUS.md, reviews, notes on related papers (docs/rules.md).
  • The rules run on ESLint, so a deliberate exception is a comment on the line above: % eslint-disable-next-line paper/leading-zero -- quoted from the reviewer.
  • Errors fail the run; warnings only print, unless you pass --max-warnings <n>.

Every check: docs/rules.md. How build compiles: docs/configuration.md.

🧩 Configuration

Two levels, one file name, both optional:

paperlint.json                   the project: papersDir, rules, defaults for every paper
papers/my-paper/paperlint.json   one paper: its venue preset ("extends"), its kind, its own rules
  • papersDir is the folder that holds your paper folders; it defaults to papers.
  • The paper's venue preset is its "extends" key — the one new --venue writes.
  • A paper's paperlint.json overrides the project's, key by key.
  • An unknown key is an error, so a typo cannot silently turn a setting off.
  • A paper that moves between venues keeps a list of attempts, cycles, instead of "extends"; each records its deadlines as read from the portal and the call, plus any override the chairs granted, and the earlier reading binds (docs/configuration.md).
  • Deadlines of a shipped venue preset stay current on their own: paperlint's repository re-reads each preset's portal daily and releases a patch when a date moves, so your normal dependency update (Dependabot, Renovate) brings it. paperlint lint itself never reads the clock or the network.

Every key: docs/configuration.md. Already use ESLint for other files? See docs/configuration.md.

➕ Add a venue that isn't listed

A venue preset is a small JSONC file: the preset it builds on, and the page limit of each kind of paper. For an ACM workshop with a 4-page limit for short papers, venues/my-workshop.jsonc:

{
  // page size, columns and fonts of the ACM two-column format
  "extends": "paperlint:acm-sigconf",
  "format": {
    // one entry per kind of paper the call for papers names
    "kinds": {
      // the limit from the call for papers, in pages, references not counted
      "short": { "body_pages_max": 4 },
    },
  },
}
npx paperlint new my-paper --venue ./venues/my-workshop.jsonc --kind short

Give the path from where you run the command; new rewrites it relative to the paper's own paperlint.json. A venue in another format: docs/rules.md.

🤖 Run it in CI

Two options:

| job | time | checks | | -------------------------- | ----------------------------- | ------------------------------------------ | | build, then lint | ~3 min first run, then cached | everything | | lint only (init adds it) | seconds | the source; not pages, fonts or references |

Lint judges pages, fonts and references from what build measured, so the full job builds first:

name: papers
on: [push, pull_request]
jobs:
  papers:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - uses: actions/cache@v4
        with:
          path: ~/.cache/paperlint/texlive
          key: texlive-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
      - run: npx paperlint toolchain
      - run: npx paperlint build --all
      - run: npx paperlint lint

Lint only — each paper then gets one warning that it was not built. Call the action from the installed package, after npm ci: the action and the CLI it runs are then one revision, pinned by your lockfile.

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: 22
  - run: npm ci
  - uses: ./node_modules/paperlint

With no paths it lints the papersDir of your paperlint.json; pass paths: only to lint less.

❓ FAQ

Does it install anything without asking? No. TeX Live comes only from paperlint toolchain, or when you say yes in init or build. On Windows, install TeX Live yourself.

Several papers for different venues in one repo? Yes. Each paper names its own venue preset in its own paperlint.json.

Does it change my paper? Only paperlint lint --fix, and only three rules: paper/section-word (§ → Section), paper/leading-zero (.05 → 0.05) and paper/figure-ref-style (one figure-reference style).

📚 Docs

License

MIT. Banal, used for page geometry, is GPL and not part of this package: docs/toolchain.md.