# visNetwork puts the vis.js network graph inside R and Shiny

> visNetwork is an R package that wraps the vis.js visualisation library, so a graph defined in data frames becomes an interactive network view, with helpers for hierarchical trees, a Shiny example app and a function that opens the full JavaScript documentation. It is on CRAN and its latest release is 2.1.1 from January 2022.

**datastorm-open/visNetwork** — R package, using vis.js library for network visualization

- Repository: https://github.com/datastorm-open/visNetwork
- Stars: 563 · Forks: 125
- Language: JavaScript
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/datastorm-open-visnetwork

## A binding, and what that means for the feature set

visNetwork is an R package, using the vis.js library for network visualization, and it is available on CRAN.

That single phrase sets the scope. This is a binding, not a reimplementation. The graph drawing, the interaction, the physics simulation and the styling model all come from vis.js, and the R package is the layer that lets you hand the library a data frame and get a widget back.

The consequence runs in both directions. Things that vis.js can do are often reachable from R, sometimes directly and sometimes through a helper function that packages the JavaScript options for you. Things vis.js cannot do are not there at all, and there is no amount of R cleverness that adds them.

The R package wraps vis.js at version 9.1.0, according to the changelog entry for 2.1.0, which is the point at which the underlying library was updated. The package version and the vis.js version are separate numbers that happen to be near each other, and it is the vis.js version that determines which interaction and layout features exist.

The documentation is split between two places, and the README points at both. The online documentation for the package is at http://datastorm-open.github.io/visNetwork, and alongside the R examples there is a link to the vis.js documentation itself. That split is deliberate: the R documentation tells you how to pass data and options from R, and the JavaScript documentation tells you what the options mean.

For an R user, that is a workable arrangement as long as you accept that the boundary of the library is the boundary of the wrapper.

## The data frame interface

The minimal example in the README is short enough to be the whole mental model of the package.

```r
nodes <- data.frame(id = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges)
```

Two data frames, one for the nodes with an id column and one for the edges with from and to columns, and a function call that returns the visualisation. The edge table refers to nodes by the same identifiers, which is the convention vis.js uses throughout.

Because it is data frames rather than a bespoke object, the inputs come from the same place everything else in an R workflow comes from. A pipeline that produces a table of nodes and a table of edges can hand them straight over without an intermediate serialization step, and a data frame with extra columns carries per-node attributes that vis.js will use for labels, groups, colours and titles.

That last point is where the package earns its keep. In vis.js a node is an object with a set of properties, and the R wrapper maps the columns of your data frame onto those properties, so grouping nodes or labelling them from your own data is a matter of naming the columns rather than constructing objects in another language.

The functions named in the changelog confirm that surface. The visHclust function works with hierarchical clustering data and was fixed in 2.1.0 for a newer ggraph version, which suggests it accepts clustering output rather than a plain edge list. The visTree function handles tree structures, and the changelog records both a fix for invalid R column names and a crash, plus a performance improvement in computing the boxplot sparkline with large data and a fix for passing a constant variable and character tooltipColumns.

The fact that visHclust integrates with ggraph is worth noting, because it means the package sits alongside the tidyverse graph tooling rather than replacing it.

## The 2.1.0 release, item by item

The changelog in the README is the most detailed piece of documentation the package has, and it reads as a list of real problems that real users hit.

The 2.1.0 entry names eight changes. Issue 361 was a fix for visHclust with the new ggraph version. The package switched to vis-network 9.1.0. visTree had a fix for invalid R column names along with a crash. FontAwesome 5.13.0 support was added. Issue 377 added custom manipulation columns. Issue 335 enabled the highlightNearest degree option for groups. visTree updated the performance of computing a boxplot sparkline with large data. And visTree and TreeModule got a fix for passing a constant variable and character tooltipColumns.

Three of those deserve a word.

The vis-network 9.1.0 jump is the one that matters most for capability, because it is when the underlying library's features change under the wrapper. Anything introduced in vis-network after 9.1.0 is not available here.

The highlightNearest degree option for groups is the interactive nicety. Highlighting the nearest neighbours of a node is a standard way to make a dense graph readable, and enabling the degree variant for grouped nodes means the highlight accounts for the group membership, which is what you want when groups are the meaningful structure.

The custom manipulation columns are the practical win for anyone doing exploratory work. It lets the R side define which columns the JavaScript side exposes for editing, so a user can change a value in the graph and the change is written to a named field, which is how an interactive graph becomes an editor rather than a picture.

The performance entry is a good sign about the maintainers' priorities. A boxplot sparkline is a small summary glyph attached to a node, and recomputing it over large data was evidently a bottleneck.

## Using it: install, vignette, Shiny

The README's example block doubles as a quick start, and it covers the four things you are likely to do.

```r
install.packages("visNetwork")

require(visNetwork)
?visNetwork

vignette("Introduction-to-visNetwork")

visDocumentation()

shiny::runApp(system.file("shiny", package = "visNetwork"))
```

