Program Analysis for R
flowR is an open source static program analyzer for your R code. It helps you understand existing scripts, find quality issues, improve reproducibility, and check the validity of your analyses.
v2.14.1 · GPL-3.0
Get started Playground ★ Star on GitHub
Available for
Try It Out
These run on the samples below. For your own code, open the playground, which runs flowR in your browser.
Point at any name below, or at an access like survey$age, and flowR keeps only the lines that matter.
It keeps the lines the value depends on, the called functions included, and drops the rest.
impact: what it goes on to affect.
On real-world R scripts, flowR (measured for v2.14.1) needs on average:
View the full stats on the benchmark page.
Features
FlowrAnalyzer API provides you with a simple interface to use flowR programmatically.
Use Cases
Inherited code
Someone left you a script that produces one number you need. Slice to that name and flowR drops every line that cannot affect it, which is usually most of them. The result still runs.
Static slice query Slicing from the REPL Dicing between two points
Reproducing a project
Before running anything, ask what it will touch: the packages it loads, the files it reads and writes, the plots it draws, and the scripts it sources. No execution, so nothing is overwritten.
Silent mistakes
The script runs, produces a number, and the number is wrong. flowR reads the code the way it will actually execute, so it can point at the parts that will not do what you meant: a path that only exists on your machine, a sample drawn without a seed so nobody can repeat it, a result computed and then never used, a column read after it was dropped, a credential left in the source.
It reports these before you run anything, and the same analysis answers what a script writes, which packages it needs, and what a variable can hold at any point.
Where a name comes from
A variable is reassigned four times and passed through two functions. flowR answers which definition a use actually reads, and which function a call actually reaches, across files.
Data that changes shape
A pipeline filters, joins and selects until a column is gone. The shape inference reports the rows and columns a data frame can have at every step, without the data.
Tooling of your own
Every answer on this page is a query. Ask them over the server, the REPL or the
FlowrAnalyzer API, and build the editor support your own workflow needs.
Ask for Something
What flowR Computes
Simplified views of a program: a dataflow
graph, a control flow graph, a
call graph, a
normalized syntax tree, and
abstract values over them.
Ask with the query API, look around with the
search API, and start with the
FlowrAnalyzerBuilder.
Contributing
Expand to see the details
- Get it running
five minutes, and no R needed
Clone it, run
npm ci, thennpm run flowr. That is the whole setup, and you do not need R installed: the tree-sitter parser is the default. See Developing for flowR for more details. - Write a linting rule the friendliest first change This is where most people start, and it is genuinely small: one file with a name, some config, and a function over the graph. The wiki builds a complete rule with you, tests and all.
- Add a query ask something flowR cannot answer yet If you keep asking flowR the same thing by hand, turn it into a query. Everything on this page is one, and yours lands in the REPL, the server and the API at the same time.
- Propose a plugin teach the analyzer something new Plugins decide how versions, sources and configuration are resolved around an analysis. Tell us what you are missing in an issue first, and we will work out the shape with you.
- Open a pull request
what we look at, and what we do not mind
Conventional commits,
npm run checkuppassing, and a sentence about what you changed. Small pull requests get read first, and drafts are welcome if you are unsure.
Maintained at Ulm University by Florian Sihler, Oliver Gerstl and everyone else who pitched in, free software under the GPLv3. Funded by the German Research Foundation (DFG), grant 504226141, with a gift from Posit.