Open-source project
yihui/knitr avatar
yihui/knitr

knitr: the literate programming engine behind R Markdown

A general-purpose tool for dynamic report generation in R

2,468 stars877 forksRLicense varies

At a glance

What is it?
knitr turns R scripts into reports by running code chunks and weaving their output into LaTeX, Markdown or HTML. It is the engine under R Markdown, and it is worth understanding on its own terms.
Who is it for?
Adopt knitr if you write reports where the numbers must come from code that actually ran: academic papers, internal analyses, teaching material. Do not adopt it expecting a notebook UI; knitr is the engine, and the interface comes from whatever calls it, such as RStudio or rmarkdown.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly R, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What knitr solves, and who it is for

The README states the package is "a general-purpose literate programming engine, with lightweight API's designed to give users full control of the output without heavy coding work." That sentence is the whole product. A literate programming document mixes prose with code, and the engine's job is to execute the code, capture whatever it produced, and splice that output back into the document at the right place.

Before knitr, the R world used Sweave. The README is unusually candid about why its author moved on. It lists the wishes that drove the rewrite: inserting a width next to a single graphics inclusion rather than setting a global LaTeX key, choosing a graphics device with an option as simple as dev = 'png', recording multiple plots from one code chunk instead of only the last one, rounding numbers in \Sexpr{} without repeating round(x, 3) at every call, and printing ggplot2 plots without an explicit print(). Those are not abstract complaints. They are the daily friction of writing a data-driven paper in Sweave.

The audience follows from that list. knitr is for people who produce documents whose numbers are computed: statistical reports, journal submissions, course notes, internal analyses. It is also, indirectly, for anyone using R Markdown, because knitr is the execution layer underneath. If you write .Rmd files in RStudio and press Knit, knitr is what runs your chunks.

How a knit actually runs: chunks in, output out

The mechanism is a parse, evaluate, weave cycle. A source document contains code chunks separated from prose. knitr parses the document, evaluates each chunk in an R session, collects the results (printed text, warnings, messages, plots written to graphics devices), and writes a new file in which each chunk has been replaced by its output. The original source is never modified.

What makes the cycle configurable is chunk options. Each chunk can carry its own settings, and the README's motivation section shows why that granularity matters: the author wanted to set a figure width per chunk rather than globally through \setkeys{Gin}, and wanted to pick a graphics device per chunk with an option like dev = 'png'. Global defaults exist too, and the README says that when options are not explicitly specified, knitr "will try to guess reasonable default settings."

The README points to a main manual and a graphics manual for the details, and to the knitr book for an organized reference. That is where chunk option semantics live. The repository's own tests/ and inst/examples/ directories, plus the Makefile target that runs Rscript knit-all.R inside inst/examples, show that the examples are exercised as part of the project's own workflow rather than left to rot.

The design goal stated in the README is worth quoting in spirit: the package was built to give the user access to every part of the process, so that reaching into core components is unnecessary. That is a claim about extensibility, and it is the reason knitr has survived as a substrate for other packages rather than being a single-purpose tool.

Installing knitr and knitting a first document

The stable version lives on CRAN. From an R session:

r
install.packages('knitr')

If you want the development version, the README describes an hourly build published through r-universe. You point the repos option at that universe first, then install:

r
options(repos = c(
  yihui = 'https://yihui.r-universe.dev',
  CRAN = 'https://cloud.r-project.org'
))

install.packages('knitr')

Once installed, the README's usage section is three lines: load the package, read the help page for knit, and call it on an input file.

r
library(knitr)
?knit
knit(input)

Here input is the path to your source document. The call writes an output file next to it and returns the path to that file. For a first real run, write a small file with a code chunk that prints something, call knit() on it, and open the result. What you should see is the chunk replaced by its printed output, with the surrounding prose untouched. That single observation tells you the engine works end to end.

A caveat on the install path: the README does not state a minimum R version. The package's DESCRIPTION file, which is in the repository, is where that constraint is declared, and it is the file to check before installing on an older R.

Where knitr is the wrong tool

knitr is an engine, not an environment. It has no notebook interface, no cell execution model, no kernel protocol. If what you want is to run one cell at a time and inspect variables interactively in a browser, knitr does not provide that, and no amount of chunk options will turn it into one. The interactive layer in the R world comes from other software that calls knitr.

