MCPInstall

r-cli

Comprehensive R package for command-line interface styling, semantic messaging, and user communication. Use this skill when working with R code that needs to: (1) Format console output with inline markup and colors, (2) Display errors, warnings, or messages with cliabort/cliwarn/cliinform, (3) Show progress indicators for long-running operations, (4) Create semantic CLI elements (headers, lists, alerts, code blocks), (5) Apply themes and customize output styling, (6) Handle pluralization in user-facing text, (7) Work with ANSI strings, hyperlinks, or custom containers. Also use when migrating from base R message/warning/stop, debugging cli code, or improving existing cli usage.

Installs
73
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/posit-dev/skills --skill r-cli
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads r-cli automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

CLI for R Packages

When to Use What

task: Display error with context and formatting use: cli_abort() with inline markup and bullet lists

task: Show warning with formatting use: cli_warn() with inline markup

task: Display informative message use: cli_inform() with inline markup

task: Show progress for counted operations use: cli_progress_bar() with total count

task: Show simple progress steps use: cli_progress_step() with status messages

task: Format code or function names use: {.code ...} or {.fn package::function}

task: Format file paths use: {.file path/to/file}

task: Format package names use: {.pkg packagename}

task: Format variable names use: {.var variable_name}

task: Format values use: {.val value}

task: Handle singular/plural text use: {?s} or {?y/ies} with pluralization

task: Create headers use: cli_h1(), cli_h2(), cli_h3()

task: Create alerts use: cli_alert_success(), cli_alert_danger(), cli_alert_warning(), cli_alert_info()

task: Create lists use: cli_ul(), cli_ol(), cli_dl() with cli_li()

Inline Markup Essentials

Use inline markup with {.class content} syntax to format text:

# Basic formatting
cli_text("Function {.fn mean} calculates averages")
cli_text("Install package {.pkg dplyr}")
cli_text("See file {.file ~/.Rprofile}")
cli_text("{.var x} must be numeric, not {.obj_type_of {x}}")
cli_text("Got value {.val {x}}")

# Code formatting
cli_text("Use {.code sum(x, na.rm = TRUE)}")

# Paths and arguments
cli_text("Reading from {.path /data/file.csv}")
cli_text("Set {.arg na.rm} to TRUE")

# Types and classes
cli_text("Object is {.cls data.frame}")

# Emphasis
cli_text("This is {.emph important}")
cli_text("This is {.strong critical}")

# Fields
cli_text("The {.field name} field is required")

Vector Collapsing

Vectors are automatically collapsed with commas and "and":

pkgs <- c("dplyr", "tidyr", "ggplot2")
cli_text("Installing packages: {.pkg {pkgs}}")
#> Installing packages: dplyr, tidyr, and ggplot2

files <- c("data.csv", "script.R")
cli_text("Found {length(files)} file{?s}: {.file {files}}")
#> Found 2 files: data.csv and script.R

Escaping Braces

Use double braces {{ and }} to escape literal braces:

cli_text("Use {{variable}} syntax in glue")
#> Use {variable} syntax in glue

For complete markup reference: See references/inline-markup.md for all 50+ inline classes, edge cases, nesting rules, and advanced patterns.

Pluralization Basics

Use {?} for pluralization with three patterns:

Single Alternative

nfile <- 1
cli_text("Found {nfile} file{?s}")
#> Found 1 file

nfile <- 3
cli_text("Found {nfile} file{?s}")
#> Found 3 files

Two Alternatives

ndir <- 1
cli_text("Found {ndir} director{?y/ies}")
#> Found 1 directory

ndir <- 5
cli_text("Found {ndir} director{?y/ies}")
#> Found 5 directories

Three Alternatives (zero/one/many)

nfile <- 0
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 0 files: no files

nfile <- 1
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 1 file: the file

nfile <- 3
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 3 files: the files

Helpers: qty() and no()

Use no() to display "no" instead of zero:

nfile <- 0
cli_text("Found {no(nfile)} file{?s}")
#> Found no files

Use qty() to set quantity explicitly:

nupd <- 3
ntotal <- 10
cli_text("{nupd}/{ntotal} {qty(nupd)} file{?s} {?needs/need} updates")
#> 3/10 files need updates

For advanced pluralization: See references/inline-markup.md for edge cases and complex patterns.

CLI Conditions: Core Patterns

Use cli conditions instead of base R for better formatting:

cli_abort() - Formatted Errors

# Before (base R)
stop("File not found: ", path)

# After (cli)
cli_abort("File {.file {path}} not found")

# With bullets for context
check_file <- function(path) {
  if (!file.exists(path)) {
    cli_abort(c(
      "File not found",
      "x" = "Cannot read {.file {path}}",
      "i" = "Check that the file exists"
    ))
  }
}

cli_warn() - Formatted Warnings

