npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nfdi4plants/arc-web-view

v2.1.0

Published

An Annotated Research Context web viewer in the style of GitHub's Primer ProductUI.

Readme

@nfdi4plants/arc-web-view

NPM Version DOI

An Annotated Research Context web viewer in the style of GitHub's Primer ProductUI.

Displays basic information about an ARC (Annotated Research Context) and allows to navigate through its structure.

👀 check out the demo

Install

npm i @nfdi4plants/arc-web-view
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BaseStyles, ThemeProvider } from '@primer/react'
import '@primer/primitives/dist/css/functional/themes/light.css'
import "@primer/css/dist/primer.css";
import { WebViewer } from '@nfdi4plants/arc-web-view'


createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ThemeProvider>
      <BaseStyles>
        <WebViewer /> // will load with empty view
      </BaseStyles>
    </ThemeProvider>
  </StrictMode>,
)

Development

This component uses GitHubs Primer ProductUI.

Find more information below:

  • Components: https://primer.style/product/components/
  • Responsive: https://github.com/primer/css/blob/b5e009778ec01b6e983cba6cbf89cebfdc5a4124/docs/content/support/breakpoints.md#media-query-mixins

Entry points and configuration

The application entry point is src/main.tsx; the npm library exports WebViewer through src/lib.ts. Both use App, which calls resolveViewerConfig in src/config.ts as the single decision point for configuration:

flowchart TD
    Start["resolveViewerConfig(props)"] --> Bridge{"Non-null window.arcwebview?"}
    Bridge -- Yes --> Plugin["Plugin mode: use bridge only"]
    Bridge -- No --> Props{"Any supported prop is not undefined?"}
    Props -- Yes --> Component["Component mode: use props"]
    Props -- No --> Showcase["Showcase mode: use defaults"]
    Plugin --> Defaults["Apply defaults for omitted options"]
    Component --> Defaults
    Showcase --> Defaults
    Defaults --> Loader{"Selected JSON loader?"}
    Loader -- Yes --> Load["Load ARC; show an error on failure"]
    Loader -- No --> Empty["Show upload and example data"]

| Priority | Entry point | Configuration source | | --- | --- | --- | | 1 | Embedded in an iframe by the Invenio plugin | window.arcwebview, including an empty {} | | 2 | Used as a component in another React application | Supported component props, when the bridge is absent | | 3 | GitHub Pages showcase | Defaults, when neither a bridge nor supported prop values are supplied |

The bridge is an explicit convention for plugin mode. It takes precedence over all component props. Missing bridge fields use defaults, without falling back to props. An absent or null bridge allows component mode. React passes a props object even for <WebViewer />, so the resolver checks supported values against undefined; showUnloadButton: false selects component mode and hides the unload button. Supplying only layout also selects component mode, including an empty {}. Unrelated props do not affect the decision.

| Option | Bridge field | React prop | Default | | --- | --- | --- | --- | | Asynchronous ROC-JSON loader | getROCJson | jsonString | No loader | | Asynchronous README loader | readmefetch | readmefetch | No README | | Asynchronous license loader | licensefetch | licensefetch | No license | | Show unload button | showUnloadButton | showUnloadButton | true | | Initially open file sidebar | layout.sidebarOpen | layout.sidebarOpen | false | | Initially expand provenance graph | layout.provenancesOpen | layout.provenancesOpen | true |

All loaders return Promise<string>. The optional bridge and its settings share one TypeScript declaration in src/config.ts; ArcWebViewBridge, WebViewerProps, and LayoutOptions are exported from the npm library. Boolean defaults use nullish coalescing (??), preserving explicit false.

For example, with a loadArcJson callback supplied by the integration:

// Initialize inside the Invenio iframe before React mounts.
window.arcwebview = {
  getROCJson: loadArcJson,
  showUnloadButton: false,
  layout: { sidebarOpen: true, provenancesOpen: false },
};
// In another React app, with no window.arcwebview bridge:
<WebViewer
  jsonString={loadArcJson}
  showUnloadButton={false}
  layout={{ sidebarOpen: true, provenancesOpen: false }}
/>

// With neither bridge nor props, use the showcase defaults:
<WebViewer />

layout sets the initial panel state when ARC content mounts. Both fields are optional and default independently, so layout={{ provenancesOpen: false }} starts with the sidebar closed and the graph collapsed. On small screens, an open sidebar appears as a side sheet and closes after file navigation. The sidebar toggle, graph Show/Hide button, and "Show in provenance graph" action remain available. Collapsing the graph leaves its heading and Show button visible.

Users can change these states after loading. Updating layout props on an already mounted viewer does not reset them; remount the component (for example, with a new React key) to apply new initial values. Clearing and reloading ARC content also applies the initial layout again.

Without a selected JSON loader, all modes start with an empty view offering upload and example data. With a loader, the viewer shows a spinner until loading completes. Only the selected source's loader runs; a failure displays an error without trying another source. When the selected loader changes, previous ARC data, errors, and example mode are cleared. Results from superseded requests or unmounted viewers are ignored. React Strict Mode may invoke the selected loader again during development, so loaders should be safe to repeat.

Integration considerations:

  • Initialize the bridge in the iframe's own window before mounting React. Setting it on the parent page does not configure the iframe; direct iframe access is subject to the same-origin policy. Cross-origin integrations need communication such as postMessage, with bridge initialization inside the iframe.
  • Bridge mutation is not reactive. For later configuration changes, use React props in component mode, or remount the plugin viewer after updating its bridge. Keep loader references stable to avoid unnecessary reloads.
  • Every viewer in the same window shares the bridge. Use props in a window without a bridge for independently configured React instances.
  • The resolver guards access to window, allowing configuration resolution during server rendering. Data loading starts after the component mounts in the browser.

Requirements

  • installed NodeJS (v20 or higher)

Run locally

  1. Install dependencies npm install (once per setup)
  2. Start development server npm start

Run the configuration regression tests with npm test.

Publish components

  1. Apply changes
  2. Change version in package.json
  3. Build component library npm run build:lib

[!NOTE]
Remember to login before the next step (verify with npm whoami).

npm login to authenticate your npm account before publishing.

  1. Publish component library npm publish --access public (or use npm publish --access public --tag next for prerelease)

Deploy to GitHub Pages

  1. Deploy using gh-pages npm library: npm run deploy

Build WebApp

  1. Build web app using npm run build