Skip to content

[chore] Migrate from unmaintained react-json-view to @microlink/react-json-view#14380

Merged
lukasmasuch merged 7 commits intodevelopfrom
lukasmasuch/migrate-json-viewer
Mar 16, 2026
Merged

[chore] Migrate from unmaintained react-json-view to @microlink/react-json-view#14380
lukasmasuch merged 7 commits intodevelopfrom
lukasmasuch/migrate-json-viewer

Conversation

@lukasmasuch
Copy link
Copy Markdown
Collaborator

@lukasmasuch lukasmasuch commented Mar 16, 2026

Describe your changes

Migrates JSON viewer component from the unmaintained react-json-view to @microlink/react-json-view (v1.31.8), its actively maintained fork.

  • Updates import statements in 3 files (drop-in replacement)
  • Updates NOTICES file with new license attribution
  • Sets showComma={false} for cleaner display (removes trailing commas)
  • Removes reactJsonViewCompat.ts shim (no longer needed with the maintained fork)
  • Updates E2E test to use hover-based interaction (per review feedback)

GitHub Issue Link (if applicable)

N/A

Testing Plan

  • No additional tests needed - existing frontend unit tests validate the component behaves identically
  • lib/src/components/elements/Json/Json.test.tsx — JSON rendering and theme tests
  • lib/src/components/elements/Json/useJsonTooltip.test.ts — Tooltip functionality tests
  • lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.test.tsx — DataFrame JSON cell tests
  • E2E test st_dialog_test.py::test_dialog_copy_buttons_work — Dialog copy button validation

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@lukasmasuch lukasmasuch added impact:internal PR changes only affect internal code change:chore PR contains maintenance or housekeeping change labels Mar 16, 2026
Copilot AI review requested due to automatic review settings March 16, 2026 12:10
@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Mar 16, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 16, 2026

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-14380/streamlit-1.55.0-py3-none-any.whl
📦 @streamlit/component-v2-lib Download from artifacts
🕹️ Preview app pr-14380.streamlit.app (☁️ Deploy here if not accessible)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the deprecated/old react-json-view dependency with the maintained fork @microlink/react-json-view in Streamlit’s frontend JSON rendering components, updating dependency metadata and license notices accordingly.

Changes:

  • Swap react-json-view@microlink/react-json-view in the frontend library dependencies and all relevant imports.
  • Update frontend/yarn.lock to reflect the new dependency graph (including updated transitive packages).
  • Refresh NOTICES entries to add/remove licenses consistent with the dependency changes.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
NOTICES Adds/removes third-party notices to match the updated dependency set (notably @microlink/react-json-view and new transitive deps).
frontend/yarn.lock Locks @microlink/[email protected] and updates transitive dependencies after removing react-json-view.
frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx Updates JSON viewer import to use @microlink/react-json-view.
frontend/lib/src/components/elements/Json/useJsonTooltip.ts Updates OnSelectProps import to @microlink/react-json-view.
frontend/lib/src/components/elements/Json/Json.tsx Updates JSON element import to @microlink/react-json-view.
frontend/lib/package.json Replaces react-json-view dependency with @microlink/react-json-view.

@lukasmasuch lukasmasuch changed the title [chore] Migrate from react-json-view to @microlink/react-json-view [chore] Migrate from unmaintained react-json-view to @microlink/react-json-view Mar 16, 2026
@lukasmasuch lukasmasuch added the update-snapshots Trigger snapshot autofix workflow label Mar 16, 2026
@github-actions github-actions bot removed the update-snapshots Trigger snapshot autofix workflow label Mar 16, 2026
lukasmasuch and others added 3 commits March 16, 2026 13:40
## Describe your changes

Automated snapshot updates for #14380 created via the snapshot autofix
CI workflow.

This workflow was triggered by adding the `update-snapshots` label to a
PR after Playwright E2E tests failed with snapshot mismatches.

**Updated snapshots:** 12 file(s)

⚠️ **Please review the snapshot changes carefully** - they could mask
visual bugs if accepted blindly.

This PR targets a feature branch and can be merged without review
approval.

Co-authored-by: Streamlit Bot <[email protected]>
The @microlink/react-json-view library hides copy buttons via inline
display:none until hover. Updated the test to make the copy container
visible via JS before clicking. Also updated the expected value since
individual copy buttons copy their specific value, not the whole array.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch lukasmasuch added the ai-review If applied to PR or issue will run AI review workflow label Mar 16, 2026
@github-actions github-actions bot removed the ai-review If applied to PR or issue will run AI review workflow label Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR migrates the JSON viewer component from the unmaintained react-json-view (v1.21.3) to the actively maintained fork @microlink/react-json-view (v1.31.8). The migration is a drop-in replacement: import paths are updated in 3 source files (Json.tsx, useJsonTooltip.ts, JsonViewer.tsx), a showComma={false} prop is added for cleaner display, the NOTICES file is updated with new license attributions, E2E snapshots are refreshed, and the dialog copy-button E2E test is adapted to the fork's DOM structure.

Key motivations:

  • Active maintenance: The original react-json-view is unmaintained; the fork is actively maintained.
  • React 18 compatibility: Resolves a peer dependency mismatch (old package declared react: ^17.0.0 || ^16.3.0 || ^15.5.4; the fork uses react: ">= 15").
  • Reduced dependency footprint: Removes heavy transitive dependencies (flux, fbjs, fbemitter, cross-fetch, node-fetch, etc.).

Code Quality

