CRAN Submission Policy — check your r package before submission

Check an R package against the CRAN Repository Policy before you submit: DESCRIPTION fields, licence strings, library() in R/, setwd(), unrestored options()/par(), T/F, ::: and more. Runs entirely in your browser — nothing is uploaded.

Sweep the whole package and keep the dated report — $29 once $29 once · one licence key per person or CI seat · A freelance R developer in North America bills $50-$100 an hour (Upwork, 2026).

Same engine as the VS Code extension, byte for byte.

Install free

Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.

VS Code MarketplaceOpen VSX (Cursor, VSCodium)npmDocker Hub
ext install ReadyStack.cran-policy-submission-lint
npx @readystack/cran-policy-submission-lint <file>
docker run --rm -v "$PWD:/w" getreadystack/cran-policy-submission-lint /w

Team? One key for every ReadyStack linter, 5 seats, $149 once

Get the full rule table as a PDF
All 25 rules CRAN Policy Submission Lint checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.

Get the full version $29

Sweep the whole package - every R/ file, DESCRIPTION and NAMESPACE together - and write a dated pre-submission report you keep and can paste into your submission comments.

One payment, one licence key for this tool. The key is shown right after payment.

A freelance R developer in North America bills $50-$100 an hour (Upwork, 2026); one rejected submission is a round trip of rework plus a wait in the queue.

Buy the full version — $29
ENDEJAESPT

Find a tool

· ReadyStack

Worked example

Real numbers from this tool, line by line.

CRAN Policy Submission Lint

Eight CRAN blockers in one paste - for R package maintainers filing to CRAN, from North America to Europe.

== surveytools - 8 of the 28 findings, checked as of 2026-09-13
  ERRO  L4   desc-title-period       Title must not end in a period
  ERRO  L5   desc-version-dev        Version 0.3.1.9000 is a development version
  ERRO  L9   desc-description-start  Description opens with "This package"
  ERRO  L10  desc-license-spec       Bare "MIT" is refused; use "MIT + file LICENSE"
  ERRO  L19  r-library-call          library(dplyr) in R/ - declare it in Imports
  ERRO  L32  r-options-par-restore   par() changed, no on.exit() anywhere in the file
  ERRO  L35  r-internal-access       dplyr:::check_weights() reaches into internals
  ERRO  L37  r-user-filespace        write.csv() to "~/" - write to tempdir() instead

None of the eight is a bug. The package installs, the tests pass, R CMD check --as-cran is quiet about every one of them. They are policy: prose in the CRAN Repository Policy and Writing R Extensions that a volunteer reviewer applies by reading. No tool in the standard R toolchain reads that layer for you, and it decides whether your tarball is accepted this week or next month.

Here is the split. R CMD check computes: an argument you documented but did not declare, an example that errors, an import you forgot. A reviewer judges the eight above - the policy asks you not to open a Description with the package name, refuses a bare MIT string without "+ file LICENSE", forbids attaching packages from R/ because it changes the user's search path, and requires par() to be put back with on.exit().

CRAN Policy Submission Lint encodes 25 of those rules and runs them on the file you have open. Ten cover DESCRIPTION: Title in title case with no trailing period, a Description that is a real sentence and does not begin with the package name, a licence string CRAN accepts, exactly one person() carrying role = "cre", no four-component or .9000 development version, no example.com placeholder address, a Date field neither in the future nor over a month stale, and packages declared under Imports rather than Depends. One covers NAMESPACE: exportPattern(), which ships your internals as public API. Fourteen cover R sources: library() and require(), install.packages(), setwd(), options()/par()/Sys.setenv() with no on.exit(), writes to ~/ instead of tempdir(), T and F, print() and cat() where message() belongs, \dontrun{}, non-ASCII characters, <<- and assign() to .GlobalEnv, installed.packages(), set.seed() inside a function, ::: into another package, and source() at package level.

The sample package that ships with the extension is one DESCRIPTION, one NAMESPACE and one R file. Run it through and you get 28 findings - 18 errors and 10 warnings - which is every one of the 25 rules firing at least once; the block above is the first eight of them. Run the corrected version of the same three files and you get zero.

R that an assistant drafts looks like R from scripts, because scripts are what it learned from - and a script may call library(), may setwd(), may use T. A package may not. Those three are also the cheapest to fix, once someone points at the line.

The cost of not pointing at it is a round trip. CRAN's reviewers are volunteers and submissions queue; a published package that fails gets an email with a dated archival deadline - a named day, after which it leaves the repository and every reverse dependency breaks. A freelance R developer in North America bills $50 to $100 an hour (Upwork, 2026); the rework is not the expensive part, the wait is.

Checking the file you have open is free and uncapped, in VS Code and in the browser tool, which runs the identical engine with nothing uploaded. The licence covers a different axis: sweeping every file in the package at once and writing a dated report you keep, commit beside the tarball, or paste into your submission comments.

15 seconds — what it actually does

Questions people ask

What does CRAN Policy Submission Lint actually check?

It reads an R package's DESCRIPTION, NAMESPACE and R source against 25 rules drawn from the CRAN Repository Policy and Writing R Extensions: Title case and trailing period, Description openings, licence specifications, one cre maintainer, development version numbers, library() in package code, setwd(), unrestored options() and par(), writes outside tempdir(), T and F, ::: and non-ASCII source.

Who is it for?

R package authors submitting to CRAN for the first time, and maintainers who have received a CRAN email with an archival deadline and need to find every policy problem in one pass. It is equally aimed at people whose package code was drafted with an AI assistant, which reliably writes library() calls and T/F into package sources.

Why is R CMD check --as-cran not enough?

R CMD check finds what a program can compute: undocumented arguments, missing imports, broken examples. A large share of CRAN rejections are prose-policy judgements it never evaluates, such as a Description that opens with the package name, a bare MIT licence string, or a package that installs software. This linter reads exactly that layer.

What is free and what needs a licence?

Checking the file you have open is free forever, in the editor and in the browser tool, against all 25 rules with no cap on how often you run it. The licence covers the other axis: sweeping every file in the package at once and writing a dated report file you keep, attach to submission comments, or commit alongside the tarball.

What would this cost me otherwise?

A freelance R developer in North America bills fifty to a hundred dollars an hour according to Upwork's 2026 rate guidance, and a rejected submission costs a rework round trip plus another wait in the CRAN queue. The extension is twenty-nine dollars once,.

Why not just ask ChatGPT or another AI chat?

A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. CRAN Submission Lint - R package policy check (DESCRIPTION, checks the file you open against 25 rules from a rule set dated 2026-09-20, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files.

Ask about this tool

One question, answered by the person who built it. Your email only if you want the answer sent.

Embed this tool on your site (free)

Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.

 All embeddable tools

For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. See Pro →