Repository navigation
Explore a standalone, dependency-free R package for the Data Viewer backend #1860
Description
Motivation
The Data Viewer backend is currently implemented inside sess, which depends on external R packages such as jsonlite, processx, and later.
These dependencies can complicate installation and cause conflicts with packages managed by renv, pixi, or other environment managers.
PR #1856 improves installation isolation, but does not eliminate these dependencies.
I propose exploring a small, standalone R package for the Data Viewer backend, similar to how jgd provides a graphics device without external R package dependencies.
Unlike session communication, the enhanced Data Viewer is optional.
If its backend is unavailable, only the enhanced viewer needs to be disabled, without affecting the R session or the standard View() behavior.
The primary goal is dependency isolation and maintainability, not performance optimization.
Proposed direction
- Publish the backend as an independent CRAN package, installed into a vscode-R-managed library rather than bundled with the extension.
- Avoid external R package dependencies (
Imports/LinkingTo), using base R and a small amount of C code where appropriate. - Keep the backend independent of sess, and VS Code-specific communication protocols.
- Reuse existing R methods such as
format()for displaying S3/S4 objects, including vector classes built with vctrs. - Preserve native comparison and sorting semantics independently of formatted display values.
- Generate only the JSON structures required by the Data Viewer, potentially using an embedded C library such as cJSON.
- Keep the existing AG Grid frontend.
A general-purpose serializer such as jsonlite provides much more functionality than the Data Viewer needs.
By normalizing R values into a limited set of display types before JSON encoding, we may be able to avoid both a jsonlite dependency and vendoring its implementation.
Prior art
- jgd: A standalone R graphics device with embedded C code and no external R package dependencies.
- vctrs / pillar: Established conventions for separating vector formatting, type information, and comparison semantics.
- Julia VS Code Table Viewer: Converts language-specific values into a limited JSON representation for AG Grid, with lazy data retrieval.
Initial investigation
A prototype could focus on ordinary data frames and matrices, evaluating:
- Whether the existing metadata, paging, sorting, and filtering behavior can be extracted into a standalone package.
- Whether existing R formatting and comparison methods are sufficient for custom vector classes, including those based on vctrs.
- Whether a minimal JSON encoder can preserve existing behavior for missing values, numeric precision, dates,
integer64, and complex columns. - Whether the package can be installed and loaded from a managed library without modifying
.libPaths().
This is an architectural investigation, not a proposal to immediately replace the current implementation.
PR #1804 (lazy Arrow/DBI viewing) should proceed independently.
Arrow IPC / nanoarrow are not required for the initial prototype.
Separating the Data Viewer also does not eliminate sess's own jsonlite dependency, which is a separate concern related to #1859.
However, an independent backend could eventually be reused through alternative transports such as arf.
Activity
Fred-Wu commentedon Oct 11, 2026
As I remember, before v3.0, the R-side Data Viewer backend was largely implemented in a single file, including operations such as data preparation, formatting, sorting, filtering, paginated row fetching, and viewer register.
Before v3.0, I implemented on-demand data loading using
httpuvin my own local build, and the current work evolved from that one.So I think extracting these operations into a standalone package should be feasible.
eitsupi commentedon Oct 13, 2026
I'm working on this.
eitsupi commentedon Oct 15, 2026
I've made https://github.com/eitsupi/jdv public.
@Fred-Wu Could you take a look at this?
While DBI/dbplyr support is not (yet) available, I believe this should cover what you want to do in #1876.
Database support is already covered if we use ADBC, but I'm not sure if that meets your needs.
I'm still considering whether to add lazy R support.
Fred-Wu commentedon Oct 16, 2026
Thanks for working on this @eitsupi. It looks promising.
Here are some immediate issues after trying the package
The current implementation may convert entire date and date/time columns into formatted strings before filtering. Filtering and sorting should use the underlying numeric values directly.
Open viewagain.blankandnotBlankfilters in addition to theNAfilter.query_limitsall necessary? For example, some genomic datasets may easily surpass 4096 columns.Here is the testing data I am using.
lazy_query_test.txt
eitsupi commentedon Oct 17, 2026
@Fred-Wu Thanks again for testing jdv and for the detailed feedback!
I have pushed fixes for most of the issues you reported, including date filtering on large data, slow paging under sort/filter, and the column limit.
Re-running
jdv_view(x)also now picks up changes to the variable automatically.Could you try the latest main again with your test data when you have time?
If anything still looks slow or doesn't update, could you let me know which object and which viewer (the jdv browser viewer or the vscode-R PR) you were using?
Fred-Wu commentedon Oct 18, 2026
Thanks @eitsupi. I have tried
jdvwith the vscode-R PR in the data viewer (but not the latest push). Some quick comments below.fetchGridPage()injdvViewer.tsmay send repeated requests to fill the rows requested by AG Grid, potentially due to themax_message_bytesandrow_capacitybudget limits.Invalid numberin the vscode-R data viewer.Tableobject, the row count is already available from its metadata throughnrow(). I think, row number should be made available in this case.eitsupi commentedon Oct 19, 2026
@Fred-Wu Thanks, could you try the latest commit?
I couldn't get any information about performance. There seem to be no problems with the jdv communication path.
Fred-Wu commentedon Oct 19, 2026
@eitsupi I have tried the latest commit.
It seems that not all uni-codes are supported for data frames.
The performance issue is associated with wide data. Here is the comparison between
sessandjdvin the data viewer. The data contains 686K rows and 150 columns, and onlyYearandMonthcolumns were shown. Others were hidden.sesssess.mp4
jdvjdv.mp4
eitsupi commentedon Oct 19, 2026
Thanks @Fred-Wu
Sys.getlocale()) and what kind of data were you using? Does the same problem happen with the sess viewer?Fred-Wu commentedon Oct 19, 2026
sessviewer has no issue.jdvArrowTableis correct, but not data frames. Here is my locale and unicodes tested.Arrow Tabledata.framejdvmay send repeated requests to fill the rows requested by AG Grid. The default row fetching is 500 per page. However, due tomax_message_bytesandrow_capacitybudget limits, it may only get 250 rows first, then another 250 rows to fill the requested 500 rows. Here is another demo on a 30M x 11 data.sesssess.mp4
jdvjdv.mp4
eitsupi commentedon Oct 20, 2026
@Fred-Wu Thanks for the report!
I fixed the locale issue and the polling problem on Windows.
Could you try again?
Fred-Wu commentedon Oct 21, 2026
@eitsupi Thanks for fixing those quickly. Unicode issue has been fixed, and scrolling is now smooth for data frames after the polling change.
Table, theArrow streamlabel sits beside the buttons, maybe put it before row count?formatmethod.