The implementation changes are clean and minimal. All three reviewers agreed on this.

  • Import updates: Straightforward package name swap; the API surface (ReactJson, OnCopyProps, OnSelectProps) is identical.
  • showComma={false} with @ts-expect-error (Json.tsx:85-86, JsonViewer.tsx:97-98): The showComma prop exists at runtime but is missing from the published TypeScript definitions. The @ts-expect-error directive with an explanatory comment is acceptable. A local type augmentation would be cleaner but is not blocking.
  • Comment updates in useJsonTooltip.ts appropriately generalize the reference from "react-json-view" to "the JSON viewer component".
  • NOTICES: Properly updated with new license entries and removed licenses for dropped transitive dependencies.

Issue — E2E test DOM manipulation (all three reviewers flagged this):

In e2e_playwright/st_dialog_test.py:468-473, copy_container.evaluate("el => el.style.display = 'inline'") directly mutates DOM styles to force the copy button visible, then clicks it. This bypasses real user interaction (hover) and couples the test to the third-party component's internal DOM structure. If the CSS :hover behavior broke, this test would still pass, hiding a regression.

Assessment: This is a legitimate concern but a non-blocking one. The test's purpose is to verify that copy-to-clipboard works within dialogs, and it still validates that. The DOM manipulation is a pragmatic workaround for a third-party component's hover-reveal behavior that is difficult to trigger reliably in Playwright. This is a minor quality issue, not a correctness bug. The comment at line 463 ("The react-json-view has a copy button") could also be updated for consistency.

Test Coverage

  • Unit tests (Json.test.tsx, useJsonTooltip.test.ts, JsonViewer.test.tsx): Unchanged and continue to validate rendering, theming, tooltip, and fallback behavior. No new unit tests are needed since the API is identical. (All reviewers agree.)
  • E2E snapshot updates: All 12 snapshot images for st_json_test are updated as expected for the visual differences.
  • E2E dialog copy test: The assertion changed from expect_markdown(app, "[1,2,3]") to expect_markdown(app, "1"). One reviewer (gpt-5.3-codex-high) flagged this as a potential backward-compatibility concern in copy semantics. However, the change reflects a difference in which element is targeted (leaf value vs. root-level), not a regression in clipboard behavior. The test still validates that copy-to-clipboard works in dialogs, which is its purpose.
  • Missing explicit test for showComma={false}: One reviewer (gpt-5.3-codex-high) suggested adding a test. This is a nice-to-have but not required — the behavior is visible in the updated E2E snapshots.

Backwards Compatibility

No breaking changes for Streamlit users:

  • st.json() Python API is unchanged — no backend changes.
  • Minor visual change: trailing commas are removed (showComma={false}), reflected in updated E2E snapshots.
  • All interactive features (expand/collapse, copy-to-clipboard, JSON path tooltip) remain functional with the same API.
  • The enableClipboard handler continues to use JSON.stringify(copy.src), preserving clipboard behavior.

Security & Risk

No security concerns identified:

  • Pure frontend dependency swap with no backend changes.
  • No new external network calls, no eval/unsafe-eval, no XSS risk.
  • New dependencies (color, color-string, lodash-es, simple-swizzle) are well-known MIT-licensed packages.
  • The migration removes potentially unnecessary transitive dependencies (node-fetch, cross-fetch, whatwg-url).
  • Low risk overall. All three reviewers agree.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • All changes are frontend-only (imports, package.json, yarn.lock, NOTICES, E2E snapshots)
    • No routing, auth, WebSocket, embedding, CORS, CSP, session, or storage changes
    • No backend changes
  • Confidence: High (all three reviewers unanimously agree)

Accessibility

No accessibility impact. No new interactive elements introduced. The JSON viewer component's DOM structure and ARIA attributes are maintained by the fork. The showComma={false} change is purely visual and does not affect screen reader behavior. All three reviewers agree.

Reviewer Agreement & Disagreements

Agreement (all three reviewers)

  • The migration is clean, appropriate, and low-risk
  • The @ts-expect-error for showComma is an acceptable workaround
  • No external tests needed
  • No security or accessibility concerns
  • The E2E test DOM manipulation (evaluate("el => el.style.display = 'inline'")) is flagged as suboptimal

Disagreement: Severity of E2E test issue

  • gemini-3.1-pro and gpt-5.3-codex-high: CHANGES REQUESTED — consider the DOM manipulation in the E2E test a blocking issue
  • opus-4.6-thinking: APPROVED — considers it a minor, non-blocking recommendation

Resolution

The E2E test DOM manipulation is a pragmatic workaround, not a correctness bug. The test still validates its core purpose (clipboard integration in dialogs). The third-party component's hover-reveal mechanism may not reliably respond to Playwright's .hover(), making the workaround reasonable. Per the E2E testing guidelines ("As a guiding principle, tests should resemble how users interact with the UI"), a hover-based approach would be ideal, but the current approach is functional and not a regression risk. This is a minor improvement opportunity, not a blocking issue.

Recommendations

  1. Minor — E2E test interaction: Consider replacing the evaluate("el => el.style.display = 'inline'") workaround with a hover-based approach if feasible. If the fork's DOM structure makes hover unreliable in Playwright, the current approach is acceptable.
  2. Minor — Type augmentation for showComma: A local module augmentation would remove the need for @ts-expect-error in two files. Optional improvement.
  3. Nit — E2E test comment: Update the comment at st_dialog_test.py:463 from "The react-json-view has a copy button" to "The JSON viewer has a copy button" for consistency with other comment updates in this PR.

Verdict

APPROVED: Clean, low-risk dependency migration from an unmaintained package to its actively maintained fork. The changes properly update license attributions, refresh E2E snapshots, and maintain API compatibility. The E2E test DOM manipulation is a minor quality concern but does not represent a correctness or regression risk.


This is a consolidated AI review by opus-4.6-thinking.


📋 Review by `gemini-3.1-pro`

Summary

Migrates the JSON viewer component from the unmaintained react-json-view to the actively maintained fork @microlink/react-json-view. This includes updating imports, adjusting the component props (showComma={false}), updating the NOTICES file, and adapting the E2E tests for the new component's DOM structure.