There is a second boundary that trips people up. knitr converts a source document into another document format; it does not render that format to a final deliverable. The step from Markdown to HTML or PDF belongs to a different package in the R Markdown stack. When a knit succeeds but the final document fails to appear, the failure is usually downstream of knitr, not inside it, and debugging it as a knitr problem wastes time.

The README also does not document rollback or recovery behaviour for a failed chunk. If a chunk errors midway, what state the session is left in is not described there. For long-running documents, that gap matters: you want to know whether a failure leaves partial output or nothing. The honest answer from the available material is that the README is silent on it, and the manuals linked from the README are where to look.

knitr compared with Jupyter, and with Sweave

The comparison people search for is knitr versus Jupyter, and the difference is architectural rather than cosmetic. Jupyter runs a persistent kernel and stores execution state in a notebook file that mixes code, output and prose in one JSON document. knitr runs a parse and evaluate pass over a plain-text source file and writes a separate output file, leaving the source as the single artifact you version. In the Jupyter model, output is part of the document; in the knitr model, output is derived and regenerable. That is why knitr documents diff cleanly in version control and Jupyter notebooks, with embedded outputs and execution counts, do not.

The comparison with Sweave is internal to R and more instructive. Sweave is the older engine, and the README's motivation section reads as a list of Sweave's constraints: global LaTeX graphics keys instead of per-chunk widths, limited graphics devices, only the last plot from a chunk retained, no per-call rounding for inline expressions. knitr was written to remove those constraints, and the README notes that the author had read the source of the add-on packages cacheSweave and pgfSweave and was uncomfortable with how much code they copied from R itself, since that code needs updating whenever R changes. knitr's answer was to expose the process instead of forking it.

Maintenance, licensing and what an upgrade costs you

The repository is not archived, and the last push was on 2026-09-27. Releases are frequent and dated: v1.50 on 2025-03-16, v1.51 on 2025-12-20, and v1.52 on 2026-09-06. A cadence of roughly two releases a year over that window is a reasonable signal for a package this widely depended on, and the NEWS.md file at the repository root is where the changes between those versions are listed.

On licensing, the README states plainly: "This package is free and open source software, licensed under GPL." The repository metadata does not name a more specific GPL variant, so if the distinction between GPL-2 and GPL-3 matters to your organisation, read the DESCRIPTION file rather than assuming. The practical consequence of a copyleft licence is that distributing a derivative work carries obligations; that is a question for your own legal review, not something the README resolves.

Upgrade cost is dominated by chunk option behaviour rather than by the API, which is small and stable. The README's usage section is three calls. What changes between versions is option semantics and edge cases, so NEWS.md is the file to read before bumping, and the repository's own test setup, including the Makefile targets that build, check and run the examples, is what the maintainer relies on to catch regressions.

Editorial conclusion

Adopt knitr if you write reports where the numbers must come from code that actually ran: academic papers, internal analyses, teaching material. Do not adopt it expecting a notebook UI; knitr is the engine, and the interface comes from whatever calls it, such as RStudio or rmarkdown. Before committing, verify three things: that your R version satisfies the package's DESCRIPTION requirements, that your chunk options behave as you expect under the format you target, and that the output format you need is one the package documents support for. Everything else follows from those.

Frequently asked questions

What is knitr in R?

It is a general-purpose literate programming engine for R, described in the README as giving users full control of the output without heavy coding work. It executes code chunks in a source document and weaves their results back into the document.

How do I install the knitr package in R?

The README gives install.packages('knitr') for the stable CRAN version. For the development version, set the repos option to include https://yihui.r-universe.dev alongside CRAN and then run install.packages('knitr').

How do I use knit in R?

The README's usage section is library(knitr), then ?knit for the help page, then knit(input) with the path to your source document. The call writes an output file and returns its path.

What package is knitr in R?

knitr is its own package on CRAN, not a component of another one. The README documents installing it directly with install.packages('knitr').

What is knitr used for?

It is used to generate dynamic reports: code chunks in a source document are evaluated and their text and graphics output is written into the resulting document. The README frames it as a literate programming engine, and it is the execution layer under R Markdown.

What is the difference between an Rmd file and an R file?

An R file holds code alone, while an Rmd file mixes prose with code chunks, and knitr is the engine that evaluates those chunks and writes their output into the resulting document. The README describes knitr as a literate programming engine, which is the distinction that matters here.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. yihui/knitr on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yihui-knitr.svg)](https://hysenlabs.com/projects/yihui-knitr)