Papers
Topics
Authors
Recent
Search
2000 character limit reached

flowR: R Analysis IDE Extension

Updated 4 July 2026
  • flowR is an extension for Positron and VS Code that incrementally analyzes R data scripts using static analysis, interactive graphs, and linting to enhance code comprehension and maintenance.
  • It integrates interprocedural data- and control-flow analyses to build comprehensive dataflow graphs, supporting features like slicing, hover annotations, and dynamic plugin interactions.
  • The system delivers near real-time performance with an average full dataflow graph computation of 576ms and rapid incremental updates for large projects.

Searching arXiv for the specified flowR variants to verify the relevant papers and disambiguate similarly named systems. flowR is an extension for the common data analysis IDEs Positron and VS Code that targets the comprehension and maintenance of R data analysis scripts by combining incremental static analysis, interactive graph visualizations, linting, inline value annotations, and a plugin system (Sihler et al., 17 Apr 2026). It incrementally analyzes R projects by intertwining interprocedural data- and control-flow analyses to build a comprehensive dataflow graph that incorporates R’s dynamic and explorative features, with an average of 576ms to calculate the full dataflow graph of real-world projects, thereby enabling near real-time feedback (Sihler et al., 17 Apr 2026). The name should be distinguished from several unrelated arXiv works using similar capitalization, including FlowR for 3D reconstructions (Fischer et al., 2 Apr 2025), FLOWR for few-shot open world recognition (Willes et al., 2021), and FLOWR for structure-aware ligand generation (Cremer et al., 14 Apr 2025).

1. Definition and scope

flowR addresses a recurrent problem in computational research: data analysis scripts are often hard to comprehend and maintain, which hinders reproducibility and reuse. The system focuses on the R programming language and is presented as an extension for Positron and VS Code. Its functionality combines a previously presented static backward program slicer with script overviews, interactive graph visualizations, linting, and inline value annotations (Sihler et al., 17 Apr 2026).

The system is designed for project-scale static analysis rather than isolated-file inspection. It analyzes R projects incrementally and exposes the resulting analyses through IDE affordances such as side bar views, hover-tooltips, graph webviews, and linting panes. A plausible implication is that flowR is intended to support both exploratory data analysis and longer-lived analytical codebases, where comprehension, debugging, and maintenance become central concerns.

A recurring source of confusion is nomenclature. The lowercase form “flowR” in the R-analysis context is distinct from “FlowR: Flowing from Sparse to Dense 3D Reconstructions” (Fischer et al., 2 Apr 2025), “Few-shot Learning for Open World Recognition (FLOWR)” (Willes et al., 2021), and “FLOWR: Flow Matching for Structure-Aware De Novo, Interaction- and Fragment-Based Ligand Generation” (Cremer et al., 14 Apr 2025). These works share an acronymic surface form but concern unrelated technical domains.

2. System architecture and IDE integration

flowR is delivered as a standard VS Code extension and is also repackaged for Open-VSX so it “just works” in Positron or in vscode.dev. On installation it registers a Language Server, via TCP or WebSocket, that the editor invokes whenever files change, cursors move, or linter or hover requests arrive. All editor-side UI, including side bar views, hover-tooltips, and graph webviews, is implemented in TypeScript/Vue in the extension, whereas the analysis itself runs in a separate flowR server process in Node.js with an optional R back-end (Sihler et al., 17 Apr 2026).

The processing pipeline follows a defined sequence. Project discovery is delegated to flowRAnalyzer, which discovers files in the workspace, including .R, .Rmd, .qmd, and notebook formats, by invoking each installed plugin’s onDiscover() hook. Plugins may influence file order, add virtual documents, or supply extra context information such as renv.lock. Parsing is then performed by Tree-sitter-R or R’s native parser. The resulting raw AST is passed to an AST normalizer or “Decorator,” yielding a normalized AST with unique numeric IDs on every node and a canonical treatment of R syntax sugar such as pipes and NSE. Core analyses then construct the Dataflow Graph Generator, Control-Flow Graph Generator, call graph, side-effect analysis, and an abstract-interpretation pass; these analyses are “tightly interleaved,” so that, for example, control dependences refine which data edges are feasible (Sihler et al., 17 Apr 2026).