# Before (base R)
warning("Column ", col, " has missing values")

# After (cli)
cli_warn("Column {.field {col}} has missing values")

# With context
cli_warn(c(
  "Data quality issues detected",
  "!" = "Column {.field {col}} has {n_missing} missing value{?s}",
  "i" = "Consider using {.fn tidyr::drop_na}"
))

cli_inform() - Formatted Messages

# Before (base R)
message("Processing ", n, " files")

# After (cli)
cli_inform("Processing {n} file{?s}")

# With structure
cli_inform(c(
  "v" = "Successfully loaded {.pkg dplyr}",
  "i" = "Version {packageVersion('dplyr')}"
))

Bullet Types

  • "x" - Error/problem (red X)
  • "!" - Warning (yellow !)
  • "i" - Information (blue i)
  • "v" - Success (green checkmark)
  • "*" - Bullet point
  • ">" - Arrow/pointer

For advanced error design: See references/conditions.md for error design principles, rlang integration, testing strategies, and real-world patterns.

Basic Progress Indicators

Simple Progress Steps

process_data <- function() {
  cli_progress_step("Loading data")
  data <- load_data()

  cli_progress_step("Cleaning data")
  clean <- clean_data(data)

  cli_progress_step("Analyzing data")
  analyze(clean)
}

Basic Progress Bar

process_files <- function(files) {
  cli_progress_bar("Processing files", total = length(files))

  for (file in files) {
    process_file(file)
    cli_progress_update()
  }
}

Auto-Cleanup

Progress bars auto-close when the function exits:

process <- function() {
  cli_progress_bar("Working", total = 100)
  for (i in 1:100) {
    Sys.sleep(0.01)
    cli_progress_update()
  }
  # No need to call cli_progress_done() - auto-closes
}

For advanced progress: See references/progress.md for nested progress, custom formats, parallel processing, all progress variables, and Shiny integration.

Semantic CLI Elements

Headers

cli_h1("Main Section")
cli_h2("Subsection")
cli_h3("Detail")

Alerts

cli_alert_success("Operation completed successfully")
cli_alert_danger("Critical error occurred")
cli_alert_warning("Potential issue detected")
cli_alert_info("Additional information available")

Text and Code

# Regular text with markup
cli_text("This is formatted text with {.emph emphasis}")

# Code blocks
cli_code(c(
  "library(dplyr)",
  "mtcars %>% filter(mpg > 20)"
))

# Verbatim text (no formatting)
cli_verbatim("This is displayed exactly as-is: {not interpolated}")

Lists

# Unordered list
cli_ul()
cli_li("First item")
cli_li("Second item")
cli_end()

# Ordered list
cli_ol()
cli_li("First step")
cli_li("Second step")
cli_end()

# Definition list
cli_dl()
cli_li(c(name = "The name field"))
cli_li(c(email = "The email address"))
cli_end()

Common Workflows

Base R to CLI Migration

# Before: Base R error handling
validate_input <- function(x, y) {
  if (!is.numeric(x)) {
    stop("x must be numeric")
  }
  if (length(y) == 0) {
    stop("y cannot be empty")
  }
  if (length(x) != length(y)) {
    stop("x and y must have the same length")
  }
}

# After: CLI error handling
validate_input <- function(x, y) {
  if (!is.numeric(x)) {
    cli_abort(c(
      "{.arg x} must be numeric",
      "x" = "You supplied a {.cls {class(x)}} vector",
      "i" = "Use {.fn as.numeric} to convert"
    ))
  }

  if (length(y) == 0) {
    cli_abort(c(
      "{.arg y} cannot be empty",
      "i" = "Provide at least one element"
    ))
  }

  if (length(x) != length(y)) {
    cli_abort(c(
      "{.arg x} and {.arg y} must have the same length",
      "x" = "{.arg x} has length {length(x)}",
      "x" = "{.arg y} has length {length(y)}"
    ))
  }
}

Error Message with Rich Context

check_required_columns <- function(data, required_cols) {
  actual_cols <- names(data)
  missing_cols <- setdiff(required_cols, actual_cols)

  if (length(missing_cols) > 0) {
    cli_abort(c(
      "Required column{?s} missing from data",
      "x" = "Missing {length(missing_cols)} column{?s}: {.field {missing_cols}}",
      "i" = "Data has {length(actual_cols)} column{?s}: {.field {actual_cols}}",
      "i" = "Add the missing column{?s} or check for typos"
    ))
  }

  invisible(data)
}

Function with Progress Bar

process_files <- function(files, verbose = TRUE) {
  n <- length(files)

  if (verbose) {
    cli_progress_bar(
      format = "Processing {cli::pb_bar} {cli::pb_current}/{cli::pb_total} [{cli::pb_eta}]",
      total = n
    )
  }

  results <- vector("list", n)

  for (i in seq_along(files)) {
    results[[i]] <- process_file(files[[i]])

    if (verbose) {
      cli_progress_update()
    }
  }

  results
}