The install is a standard CRAN install, and the README also gives the development path, which is devtools::install_github("datastorm-open/visNetwork") for the development version.

The help is available in two forms. The question mark operator gives you the help page for the package, and the vignette titled Introduction-to-visNetwork is the guided introduction.

The visDocumentation() function is the interesting one. It gives you access to the full JavaScript documentation, which means the R package does not try to wrap up the entire vis.js API in R documentation. It hands you the original documentation instead, which is a pragmatic choice: it avoids maintaining a translation of a large and changing API, and it means the R user still has the authoritative reference.

The Shiny line runs the example application that ships inside the package, which is the fastest way to see what the widget looks like inside a reactive application rather than in a static plot.

Taken together, the four steps form a sensible progression: install it, read the R-level introduction, look up the JavaScript options when you need something the wrapper does not cover, and run the example app to see the integration in place.

## Where visNetwork fits, and where it stops

The comparison worth making is with igraph and ggraph in R, and with writing the vis.js call yourself in JavaScript.

Against igraph, the difference is the kind of analysis each one supports. igraph is a graph library aimed at computation rather than rendering. visNetwork is a rendering layer, and its graphs are typically produced by something else. In practice the two are used together rather than against each other, and the ggraph integration in the changelog is evidence of that.

Against ggraph, the difference is that ggraph is a grammar for building plots in the tidyverse, where the plot is composed declaratively and the layout comes from a broad set of algorithms, while visNetwork is a specific widget with its own physics-based layout and its own interaction model. Choosing visNetwork means choosing the vis.js look and behaviour.

Against writing vis.js directly, the difference is who maintains the bridge. In R you get data frame inputs and a helper for the tree and clustering cases, and you avoid maintaining a JavaScript build. Outside R, vis.js sits upstream, and the R package's own release history shows the two drifting apart, since the wrapper last shipped in January 2022.

The limits are worth stating. The package is on CRAN, which means installation is easy, but the release cadence is slow, and the pinned vis.js version means some upstream features are simply not reachable. Anything beyond the wrapped function set needs JavaScript in the page, which means going around the abstraction the package provides. And the output is an interactive web widget, so it does not serve a report, a paper figure or a PDF without additional work.

The licence is recorded as a custom one that GitHub cannot classify, with the LICENSE file in the repository as the authoritative text, which matters for a package distributed through CRAN under different terms than the repository suggests.

The last push was on 2026-07-15 and the repository is not archived, so the code is still being touched even though the CRAN release is from 2022.

## Conclusion

visNetwork suits an R analyst who already has their graph in data frames and wants an interactive network view without writing JavaScript, since the nodes and edges tables map directly onto the vis.js model and the tree helpers handle the layout options that are fiddly to get right. It is the wrong tool if you need a static figure for a paper, since the output is an interactive web widget, and it is the wrong tool if your project is not on R, since the package is a thin R binding to a JavaScript library. Before adopting it, read the online documentation at datastorm-open.github.io/visNetwork and check the vis.js documentation for the features you need, because the R package covers a subset of what the JavaScript library offers.

## FAQ

### What is visNetwork?

It is an R package that uses the vis.js library for network visualization, and it is available on CRAN. Graphs are passed in as data frames, one for nodes with an id column and one for edges with from and to columns, and the package returns an interactive network view.

### How do I install visNetwork?

Run install.packages("visNetwork") for the CRAN version. The README also gives devtools::install_github("datastorm-open/visNetwork") for the development version, and the package is documented online at http://datastorm-open.github.io/visNetwork.

### What does the visDocumentation() function do?

It opens the full JavaScript documentation for vis.js, so you can look up the options that the R wrapper does not cover. The package deliberately points at the original documentation rather than restating the whole vis.js API in R.

### What changed in visNetwork 2.1.0?

The release switched to vis-network 9.1.0, fixed visHclust with the new ggraph version, fixed visTree for invalid R column names and a crash, added FontAwesome 5.13.0 support, added custom manipulation columns at issue 377, enabled the highlightNearest degree option for groups at issue 335, improved visTree performance for the boxplot sparkline with large data, and fixed passing a constant variable and character tooltipColumns.

### Can I use visNetwork with Shiny?

Yes. The package ships a Shiny example application, and the README shows it being started with shiny::runApp(system.file("shiny", package = "visNetwork")).

### When was the last visNetwork release?

The last CRAN release is 2.1.1 from 2022-01-31, after 2.1.0 from 2021-10-04 and 2.0.8 from 2019-08-30. The repository itself was last pushed on 2026-07-15 and is not archived, and the licence is a custom one that GitHub cannot classify, with the LICENSE file as the authoritative text.

## Sources

- [datastorm-open/visNetwork on GitHub](https://github.com/datastorm-open/visNetwork)
- [Issues](https://github.com/datastorm-open/visNetwork/issues)
- [README](https://github.com/datastorm-open/visNetwork/blob/master/README.md)
- [Releases](https://github.com/datastorm-open/visNetwork/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/datastorm-open-visnetwork