The architecture exposes a Query API and fixpoint solver. On requests such as hover, slice, linter, or graph view, flowR executes an on-demand query that walks the DFG or CFG and may re-invoke the fixpoint solver on the affected subgraph. Results are returned as JSON objects such as dataflow-info, slice-nodes, lint-results, and value-facts, after which the extension incrementally updates the dependency view, lint-message carousel, hover-tooltips, and Mermaid webviews (Sihler et al., 17 Apr 2026).

flowR can also be run via Docker using docker run --rm -it eagleoutice/flowr, and the source code and documentation are hosted at https://github.com/flowr-analysis/flowr (Sihler et al., 17 Apr 2026). This suggests a deployment model that is not confined to interactive IDE usage, but can also be embedded in R or npm-based pipelines.

3. Static analyses and formal foundations

The core analysis layer is centered on interprocedural data-flow analysis, control-flow analysis, and slicing. Let NN be the set of normalized AST locations, each with a unique ID, and let VV be the set of program variables, including temporaries, function parameters, and globals. The abstract fact domain is defined as D=V×P(oc)D = V \times \mathcal{P}(\ell oc), interpreted as “vv may be defined at locations \ell.” For each N\ell \in N, a transfer function F():DDF(\ell): D \to D incorporates the effect at \ell. If \ell is an assignment x <- e, the transfer function performs the expected kill/gen behavior and propagation from predecessors. The join operator \sqcup on VV0 is set union, and the data-flow equations are solved on the interprocedural CFG until a fixpoint:

VV1

Call and return edges are added by a standard 0-CFA-style interprocedural scheme (Sihler et al., 17 Apr 2026).

The control-flow component builds a reduced CFG whose nodes are basic blocks or important statements, with edges labeled by Boolean conditions for branches. Formally,

VV2

where VV3 is labeled with required path conditions. Each CFG edge is enriched with dataflow information so that data edges connect only if the control condition along every intervening path is satisfiable under the abstract environment. This interleaving is explicitly intended to prevent infeasible data edges. A toy normalized grammar includes assignments, conditional statements, loops, and function calls, with every if or while abstracted into a branch node with true and false sub-edges (Sihler et al., 17 Apr 2026).

The slicing mechanism is based on a Program Dependence Graph VV4, where VV5 contains data-dependence edges such as Def→Use and side-effect relations, and VV6 contains control-dependence edges from branches to dependent nodes. Given a slicing criterion VV7, the backward slice is

VV8

The worklist implementation begins from the criterion, iteratively traverses PDG predecessors, and accumulates visited nodes. Forward or impact slicing reverses the traversal direction (Sihler et al., 17 Apr 2026).

These formal definitions position flowR as a static-analysis framework tailored to R’s project-scale, interprocedural, and dynamically flavored workflows. This suggests that its design is not merely a visualization layer, but a compiler-style analysis infrastructure adapted to analytical scripting.

4. User-facing functionality

flowR provides several integrated features for script comprehension. Interactive graph visualizations cover the normalized AST, DFG, CFG, and call graph, all rendered via Mermaid.js in a VS Code Webview panel. On each edit or cursor move, the extension requests only the subgraph reachable within VV9 hops of the selected AST node, and the returned Mermaid diagram is updated incrementally. Panel controls support options such as “hide dead code,” “compact vs. detailed CFG,” and “highlight slice” (Sihler et al., 17 Apr 2026).

Linting is driven by a specific analysis pass over the DFG together with abstract values. The default rule set comprises ten rules, including absolute-path usage, missing-file detection, missing-column in a data-frame operation, RNG without set.seed(), and checks for deprecated functions and unused variables. Each rule is implemented as a function of the form function lintRule(ctx: AnalysisContext): LintFinding[]. Quick-fix actions are delegated to a CodeActionProvider in the extension, enabling edits such as converting an absolute path to file.path(…) or inserting set.seed(123) at the top of a script (Sihler et al., 17 Apr 2026).

Inline value annotations, referred to as “hover values,” are expressed as typed queries such as { type: 'resolveValue', nodeId: ℓ }. The returned abstract-domain element is then pretty-printed, for example as 42L or as a data-frame schema such as data frame 4×{foo,bar,…}. This feature connects the underlying abstract interpretation directly to the editor interface (Sihler et al., 17 Apr 2026).

