Learn R Programming


output: rmarkdown::github_document: pandoc_args: ["--wrap=none"]

lintr

{lintr} provides static code analysis for R. It checks for adherence to a given style, identifying syntax errors and possible semantic issues, then reports them to you so you can take action.

For example, given a file bad.R with the following contents:

my_func = function(x){
    if(x > 0){
        print("Positive")
    }
    else {
        print("Not positive")
    }
    return(T)
}

Running lintr::lint() on this file would produce the following output:

lintr::lint("bad.R")
bad.R:1:9: style: [assignment_linter] Use one of <-, <<- for assignment, not =.
my_func = function(x){
        ^
bad.R:1:22: style: [brace_linter] There should be a space before an opening curly brace.
my_func = function(x){
                     ^
bad.R:1:22: style: [paren_body_linter] Put a space between a right parenthesis and a body expression.
my_func = function(x){
                     ^
bad.R:2:4: style: [indentation_linter] Indentation should be 2 spaces but is 4 spaces.
    if(x > 0){
  ~^
bad.R:2:7: style: [spaces_left_parentheses_linter] Place a space before left parenthesis, except in a function call.
    if(x > 0){
      ^
bad.R:2:14: style: [brace_linter] There should be a space before an opening curly brace.
    if(x > 0){
             ^
bad.R:2:14: style: [paren_body_linter] Put a space between a right parenthesis and a body expression.
    if(x > 0){
             ^
bad.R:3:8: style: [indentation_linter] Indentation should be 4 spaces but is 8 spaces.
        print("Positive")
    ~~~^
bad.R:4:4: style: [indentation_linter] Indentation should be 2 spaces but is 4 spaces.
    }
  ~^
bad.R:5:5: style: [brace_linter] `else` should come on the same line as the previous `}`.
    else {
    ^~~~
bad.R:6:8: style: [indentation_linter] Indentation should be 4 spaces but is 8 spaces.
        print("Not positive")
    ~~~^
bad.R:7:4: style: [indentation_linter] Indentation should be 2 spaces but is 4 spaces.
    }
  ~^
bad.R:8:5: style: [return_linter] Use implicit return behavior; explicit return() is not needed.
    return(T)
    ^~~~~~
bad.R:8:13: style: [T_and_F_symbol_linter] Use TRUE instead of the symbol T.
    return(T)
           ~^
bad.R:10:1: style: [trailing_blank_lines_linter] Remove trailing blank lines.

^

{lintr} is complementary to the {styler} package which automatically restyles code, eliminating some of the problems that {lintr} can detect.

Installation

Install the stable version from CRAN:

install.packages("lintr")

Or the development version from GitHub:

# install.packages("remotes")
remotes::install_github("r-lib/lintr")

Usage

And then you can create a configuration file and run selected linters:

lintr::use_lintr(type = "tidyverse")

# in a project:
lintr::lint_dir()

# in a package:
lintr::lint_package()

To see a list of linters included for each configuration:

# tidyverse (default)
names(lintr::linters_with_defaults())

# full
names(lintr::all_linters())

Setting up GitHub Actions

{usethis} provides helper functions to generate lint workflows for GitHub Actions:

# in a project:
usethis::use_github_action("lint-project")

# in a package:
usethis::use_github_action("lint")

You can also run lintr during continuous integration or within your IDE or text editor. See vignette("continuous-integration") and vignette("editors") for more details.

Without further configuration, this will run the default linters. See vignette("lintr") to learn how to modify these defaults.

Code of Conduct

Please note that the lintr project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.

Copy Link

Version

Install

install.packages('lintr')

Monthly Downloads

76,512

Version

3.4.0

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Michael Chirico

Last Published

July 16th, 2026

Functions in lintr (3.4.0)

commented_code_linter

Commented code linter
boolean_arithmetic_linter

Require usage of boolean operators over equivalent arithmetic
brace_linter

Brace linter
class_equals_linter

Block comparison of class with ==
best_practices_linters

Best practices linters
coalesce_linter

Encourage usage of the null coalescing operator %||%
checkstyle_output

Checkstyle Report for lint results
common_mistakes_linters

Common mistake linters
commas_linter

Commas linter
condition_message_linter

Block usage of paste() and paste0() with messaging functions using ...
correctness_linters

Correctness linters
consecutive_mutate_linter

Require consecutive calls to mutate() to be combined when possible
configurable_linters

Configurable linters
conjunct_test_linter

Force && conditions to be written separately where appropriate
consistency_linters

Consistency linters
clear_cache

Clear the lintr cache
comparison_negation_linter

Block usages like !(x == y) where a direct relational operator is appropriate
condition_call_linter

Recommend usage of call. = FALSE in conditions
consecutive_assertion_linter

Force consecutive calls to assertions into just one when possible
cyclocomp_linter

Cyclomatic complexity linter
duplicate_argument_linter

Duplicate argument linter
efficiency_linters

Efficiency linters
all_undesirable_functions

Default undesirable functions and operators
download_file_linter

Recommend usage of a portable mode value for downloading files
equals_na_linter

Equality check with NA linter
exclude

Exclude lines or files from linting
default_settings

Default lintr settings
default_linters

Default linters
deprecated_linters

Deprecated linters
empty_assignment_linter

Block assignment of {}
expect_lint

Lint expectation
expect_null_linter

Require usage of expect_null for checking NULL
expect_length_linter

Require usage of expect_length(x, n) over expect_equal(length(x), n)
executing_linters

Code executing linters
expect_s3_class_linter

Require usage of expect_s3_class()
expect_named_linter

Require usage of expect_named(x, n) over expect_equal(names(x), n)
expect_not_linter

Require usage of expect_false(x) over expect_true(!x)
expect_identical_linter

Require usage of expect_identical(x, y) where appropriate
expect_lint_free

Test that the package is lint free
expect_comparison_linter

Require usage of expect_gt(x, y) over expect_true(x > y) (and similar)
function_left_parentheses_linter

Function left parentheses linter
get_r_string

Extract text from STR_CONST nodes
function_argument_linter

Function argument linter
for_loop_index_linter

Block usage of for loops directly overwriting the indexing variable
expect_true_false_linter

Require usage of expect_true(x) over expect_equal(x, TRUE)
fixed_regex_linter

Require usage of fixed=TRUE in regular expressions where appropriate
function_return_linter

Lint common mistakes/style issues cropping up from return statements
expect_s4_class_linter

Require usage of expect_s4_class(x, k) over expect_true(is(x, k))
get_source_expressions

Parsed sourced file from a filename
expect_type_linter

Require usage of expect_type(x, type) over expect_equal(typeof(x), type)
implicit_integer_linter

Implicit integer linter
if_not_else_linter

Block statements like if (!A) x else y
ids_with_token

Get parsed IDs by token
if_switch_linter

Require usage of switch() over repeated if/else blocks
ifelse_censor_linter

Block usage of ifelse() where pmin() or pmax() is more appropriate
infix_spaces_linter

Infix spaces linter
implicit_assignment_linter

Avoid implicit assignment in function calls
inner_combine_linter

Require c() to be applied before relatively expensive vectorized functions
gitlab_output

GitLab Report for lint results
indentation_linter

Check that indentation is consistent
length_test_linter

Check for a common mistake where a size check like 'length' is applied in the wrong place
library_call_linter

Library call linter
lengths_linter

Require usage of lengths() where possible
length_levels_linter

Require usage of nlevels over length(levels(.))
keyword_quote_linter

Block unnecessary quoting in calls
lint-s3

Create a lint object
lint

Lint a file, directory, or package
line_length_linter

Line length linter
is_numeric_linter

Redirect is.numeric(x) || is.integer(x) to just use is.numeric(x)
is_lint_level

Is this an expression- or a file-level source object?
linters_with_tags

Create a tag-based linter configuration
missing_argument_linter

Missing argument linter
linters_with_defaults

Create a linter configuration based on defaults
make_linter_from_xpath

Create a linter from an XPath
literal_coercion_linter

Require usage of correctly-typed literals over literal coercions
matrix_apply_linter

Require usage of colSums(x) or rowSums(x) over apply(x, ., sum)
list_comparison_linter

Block usage of comparison operators with known-list() functions like lapply
lintr-package

Lintr
list2df_linter

Recommend direct usage of data.frame() to create a data.frame from a list
linters

Available linters
nested_ifelse_linter

Block usage of nested ifelse() calls
namespace_linter

Namespace linter
nonportable_path_linter

Non-portable path linter
nested_pipe_linter

Block usage of pipes nested inside other calls
nzchar_linter

Require usage of nzchar where appropriate
numeric_leading_zero_linter

Require usage of a leading zero in all fractional numerics
modify_defaults

Modify lintr defaults
nrow_subset_linter

Block usage of nrow(subset(x, .))
missing_package_linter

Missing package linter
normalize_exclusions

Normalize lint exclusions
object_usage_linter

Object usage linter
package_development_linters

Package development linters
object_overwrite_linter

Block assigning any variables whose name clashes with a base R function
one_call_pipe_linter

Block single-call magrittr pipes
outer_negation_linter

Require usage of !any(x) over all(!x), !all(x) over any(!x)
paren_body_linter

Parenthesis before body linter
object_length_linter

Object length linter
object_name_linter

Object name linter
package_hooks_linter

Package hooks linter
pipe_consistency_linter

Pipe consistency linter
quotes_linter

Character string quote linter
paste_linter

Raise lints for several common poor usages of paste()
pkg_testthat_linters

Testthat linters
pipe_return_linter

Block usage of return() in magrittr pipelines
print_linter

Block usage of print() for logging
read_settings

Read lintr settings
pipe_call_linter

Pipe call linter
readability_linters

Readability linters
pipe_continuation_linter

Pipe continuation linter
parse_exclusions

read a source file and parse all the excluded lines from it
regex_subset_linter

Require usage of direct methods for subsetting strings via regex
rep_len_linter

Require usage of rep_len(x, n) over rep(x, length.out = n)
robustness_linters

Robustness linters
repeat_linter

Repeat linter
sample_int_linter

Require usage of sample.int(n, m, ...) over sample(1:n, m, ...)
regex_linters

Regular expression linters
return_linter

Return linter
routine_registration_linter

Identify unregistered native routines
redundant_equals_linter

Block usage of ==, != on logical vectors
redundant_ifelse_linter

Prevent ifelse() from being used to produce TRUE/FALSE or 1/0
stopifnot_all_linter

Block usage of all() within stopifnot()
semicolon_linter

Semicolon linter
sarif_output

SARIF Report for lint results
string_boundary_linter

Require usage of startsWith() and endsWith() over grepl()/substr() versions
spaces_inside_linter

Spaces inside linter
spaces_left_parentheses_linter

Spaces before parentheses linter
sort_linter

Check for common mistakes around sorting vectors
sprintf_linter

Require correct sprintf() calls
style_linters

Style linters
trailing_whitespace_linter

Trailing whitespace linter
undesirable_function_linter

Undesirable function linter
trailing_blank_lines_linter

Trailing blank lines linter
seq_linter

Sequence linter
todo_comment_linter

TODO comment linter
undesirable_operator_linter

Undesirable operator linter
tidy_design_linters

Tidyverse design linters
strings_as_factors_linter

Identify cases where stringsAsFactors should be supplied explicitly
terminal_close_linter

Prohibit close() from terminating a function definition
scalar_in_linter

Block usage like x %in% "a"
system_file_linter

Block usage of file.path() with system.file()
unnecessary_concatenation_linter

Unneeded concatenation linter
which_grepl_linter

Require usage of grep over which(grepl(.))
unreachable_code_linter

Block unreachable code and comments following return statements
use_lintr

Use lintr in your project
xp_call_name

Get the name of the function matched by an XPath
yoda_test_linter

Block obvious "yoda tests"
unnecessary_lambda_linter

Block usage of anonymous functions in iteration functions when unnecessary
xml_nodes_to_lints

Convert an XML node or nodeset into a Lint
unnecessary_nesting_linter

Block instances of unnecessary nesting
unused_import_linter

Check that imported packages are actually used
vector_logic_linter

Enforce usage of scalar logical operators in conditional statements
unnecessary_placeholder_linter

Block usage of pipeline placeholders if unnecessary
whitespace_linter

Whitespace linter
all_equal_linter

Warn about invalid usage of all.equal()
T_and_F_symbol_linter

T and F symbol linter
assignment_linter

Assignment linter
absolute_path_linter

Absolute path linter
backport_linter

Backport linter
any_is_na_linter

Require usage of anyNA(x) over any(is.na(x))
any_duplicated_linter

Require usage of anyDuplicated(x) > 0 over any(duplicated(x))
all_linters

Create a linter configuration based on all available linters
Linter

Create a linter closure
available_linters

Get Linter metadata from a package