Skip to content

CLI

The complete command-line surface of the ry binary.

CommandWhat it does
checkRuns code analysis over your project and reports findings
fmtFormats R files, in place or as a diff
serverRuns the language server over stdio
replStarts an interactive R console with an embedded R
runRuns an R file through the embedded R and exits
helpPrints help for the binary or for one command
debugNot stable. Development commands: debug ast dumps a syntax tree, debug analysis-stats reports where analysis time and memory go. Output shape can change at any time

check, fmt, and server need no R installation. repl and run locate and load the R on your machine; their walkthrough lives in ry at the R console.

Two aliases exist: format for fmt, and lsp for server.

FlagArgumentDefaultEffect
-V, --versionPrints ry 0.3.0-alpha and exits 0
-h, --helpPrints help and exits 0. Available on every command
--stdioAccepted and ignored. It exists so VS Code’s default launch arguments do not error
--experimental-featuresFEATURESnoneSpace-separated feature names, or all. Only range_formatting exists today, and only the language server reads it — the flag does nothing for check, fmt, repl, or run. An unknown name prints a warning on stderr and is ignored, not a usage error
Terminal window
ry check # the current directory
ry check R/ tests/ # named directories
ry check R/model.R # one file
ry check --output json # machine-readable, on stdout
ry check --min-severity error # only errors report and gate
FlagArgumentDefaultEffect
positionalFILES....Files and directories to report on. Directories are walked for .R, .r, and literate extensions; renv, packrat, revdep, .Rproj.user, and .Rcheck are skipped, and .gitignore is honored even outside a git checkout. A file you name explicitly is always checked, even when [check] exclude matches it
--outputhuman | jsonhumanhuman renders diagnostics with source snippets on stderr and one summary line on stdout. json writes JSON Lines on stdout and prints no summary
--min-severitywarning | errorwarningFindings below the floor are neither reported nor counted toward the exit code

Analysis always covers the whole project a named path belongs to — the nearest ancestor holding ry.toml or DESCRIPTION, otherwise the target’s own directory — so cross-file names resolve identically however you spell the paths. Only reporting is scoped to what you named.

Type errors are opt-in through [check] typing in ry.toml; the codes themselves are listed in Diagnostic codes.

Terminal window
$ ry check
warning[duplicate]: Top-level binding `value` is overwritten by a later top-level binding in this package.
--> R/main.R:1:1
1 | value <- 1
^^^^^
= note: the later binding is here. --> /home/you/demo/R/main.R:2:1
warning[duplicate]: Top-level binding `value` overwrites an earlier top-level binding in this package.
--> R/main.R:2:1
2 | value <- 2
^^^^^
= note: the earlier binding is here. --> /home/you/demo/R/main.R:1:1
warning[unresolved]: I could not resolve `undefined_thing` in this package, its imports, or builtins.
--> R/main.R:3:11
3 | result <- undefined_thing(3)
^^^^^^^^^^^^^^^
3 problems in 2 files
Terminal window
ry fmt # rewrite files in place
ry fmt --check # list what would change, exit 1 (CI)
ry fmt --diff # show the change without writing, exit 1
FlagArgumentDefaultEffect
positionalFILES....Files and directories to format. Literate documents are walked but deliberately skipped — the formatter rewrites whole-file layout and must not touch prose. [check] exclude does not apply here
--checkoffWrites nothing. Prints Would reformat: <path> per file that would change
--diffoffWrites nothing. Prints a coloured unified diff per changed file. Takes precedence over --check
-v, --verboseoffAdds a throughput line after the summary

All fmt output — diffs, Would reformat: lines, and the summary — goes to stderr. The rules it applies are documented in Formatting rules.

Terminal window
$ ry fmt --diff
Diff in ./messy.R:
1 |-f<-function(x,y){
2 |-x+y
1 |+f <- function(x, y) {
2 |+ x + y
3 3 | }
1 file would be reformatted, 0 files already formatted

Speaks the Language Server Protocol over stdio; editors start it for you.

FlagArgumentDefaultEffect
--debugoffAdds internal analysis facts to hover — a developer aid for working on ry itself. RY_DEBUG=1 is the environment equivalent; the flag wins
--stdioAccepted and ignored (VS Code compatibility)
-v, --verboseoffDeclared but not wired to anything yet

Starts an interactive R console backed by the R installed on your machine, with analysis-backed completion. See ry at the R console.

FlagArgumentDefaultEffect
--keybindingsemacs | viemacsLine-editing keys for the console
-f, --fileFILEnoneRuns this R file before the first prompt, then keeps prompting
Terminal window
$ ry repl
ry R console — R at <the R_HOME it found> (q() or Ctrl-D quits)

Runs one R file through the same embedded R and exits. The file argument is required.

ArgumentRequiredEffect
FILEyesThe R file to execute. A top-level error stops the script and exits 1, the way Rscript behaves

run prints R’s own startup banner; it is not a quiet runner.

check and fmt share one scheme, which is what CI gates on.

Codecheckfmt
0No findings after the --min-severity filter, and no I/O failure. Finding no R files at all is also cleanDefault mode finished, however many files were rewritten; or --check/--diff found nothing to change; or there were no files to format
1At least one finding was counted. Warnings alone are enough at the default severity floor--check or --diff was passed and at least one file would be reformatted
2A usage, configuration, or I/O failure: unparseable ry.toml, a path that does not exist, an invalid exclude pattern, an unreadable source file or stub. This overrides code 1A file could not be read, parsed, or written back. This overrides code 1

The other commands:

Command012
serverAlways, once the server loop returns
runThe script ran to completionAn uncaught top-level R errorR could not be found or loaded, or the file could not be read
replSession ended normallyR could not be found or loaded, or a --file script could not be read
debug astThe tree was printed. Parse errors are listed but do not change the codeThe file could not be read

Any usage error — an unknown flag, a missing required argument, an invalid enum value, or ry with no command at all — exits 2.

ry check --output json writes JSON Lines to stdout: one independent object per finding, no wrapping array, no summary object, nothing else on the stream. Keys are alphabetical.

{"code":"type-mismatch","column":21,"endColumn":27,"endLine":4,"line":4,"message":"expected `integer`, found `character`","path":"/home/you/demo/main.R","related":[],"severity":"error"}
FieldTypeMeaning
pathstringAbsolute path of the file the finding is in
lineinteger1-based start line
columninteger1-based start column, counted in characters — the same number the rendered output and your editor show
endLineinteger1-based end line
endColumninteger1-based end column, exclusive, in characters
severity"warning" | "error"The only two levels the CLI emits
codestringThe diagnostic code — exactly what a # ry: allow(...) comment spells
messagestringThe rendered message
relatedarrayCompanion locations, [] when there are none. Each entry has path, line, column, endLine, endColumn, and message. A duplicate finding names both sites

A related location is dropped when its file is outside the files this run analyzed, rather than reported with an unusable path. Warnings the CLI itself emits — unknown config keys, unreadable files — stay on stderr as human text and never appear as JSON.

These field names are a contract; see Continuous integration for a job that consumes them.