Resources & Advanced Topics

Reference Files

  • references/inline-markup.md - Complete catalog of inline classes organized by category, advanced patterns, nesting rules, and real-world examples

  • references/conditions.md - Advanced error design patterns, rlang integration, testing with testthat snapshots, migration guide, and anti-patterns

  • references/progress.md - Nested progress bars, custom formats, all progress variables, parallel processing, Shiny integration, and debugging

  • references/themes.md - Complete theming system with CSS-like selectors, container functions, color palettes, custom themes, and accessibility

  • references/ansi-operations.md - ANSI string operations (align, columns, nchar, etc.), hyperlinks, color detection, testing CLI output, and troubleshooting

External Resources

Related Packages

  • rlang - Condition handling and error objects integrate with cli
  • glue - String interpolation powers cli's {} syntax
  • testthat - Snapshot testing for cli output

FAQ

What does the r-cli skill do?

Comprehensive R package for command-line interface styling, semantic messaging, and user communication. Use this skill when working with R code that needs to: (1) Format console output with inline markup and colors, (2) Display errors, warnings, or messages with cliabort/cliwarn/cliinform, (3) Show progress indicators for long-running operations, (4) Create semantic CLI elements (headers, lists, alerts, code blocks), (5) Apply themes and customize output styling, (6) Handle pluralization in user-facing text, (7) Work with ANSI strings, hyperlinks, or custom containers. Also use when migrating from base R message/warning/stop, debugging cli code, or improving existing cli usage.

How do I install r-cli?

Run npx skills add https://github.com/posit-dev/skills --skill r-cli in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/r-cli/ (personal) or .claude/skills/r-cli/ (project).

Which AI agents can use r-cli?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is r-cli safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains r-cli?

It is published by posit-dev in posit-dev/skills. It has 73 recorded installs.

More from posit-dev/skills

View all →

quarto-authoring

posit-dev/skills

Use when the user is explicitly working with Quarto, .qmd files, quarto.yml, Quarto projects, or Quarto features such as callouts, cross-references, citations, Mermaid diagrams, extensions, websites, books, presentations, and reports. Also use for explicit migration from or comparison with R Markdown, bookdown, blogdown, xaringan, distill, or Jupyter notebooks to Quarto. Do not use for general R Markdown or related-format questions unless Quarto or migration to Quarto is explicitly mentioned.

Docs & Writing1.4K installs

critical-code-reviewer

posit-dev/skills

Rigorously review code or pull requests for correctness, security, accessibility, maintainability, tests, and edge cases. Use when users request a critical code review, want a guided walkthrough of findings, need implementer-facing feedback, or want to prepare, create, or submit a GitHub pull request review.

brand-yml

posit-dev/skills

Create and use brand.yml files for consistent branding across Shiny apps and Quarto documents. Covers: (1) Creating new brand.yml files, (2) Applying to Shiny (R and Python), (3) Using in Quarto, (4) Modifying existing files, and (5) Troubleshooting. Includes complete specifications and integration guides.

Marketing & SEO918 installs

r-package-development

posit-dev/skills

R package development with devtools, testthat, and roxygen2. Use when the user is working on an R package, running tests, writing documentation, or building package infrastructure.

Docs & Writing811 installs

shiny-bslib

posit-dev/skills

Build modern Shiny dashboards and applications using bslib (Bootstrap 5). Use when creating new Shiny apps, modernizing legacy apps (fluidPage, fluidRow/column, tabsetPanel, wellPanel, shinythemes), or working with bslib page layouts, grid systems, cards, value boxes, navigation, sidebars, filling layouts, theming, accordions, tooltips, popovers, toasts, or bslib inputs. Assumes familiarity with basic Shiny.

801 installs

describe-design

posit-dev/skills

Research a codebase and create architectural documentation describing how features or systems work. Use when the user asks to: (1) Document how a feature works, (2) Create an architecture overview, (3) Explain code structure for onboarding or knowledge transfer, (4) Research and describe a system's design. Produces markdown documents with Mermaid diagrams and stable code references suitable for humans and AI agents.

Docs & Writing790 installs

Popular frontend & design skills

View category →

setup-matt-pocock-skills

mattpocock/skills

Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.

Frontend & Design1.1M installs

frontend-design

anthropics/skills

Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.

OfficialFrontend & Design1M installs

hyperframes-animation

heygen-com/hyperframes

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.

prototype

mattpocock/skills

Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.

Frontend & Design999.2K installs

hyperframes-core

heygen-com/hyperframes

The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.

Frontend & Design930.5K installs

vercel-react-best-practices

vercel-labs/agent-skills

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

OfficialFrontend & Design843.1K installs