The plugin system exposes a central TypeScript interface: D=V×P(oc)D = V \times \mathcal{P}(\ell oc)6 Plugins are registered via new FlowrAnalyzerBuilder().addPlugin(myPlugin).build(). The Query API is similarly typed and includes requests such as dependencies, df-slice, and resolveValue (Sihler et al., 17 Apr 2026). A plausible implication is that flowR is intended as a host platform for additional analyses rather than a closed, monolithic tool.

5. Performance characteristics and empirical behavior

The computational profile of flowR is reported in both asymptotic and empirical terms. Let D=V×P(oc)D = V \times \mathcal{P}(\ell oc)0 and D=V×P(oc)D = V \times \mathcal{P}(\ell oc)1. Building the DFG and CFG is described as essentially a graph-construction process over the AST with complexity D=V×P(oc)D = V \times \mathcal{P}(\ell oc)2. The interprocedural fixpoint solve for dataflow, using an IFDS-style sparse representation, is described as D=V×P(oc)D = V \times \mathcal{P}(\ell oc)3 in practice, where D=V×P(oc)D = V \times \mathcal{P}(\ell oc)4 is the average number of iterations and is reported as very small for R scripts. Slicing on the PDG reduces to graph reachability with complexity D=V×P(oc)D = V \times \mathcal{P}(\ell oc)5. The worst case is characterized as a potential quadratic blow-up with hundreds of thousands of AST nodes, but real-world R scripts are said to stay in the few-thousand-node range (Sihler et al., 17 Apr 2026).

Empirically, on a corpus of 4,230 real-world R projects with an average of approximately 1,733 DFG nodes and 3,738 edges, the reported cold-start, single-threaded timings are 115 ms average for parse and normalize, 525 ms average for dataflow graph build, and 640 ms average total, with median approximately 250 ms. Typical incremental updates after a single keystroke take 10–100 ms, and slice, hover, and linter queries are answered in much less than 100 ms once the DFG and CFG are resident in memory (Sihler et al., 17 Apr 2026).

The abstract reports an average of 576ms to calculate the full dataflow graph of real-world projects (Sihler et al., 17 Apr 2026). The discrepancy between “576ms” in the abstract and the more detailed benchmark decomposition in the extended description reflects different reporting scopes: the former concerns the full dataflow graph, whereas the latter separates parsing, normalization, graph construction, and total runtime. This suggests that the system’s near real-time character is robust across measurement views, even if individual timing aggregates depend on the benchmark protocol.

6. Example workflow and relation to similarly named systems

An illustrative script is given as: D=V×P(oc)D = V \times \mathcal{P}(\ell oc)7 For this script, the flowR side bar shows the library ggplot2, the input file data.csv, the filter operation, and plot functions ggplot and geom_point. Hovering over thresh yields Value: 10L if flowR infers a default; hovering over df yields a data-frame shape and column summary. A backward slice from geom_point highlights lines (1)–(4), while a forward slice from the literal "data.csv" highlights lines (2)–(4). The dataflow graph view exposes nodes such as raw:def → raw:use → filter:def → df:use → ggplot:call → geom_point:call, with edge colors indicating data, control, argument, and return relations. If thresh is renamed to threshold, the system updates within 50 ms so that the hover value fails, the linter flags an undefined symbol, and the slice highlighting disappears (Sihler et al., 17 Apr 2026).

Taken together, these examples show how flowR combines interprocedural data/control-flow analyses, an abstract-interpretation solver for values, a static slicer, an extensible linter, incrementally updated graph views, and notebook support into a practical environment for understanding and maintaining R data-analysis scripts (Sihler et al., 17 Apr 2026).

The name “flowR” must be distinguished from unrelated research systems. “FlowR: Flowing from Sparse to Dense 3D Reconstructions” is a multi-view flow-matching model for augmenting sparse 3D Gaussian splatting reconstructions with generated novel views (Fischer et al., 2 Apr 2025). “FLOWR” in few-shot open world recognition denotes a Bayesian non-parametric framework built on embedding-based pre-training and Chinese Restaurant Process priors (Willes et al., 2021). “FLOWR” in molecular design is a structure-based framework for 3D ligand generation using continuous and categorical flow matching with equivariant optimal transport (Cremer et al., 14 Apr 2025). These are independent uses of the label rather than variants of the R-analysis tool.

Topic to Video (Beta)

No one has generated a video about this topic yet.

Whiteboard

No one has generated a whiteboard explanation for this topic yet.

Follow Topic

Get notified by email when new papers are published related to flowR.