Code Quality

The code changes are clean and straightforward. The use of @ts-expect-error for showComma is appropriate given that the prop exists at runtime but is missing from the library's type definitions.

However, there is a minor issue in the E2E test (e2e_playwright/st_dialog_test.py):

  • Using .evaluate("el => el.style.display = 'inline'") to force the copy button to be visible bypasses actual user interaction. If the CSS :hover state were to break, this test would still pass, hiding a potential UI regression.

Test Coverage

The changes are well covered by existing unit tests and updated E2E snapshot tests. The E2E test for the dialog copy button was updated to reflect the new component's behavior.

Backwards Compatibility

This is a drop-in replacement. Setting showComma={false} removes trailing commas, which is a minor visual change but results in a cleaner display. This should not negatively affect existing users.

Security & Risk

Replacing an unmaintained dependency with an actively maintained fork is a positive change for security and maintainability. No new security risks or regression risks are identified.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • frontend/lib/package.json: Only swaps a React component dependency.
    • frontend/lib/src/components/elements/Json/Json.tsx: Only updates imports and props for the JSON viewer component.
  • Suggested external_test focus areas: N/A
  • Confidence: High
  • Assumptions and gaps: None

Accessibility

No significant accessibility changes. The new component behaves similarly to the old one.

Recommendations

  1. Avoid DOM manipulation in E2E tests: In e2e_playwright/st_dialog_test.py (around line 468), replace copy_container.evaluate("el => el.style.display = 'inline'") with a Playwright .hover() action on the parent element or row that triggers the visibility. E2E tests should simulate real user interactions as closely as possible.
    copy_container = json_element.locator(".copy-to-clipboard-container").first
    # Hover over the parent row to reveal the copy button naturally
    copy_container.locator("..").hover()
    copy_container.click()
    (If hovering the parent doesn't work due to the specific DOM structure, try finding the closest visible container row to hover, or use .click(force=True) as a last resort rather than modifying the style attribute directly).

Verdict

CHANGES REQUESTED: Please update the E2E test to use a natural hover interaction instead of modifying the DOM's style attribute directly.


This is an automated AI review by gemini-3.1-pro.

📋 Review by `gpt-5.3-codex-high`

Summary

This PR migrates the frontend JSON viewer from react-json-view to @microlink/react-json-view, updates dependency metadata (frontend/lib/package.json, frontend/yarn.lock, NOTICES), and adjusts JSON rendering config (showComma={false}) in both main JSON rendering surfaces. It also updates E2E snapshots and modifies one dialog copy-button E2E test.

Code Quality

The migration in implementation files is generally clean and minimal (frontend/lib/src/components/elements/Json/Json.tsx, frontend/lib/src/components/elements/Json/useJsonTooltip.ts, frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx).

Issue found:

  • e2e_playwright/st_dialog_test.py:468-473 directly mutates DOM styles via evaluate("el => el.style.display = 'inline'") and clicks a library-internal CSS container (.copy-to-clipboard-container). This bypasses real user interaction behavior (hover/focus) and couples the test to private DOM structure of the third-party component, making the test brittle and lower-signal.

Test Coverage

  • Existing unit tests still cover parsing/theming/path behavior (frontend/lib/src/components/elements/Json/Json.test.tsx, frontend/lib/src/components/elements/Json/useJsonTooltip.test.ts, frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.test.tsx).
  • However, there is no explicit new assertion for the newly introduced showComma={false} behavior in:
    • frontend/lib/src/components/elements/Json/Json.tsx:85-86
    • frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx:97-98
  • The changed dialog copy test now asserts copying "1" (e2e_playwright/st_dialog_test.py:481-482) after forced DOM visibility, which no longer validates the prior user-level copy flow and may miss regressions in actual hover/copy UI behavior.

Backwards Compatibility

  • Potential behavior drift is visible in test expectations: copy behavior changed from array/object-level content to leaf value (e2e_playwright/st_dialog_test.py:481-482). If intentional, this should be explicitly documented as a UX change; if unintentional, this is a backward-compatibility regression in st.json copy semantics.
  • The comma display change (showComma={false}) is a visible output change and should be considered a minor UX behavior update.

Security & Risk

  • No backend/auth/session/websocket/endpoint/CORS/security-header changes were found in this PR.
  • No direct high-risk patterns (e.g., eval, dynamic code execution, command injection paths) were introduced in changed repository code.
  • Dependency change introduces new transitive packages via @microlink/react-json-view; this is normal for the migration but should continue to rely on existing dependency governance/scanning.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • frontend/lib/src/components/elements/Json/Json.tsx: frontend component import/config migration only; no routing/auth/ws/cross-origin/storage changes.
    • frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx: same scope (UI rendering layer only).
    • frontend/lib/package.json, frontend/yarn.lock, NOTICES: dependency/license metadata updates only.
    • e2e_playwright/st_dialog_test.py: test adaptation for copy interaction; no external-hosting/embedding-runtime changes.
  • Suggested external_test focus areas:
    • None required by this diff.
    • Optional smoke check only: verify JSON rendering/copy behavior in an externally hosted embedded app if this area has recent instability.
  • Confidence: High
  • Assumptions and gaps: Assessment is based on repository diff only; third-party package internals were not audited beyond lockfile metadata.

Accessibility

  • No new first-party custom interactive controls were introduced in Streamlit-owned code paths.
  • Accessibility risk is low but non-zero because behavior is delegated to a different third-party JSON viewer implementation; no new a11y-specific tests were added for keyboard/screen-reader copy interactions.

Recommendations

  1. Update e2e_playwright/st_dialog_test.py to validate copy behavior via user-realistic interaction (hover/focus + visible control click) and avoid DOM style mutation / internal class coupling.
  2. Add explicit tests for migrated behavior that now matters to users (at minimum: copy semantics and comma rendering) to make regression intent clear.

Verdict

CHANGES REQUESTED: The implementation migration is mostly solid, but the modified dialog copy E2E test bypasses user behavior and may hide copy-semantic regressions, so this is not merge-ready yet.


This is an automated AI review by gpt-5.3-codex-high. Please verify the feedback and use your judgment.

📋 Review by `opus-4.6-thinking`

Summary

This PR migrates the JSON viewer component from the unmaintained react-json-view (v1.21.3) to its actively maintained fork @microlink/react-json-view (v1.31.8). The migration is essentially a drop-in replacement — import paths are updated in 3 source files, a showComma={false} prop is added for cleaner display, the NOTICES file is updated with new license attributions, E2E snapshots are refreshed, and the dialog copy-button E2E test is adapted to the fork's slightly different DOM structure.

Key improvements:

  • React 18 peer dependency support: The old package declared react: ^17.0.0 || ^16.3.0 || ^15.5.4, excluding React 18. The fork uses react: ">= 15", properly covering React 18.
  • Reduced dependency footprint: Removes heavy transitive dependencies (flux, fbjs, fbemitter, cross-fetch, node-fetch, promise, asap, base16, pure-color, whatwg-url, webidl-conversions). Adds lighter alternatives (color, color-string, lodash-es, simple-swizzle).
  • Active maintenance: The original react-json-view has been unmaintained; @microlink/react-json-view is actively maintained.

Code Quality

The code changes are clean and minimal:

  • Import updates (Json.tsx, useJsonTooltip.ts, JsonViewer.tsx): Straightforward package name swap. The API surface (ReactJson, OnCopyProps, OnSelectProps) is identical.
  • showComma={false} with @ts-expect-error (Json.tsx:85-86, JsonViewer.tsx:97-98): The showComma prop exists at runtime in @microlink/react-json-view but is missing from the published TypeScript definitions. The @ts-expect-error directive with an explanatory comment is an acceptable workaround. This could be improved by submitting a type fix upstream or adding a local type augmentation, but it's not blocking.
  • CSS selectors in styled-components.ts (line 22) and JsonViewer.tsx (line 33) use .react-json-view .copy-icon svg — these class names are preserved by the fork, so the selectors continue to work correctly.
  • Comment updates in useJsonTooltip.ts (lines 43, 74) appropriately generalize the reference from "react-json-view" to "the JSON viewer component".
  • NOTICES: Properly adds the new @microlink/react-json-view license entry and removes licenses for dropped transitive dependencies. The invariant, prop-types, warning license entry was updated to remove fbjs/fbjs-css-vars since those are no longer included. @types/lodash was added since it's a new transitive dependency.

Test Coverage

  • Existing unit tests (Json.test.tsx, useJsonTooltip.test.ts, JsonViewer.test.tsx) are unchanged and continue to validate the same behavior — rendering, theming, tooltip functionality, and fallback for invalid JSON. No new unit tests are needed since the API is identical.
  • E2E snapshot updates: All 12 snapshot images for st_json_test are updated (copy icon hover for light/dark themes across 3 browsers, width and bounds tests). This is expected given the visual differences from the fork (e.g., comma removal via showComma={false}).
  • E2E dialog copy test (st_dialog_test.py:460-482): Adapted to the fork's DOM structure. The old test hovered and clicked .copy-icon.first (root-level copy, copying [1,2,3]). The new test targets .copy-to-clipboard-container.first and copies value 1 (the first individual value). Two observations:
    1. Using evaluate("el => el.style.display = 'inline'") to force the copy container visible is somewhat brittle compared to the previous hover-based approach, but may be necessary given DOM structure differences in the fork.
    2. The assertion changed from expect_markdown(app, "[1,2,3]") to expect_markdown(app, "1") — this validates clipboard integration still works, though it tests a different granularity of copy. The test's purpose is to verify copy-paste works in dialogs, which it still does.

Overall, test coverage is adequate for this dependency migration.

Backwards Compatibility

No breaking changes for Streamlit users:

  • st.json() API is unchanged — no Python-side changes.
  • The visual appearance will have minor differences (trailing commas removed due to showComma={false}), which are reflected in updated E2E snapshots.
  • The JSON viewer's interactive features (expand/collapse, copy-to-clipboard, JSON path tooltip) all remain functional with the same API.
  • The enableClipboard handler in Json.tsx continues to use JSON.stringify(copy.src), preserving the clipboard behavior.

Security & Risk

No security concerns identified:

  • This is a pure frontend dependency swap with no backend changes.
  • No new external network calls, no eval/unsafe-eval, no XSS risk.
  • The new package and its dependencies (color, color-string, lodash-es, simple-swizzle) are well-known, widely-used open-source packages with MIT licenses.
  • The migration removes potentially risky transitive dependencies (node-fetch, cross-fetch, whatwg-url) that were unused artifacts of the old flux/fbjs dependency chain.
  • No HTML/Markdown sanitization changes.

Risk assessment:

  • Low risk. The fork is API-compatible, actively maintained, and resolves the React 18 peer dependency mismatch.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • All changes are frontend-only (import paths, package.json, yarn.lock, NOTICES, E2E snapshots)
    • No routing, auth, WebSocket, embedding, CORS, CSP, session, or storage changes
    • No backend changes whatsoever
  • Suggested external_test focus areas: N/A
  • Confidence: High
  • Assumptions and gaps: None — this is a straightforward frontend dependency swap with no cross-layer impact.

Accessibility

No accessibility impact:

  • No new interactive elements are introduced.
  • The JSON viewer component's DOM structure (including ARIA attributes from the library) is maintained by the fork.
  • The showComma={false} change is purely visual and does not affect screen reader behavior.
  • The copy-to-clipboard functionality remains accessible through the same interaction patterns.

Recommendations

  1. Minor — E2E test brittleness: The copy_container.evaluate("el => el.style.display = 'inline'") workaround in st_dialog_test.py:470 directly manipulates DOM styles, which is fragile. Consider verifying whether a hover interaction (similar to the old test) would work with the fork's copy button visibility mechanism. If not feasible, the current approach is acceptable.

  2. Minor — Consider type augmentation for showComma: Rather than @ts-expect-error, a local module augmentation could provide type safety:

    declare module "@microlink/react-json-view" {
      interface ReactJsonViewProps {
        showComma?: boolean
      }
    }

    This is optional but would remove the need for suppression comments in two files.

  3. Housekeeping — Comment in E2E test: The comment at st_dialog_test.py:463 still says "The react-json-view has a copy button" — while technically descriptive, it could be updated to reference the library by its current package name or simply say "The JSON viewer" for consistency with the useJsonTooltip.ts comment updates.

Verdict

APPROVED: Clean, low-risk dependency migration from an unmaintained package to its actively maintained fork, with proper license updates, snapshot refreshes, and test adaptations. The changes improve React 18 compatibility and reduce the dependency footprint.


This is an automated AI review by opus-4.6-thinking.

Use hover-based interaction instead of DOM style manipulation
to reveal the copy button, following E2E best practices.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch lukasmasuch added the ai-review If applied to PR or issue will run AI review workflow label Mar 16, 2026
@github-actions github-actions bot removed the ai-review If applied to PR or issue will run AI review workflow label Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR migrates the JSON viewer component from the unmaintained react-json-view (v1.21.3) to its actively maintained fork @microlink/react-json-view (v1.31.8). The changes are minimal and focused:

  • Import updates in 3 TypeScript files (Json.tsx, useJsonTooltip.ts, JsonViewer.tsx) — drop-in replacement.
  • showComma={false} prop added to both Json.tsx and JsonViewer.tsx for cleaner display.
  • E2E test (st_dialog_test.py) updated to match the new copy-button interaction model (hover-based, per-row copy).
  • 12 E2E snapshots updated to reflect minor visual differences.
  • NOTICES file updated with new license attributions and stale entries removed.
  • package.json / yarn.lock updated: old react-json-view removed, @microlink/react-json-view added.

The old library had a stale peer dependency on React ≤17, while Streamlit uses React 18. The fork (react: ">= 15") properly supports React 18+, making this also a compatibility fix.

Reviewer Consensus

All three reviewers (gemini-3.1-pro, gpt-5.3-codex-high, opus-4.6-thinking) unanimously approved this PR. No reviewer raised blocking issues. There were no disagreements on any aspect of the review.

Code Quality

[Full agreement] All reviewers found the code changes clean, minimal, and well-executed:

  • Import migration is consistent and correct across all three files. No residual imports from the old package.
  • The @ts-expect-error usage for showComma in Json.tsx and JsonViewer.tsx is well-documented with a clear rationale comment ("prop exists at runtime but is missing from type definitions"). All reviewers considered this an acceptable pragmatic pattern.
  • The NOTICES file update is thorough — new entries added for @microlink/react-json-view, color, color-string, simple-swizzle, and stale entries properly removed for react-json-view, asap, base16, cross-fetch, fbemitter, fbjs/fbjs-css-vars, flux, node-fetch, promise, pure-color, webidl-conversions, whatwg-url.
  • JSDoc comments in useJsonTooltip.ts updated to use generic "the JSON viewer component" rather than coupling to a specific package name.

[Unique observation — opus-4.6-thinking] CSS selector stability concern: Both styled-components.ts:22 and JsonViewer.tsx:33 still target .react-json-view .copy-icon svg, while the E2E test switched from .copy-icon to .copy-to-clipboard-container. If the fork renamed the .copy-icon class, copy icon styling would silently stop applying. Updated E2E snapshots suggest the styling still works, but explicit verification is recommended.

Test Coverage

[Full agreement] Coverage is adequate for a dependency swap:

  • Unit tests (unchanged): Json.test.tsx, useJsonTooltip.test.ts, JsonViewer.test.tsx validate rendering, theming, tooltip state, and invalid JSON handling with the new library.
  • E2E tests: st_json_test.py covers display, bounds, theming, copy icon on hover, and JSON path tooltip (12 snapshots updated). st_dialog_test.py updated to match new copy interaction model.

[Unique observation — opus-4.6-thinking] The E2E test behavioral change in st_dialog_test.py reflects a subtle library behavior difference: copy buttons are now per-row rather than at the root level. The old test copied the entire array [1,2,3]; the new test copies just the first value 1. The test correctly adapts to the new behavior.

Backwards Compatibility

[Full agreement] No breaking Streamlit API changes. The st.json() Python API is completely unchanged.

User-visible deltas are cosmetic:

  1. Comma removal: showComma={false} removes trailing commas — deliberate cosmetic improvement.
  2. Visual rendering: Minor differences in copy icon positioning, fonts, spacing (captured by 12 updated snapshots).
  3. Copy behavior change: Copy-to-clipboard now operates per-row rather than at root level. This is a minor UX change in the third-party component, not a Streamlit API change.

Security & Risk

[Full agreement] Low risk. No security concerns identified:

  • No changes to WebSocket handling, authentication, file serving, CORS, CSP, iframe embedding, or other security-critical paths.
  • No dynamic code execution patterns (eval, Function, exec/subprocess).
  • The dependency swap actually improves security posture: removes unmaintained dependencies (flux, fbjs, cross-fetch, fbemitter, node-fetch) and reduces overall dependency surface area.
  • @microlink/react-json-view is published on npm with the same MIT license as the original.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence: Purely frontend UI component dependency swap with no server, networking, embedding, auth, routing, cross-origin, or storage implications.
  • Confidence: High (unanimous across all three reviewers)

Accessibility

[Full agreement] No accessibility regressions identified. The fork maintains the same interactive structure (keyboard-navigable JSON tree, copy buttons).

[Unique observation — opus-4.6-thinking] The fork's copy buttons should ideally have aria-label attributes for screen reader users, but this is an upstream concern in the third-party library, not something introduced by this PR.

Consolidated Recommendations

  1. Verify .copy-icon CSS class (opus-4.6-thinking): Confirm that @microlink/react-json-view still renders elements with the .copy-icon class used in styled-components.ts and JsonViewer.tsx CSS selectors. Snapshot tests suggest it works, but explicit verification adds confidence.

  2. Upstream type contribution (opus-4.6-thinking, gpt-5.3-codex-high): Both reviewers noted that the showComma prop's @ts-expect-error could be resolved. Options: open an issue/PR upstream to add the prop to type definitions, or add a local type augmentation module to type it without @ts-expect-error.

  3. Consider targeted comma-display assertion (gpt-5.3-codex-high): Add a frontend unit test assertion for showComma={false} behavior to lock in this intended UX change.

None of these recommendations are blocking.

Verdict

APPROVED: Unanimous approval across all three reviewers. This is a clean, low-risk dependency migration from the unmaintained react-json-view to its actively maintained fork @microlink/react-json-view, with appropriate test updates, snapshot refreshes, NOTICES/license attribution changes, and a net reduction in dependency surface. The swap fixes React 18 compatibility and introduces no breaking API changes.


This is a consolidated AI review by opus-4.6-thinking, synthesizing reviews from gemini-3.1-pro, gpt-5.3-codex-high, and opus-4.6-thinking.

All 3 of 3 expected reviewers completed their reviews successfully.


📋 Review by `gemini-3.1-pro`

Summary

This PR migrates the JSON viewer component from the unmaintained react-json-view to its actively maintained fork @microlink/react-json-view. This is a drop-in replacement that updates imports, adds a showComma={false} prop for cleaner display, updates the NOTICES file, and adapts the E2E test to the new DOM structure and hover-based interactions.

Code Quality

The code changes are clean, minimal, and well-executed:

  • Import updates are straightforward and correct.
  • The use of @ts-expect-error for showComma in frontend/lib/src/components/elements/Json/Json.tsx and frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx is appropriately documented with a comment explaining that the prop exists at runtime but is missing from type definitions.
  • The NOTICES file is properly updated, adding the new license and removing licenses for dropped transitive dependencies.
  • The E2E test in e2e_playwright/st_dialog_test.py correctly uses Playwright's .hover() to reveal the copy button, simulating real user interaction rather than relying on DOM style manipulation.

Test Coverage

Test coverage is adequate. Existing frontend unit tests remain valid as the component behaves identically. The E2E snapshots have been updated to reflect the visual changes (removal of trailing commas). The dialog copy-button E2E test has been successfully adapted to target the new .copy-to-clipboard-container and correctly expects the copied value.

Backwards Compatibility

There are no breaking changes. The component acts as a drop-in replacement. The visual appearance is slightly cleaner due to the removal of trailing commas, and the interactive features (expand/collapse, copy-to-clipboard) remain fully functional.

Security & Risk

No security concerns identified. This is a frontend dependency swap that introduces no new external network calls, no unsafe JS execution, and no backend changes. It also removes several heavy transitive dependencies, reducing the overall dependency footprint.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • Changes are strictly frontend dependency updates and UI rendering adjustments.
    • No changes to routing, auth, WebSocket, embedding, cross-origin behavior, or storage.
  • Suggested external_test focus areas: N/A
  • Confidence: High
  • Assumptions and gaps: None

Accessibility

No accessibility impact. The JSON viewer component's DOM structure and ARIA attributes are maintained by the fork, and the showComma={false} change is purely visual.

Recommendations

None. The implementation is solid and the previous feedback regarding the E2E test interaction has been addressed.

Verdict

APPROVED: Clean and low-risk dependency migration to an actively maintained fork, with proper test adaptations and license updates.


This is an automated AI review by gemini-3.1-pro. Please verify the feedback and use your judgment.

📋 Review by `gpt-5.3-codex-high`

Summary

This PR cleanly migrates JSON rendering from react-json-view to the maintained fork @microlink/react-json-view in both JSON surfaces (st.json and DataFrame JSON cell viewer), updates lockfile/legal notices, and adjusts one dialog e2e test plus related JSON snapshots to match the new copy-button hover behavior and comma display.

Code Quality

The implementation is intentionally small and focused:

  • Import migration is consistent across frontend/lib/src/components/elements/Json/Json.tsx, frontend/lib/src/components/elements/Json/useJsonTooltip.ts, and frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx.
  • The added showComma={false} behavior is applied consistently in both JSON viewers.
  • Dependency metadata and licensing updates in frontend/lib/package.json, frontend/yarn.lock, and NOTICES are coherent with the library swap.

No blocking code-quality issues found.

Test Coverage

Coverage is solid for this scope:

  • Existing frontend unit tests for JSON rendering/theme/tooltip and DataFrame JSON fallback behavior still cover core behavior (frontend/lib/src/components/elements/Json/Json.test.tsx, frontend/lib/src/components/elements/Json/useJsonTooltip.test.ts, frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.test.tsx).
  • The updated e2e flow in e2e_playwright/st_dialog_test.py now validates the hover-to-reveal copy interaction path used by the new package.
  • Snapshot updates in e2e_playwright/__snapshots__/linux/st_json_test/ capture visual deltas introduced by the migration.

No testing gaps that should block merge.

Backwards Compatibility

No API-level breaking change is introduced. This is a frontend dependency migration with behavior parity goals.
Expected user-visible delta: JSON viewer comma presentation is intentionally changed (showComma={false}), which is cosmetic and low-risk.

Security & Risk

No security-sensitive backend/runtime surfaces were modified (no auth/session/websocket/server endpoint changes).
No new dynamic code-execution patterns (eval, Function, Python exec/subprocess) were introduced.
Risk profile is low; primary change is a third-party frontend dependency replacement.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • frontend/lib/src/components/elements/Json/Json.tsx: frontend JSON viewer dependency swap and display prop change only.
    • frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx: same scoped UI component migration.
    • e2e_playwright/st_dialog_test.py: selector/interaction update for copy button behavior; no external hosting, routing, auth, iframe-boundary, or cross-origin logic changes.
    • frontend/lib/package.json and frontend/yarn.lock: dependency graph update only.
  • Suggested external_test focus areas:
    • None required for this PR specifically.
    • Continue normal external coverage for unrelated routing/auth/embedding changes in future PRs.
  • Confidence: High
  • Assumptions and gaps: Assessment is based on this PR diff only; no hidden runtime feature flags or out-of-band infra changes are included.

Accessibility

No new custom interactive controls were introduced; interactions remain provided by the JSON viewer component.
No explicit a11y regressions are evident in this diff. The hover-based copy affordance remains a known pattern; this PR does not worsen keyboard/screen-reader behavior relative to prior implementation.

Recommendations

  1. Consider adding a targeted frontend assertion for comma-display behavior (showComma={false}) to lock in this intended UX change.
  2. Consider a local type augmentation for @microlink/react-json-view so showComma can be typed without @ts-expect-error in two call sites.

Verdict

APPROVED: The migration is focused, low-risk, adequately covered by existing and updated tests, and appears ready to merge.


This is an automated AI review by gpt-5.3-codex-high. Please verify the feedback and use your judgment.

📋 Review by `opus-4.6-thinking`

Summary

This PR migrates the JSON viewer component from the unmaintained react-json-view (v1.21.3) to @microlink/react-json-view (v1.31.8), its actively maintained fork. The changes are intentionally minimal:

  • Import updates in 3 TypeScript files (Json.tsx, useJsonTooltip.ts, JsonViewer.tsx) — drop-in replacement.
  • showComma={false} prop added to both Json.tsx and JsonViewer.tsx for cleaner display.
  • E2E test (st_dialog_test.py) updated to match new copy-button interaction model.
  • 12 E2E snapshots updated to reflect minor visual differences.
  • NOTICES file updated with new license attributions and stale entries removed.
  • package.json / yarn.lock updated: old react-json-view removed, @microlink/react-json-view added.

The old library had a stale peer dependency on React ≤17, while Streamlit uses React 18. The fork (react: ">= 15") properly supports React 18+, making this also a compatibility fix.

Code Quality

The code changes are clean and well-structured.

  1. Import swap is correct: All three files (Json.tsx:19, useJsonTooltip.ts:19, JsonViewer.tsx:22) now import from @microlink/react-json-view. No residual imports from the old package exist.

  2. @ts-expect-error for showComma: Used in both Json.tsx:85 and JsonViewer.tsx:97. The comment clearly explains the rationale ("prop exists at runtime but is missing from type definitions"). This is an acceptable pragmatic pattern.

  3. JSDoc comment updates in useJsonTooltip.ts (lines 43, 75): References to react-json-view updated to "the JSON viewer component" — good, avoids package-name coupling in documentation.

  4. CSS selector stability concern: Both styled-components.ts:22 and JsonViewer.tsx:33 still target .react-json-view .copy-icon svg. Since the E2E test switched from .copy-icon to .copy-to-clipboard-container, it's worth verifying that the .copy-icon class is still rendered by the fork. If the fork renamed this class, the copy icon styling (font size, margin, vertical alignment) would silently stop applying. The updated E2E snapshots suggest the styling still works, but this should be explicitly confirmed.

  5. NOTICES file: Properly updated — added @microlink/react-json-view, color, color-string, simple-swizzle, invariant/prop-types/warning (split from fbjs group), @types/lodash. Removed stale entries for react-json-view, asap, base16, cross-fetch, fbemitter, fbjs/fbjs-css-vars, flux, node-fetch, promise, pure-color, webidl-conversions, whatwg-url. The cleanup is thorough and correctly reflects the dependency tree change.

Test Coverage

Unit tests (unchanged, covering the swap):

  • Json.test.tsx — Tests JSON rendering, invalid JSON handling, and theme selection. These validate the component works identically with the new library.
  • useJsonTooltip.test.ts — Tests tooltip state management, mousedown tracking, and path formatting. These validate the hook works with the new OnSelectProps type.
  • JsonViewer.test.tsx — Tests JSON object/string rendering, invalid JSON fallback, and null/undefined handling.

E2E tests:

  • st_json_test.py — Existing tests cover display, bounds, theming, copy icon on hover, and JSON path tooltip. Snapshots are updated.
  • st_dialog_test.py — The test_dialog_copy_buttons_work test was updated to match the new copy interaction model.

E2E test behavioral change (st_dialog_test.py:454-484): The copy test previously hovered on the JSON element and clicked .copy-icon.first, which copied the entire array [1,2,3]. The new test hovers on .variable-row.first and clicks .copy-to-clipboard-container.first, which copies just the first value 1. This reflects a subtle behavior change in the library: copy buttons are now per-row rather than at the root level. The test correctly adapts to the new behavior.

Coverage is adequate for a dependency swap. The existing test suites validate that the component behaves identically in rendering and interaction.

Backwards Compatibility

  1. Visual differences: The 12 updated snapshots indicate minor visual rendering differences (e.g., copy icon positioning, fonts, spacing). These are expected when swapping library versions and are cosmetic.

  2. Copy behavior change: The copy-to-clipboard interaction now operates per-row rather than at a top-level scope. Users who previously used the root-level copy icon to copy entire JSON structures will experience a different behavior. However, this is a minor UX change in the third-party component and not a Streamlit API change.

  3. showComma={false}: Removes trailing commas from JSON display. This is a deliberate cosmetic improvement and is unlikely to affect users negatively.

  4. No Streamlit API changes: The st.json() Python API is completely unchanged. This is purely a frontend dependency swap.

No breaking changes for existing users.

Security & Risk

  1. New dependency: @microlink/react-json-view is the actively maintained fork of the original react-json-view by the Microlink team. It's published on npm with the same MIT license. The dependency tree is actually simpler — the old react-json-view pulled in flux, fbjs, cross-fetch, fbemitter, and other heavy/deprecated Facebook dependencies. The new fork uses [email protected], react-lifecycles-compat, and react-textarea-autosize — a cleaner, lighter set.

  2. Transitive dependency reduction: The swap removes several transitive dependencies (node-fetch, whatwg-url, webidl-conversions, tr46, promise, asap, fbjs-css-vars, base16, pure-color, lodash.curry, lodash.flow). New transitive deps added are color, color-string, simple-swizzle, is-arrayish, @types/lodash, csstype, lodash-es. Net reduction in dependency surface.

  3. No security-sensitive areas touched: No changes to WebSocket handling, authentication, file serving, CORS, CSP, iframe embedding, or other security-critical paths.

  4. No runtime code execution risks: The library is a UI component for rendering JSON — no eval, Function(), or dynamic code execution.

Low risk overall. The dependency swap actually improves the security posture by removing unmaintained dependencies.

External test recommendation

  • Recommend external_test: No
  • Triggered categories: None
  • Evidence:
    • frontend/lib/src/components/elements/Json/Json.tsx: Import change only, no routing/auth/embedding impact
    • frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx: Import change only, no networking/cross-origin behavior
    • frontend/lib/package.json: Frontend dependency swap, no server-side changes
    • e2e_playwright/st_dialog_test.py: E2E test selector update, no infrastructure change
  • Suggested external_test focus areas: None required
  • Confidence: High
  • Assumptions and gaps: None — this is a purely frontend UI component dependency swap with no server, networking, embedding, auth, or storage implications.

Accessibility

No accessibility regressions identified. The @microlink/react-json-view fork maintains the same interactive structure (keyboard-navigable JSON tree, copy buttons). The copy icon styling selectors (.react-json-view .copy-icon svg) remain in place. The updated snapshots show visually consistent rendering.

One minor note: The fork's copy buttons should ideally have aria-label attributes for screen reader users, but this is an upstream concern in the third-party library, not something introduced by this PR.

Recommendations

  1. Verify .copy-icon CSS class: Confirm that the @microlink/react-json-view fork still renders elements with the .copy-icon class. Both styled-components.ts:22 and JsonViewer.tsx:33 target .react-json-view .copy-icon svg for styling. If the fork renamed this class, the copy icon sizing/spacing would silently stop applying. The snapshot tests suggest it works, but explicit verification would add confidence.

  2. Consider upstream type contribution: The showComma prop requires @ts-expect-error in two places because it's missing from the type definitions. Consider opening an issue or PR on the @microlink/react-json-view repo to add this prop to the type definitions, which would allow removing the @ts-expect-error suppression in the future.

Verdict

APPROVED: Clean dependency migration from unmaintained react-json-view to its actively maintained fork @microlink/react-json-view, with appropriate test updates, snapshot refreshes, and NOTICES/license attribution changes. The swap reduces dependency surface, fixes React 18 compatibility, and introduces no breaking API changes.


This is an automated AI review by opus-4.6-thinking.

The compat shim was created for the old react-json-view CommonJS module
with Vite 8 interop issues. Since @microlink/react-json-view is actively
maintained and direct imports work correctly, the shim is no longer needed.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch lukasmasuch merged commit 0ae9988 into develop Mar 16, 2026
43 checks passed
@lukasmasuch lukasmasuch deleted the lukasmasuch/migrate-json-viewer branch March 16, 2026 20:40
lukasmasuch added a commit that referenced this pull request Mar 17, 2026
## Describe your changes

Restores the `reactJsonViewCompat.ts` compatibility shim that was
removed in #14380. The direct import from `@microlink/react-json-view`
works in CI builds but fails when running locally with the dev server
(e.g., `make debug` or `make frontend-dev`).

**Changes:**
- Restored `frontend/lib/src/util/reactJsonViewCompat.ts` with updated
imports for `@microlink/react-json-view`
- Updated `Json.tsx`, `useJsonTooltip.ts`, and `JsonViewer.tsx` to
import through the compat shim

**Why this is needed:**
- `@microlink/react-json-view` is published as CommonJS
- Vite 8 interop can yield different runtime module shapes (`module`,
`module.default`, `module.default.default`) depending on the
optimization path
- Without normalization, Json components fail with "Element type is
invalid" errors in local dev

## GitHub Issue Link (if applicable)

- Related to #14380

## Testing Plan

- [x] Unit Tests (existing tests pass)
- [x] Manual testing with `make debug` to verify Json elements render
correctly

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

<!-- agent-metrics-start -->
<details>
<summary>Agent metrics</summary>

| Type | Name | Count |
|------|------|------:|
| subagent | fixing-pr | 1 |
| subagent | general-purpose | 1 |

</details>
<!-- agent-metrics-end -->

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:chore PR contains maintenance or housekeeping change impact:internal PR changes only affect internal code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants