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

@pollium/vyva-react

v0.3.0

Published

React viewer and editors for Vyva documents and decks.

Readme

@pollium/vyva-react

The React viewer and editors for Vyva content: a Viewer, a Word-style DocumentEditor, a Canva-style DeckEditor and a full-screen PresentMode. It needs React 19.

npm install @pollium/vyva-react @pollium/vyva-core react react-dom

Setup

import '@pollium/vyva-react/styles.css';
import '@pollium/vyva-react/fonts';
  • styles.css is already built. Every class starts with vy:, so it never collides with the host's styles. Colors come from --vy-color-* variables, which the host can override. Dark mode turns on with .dark or data-theme="dark" on :root.
  • No reset is needed. Vyva resets the browser's default styles inside its own UI and leaves the rest of the page alone. Its UI takes the font of the page around it.
  • HeroUI hosts also import @pollium/vyva-react/heroui.css, which points those variables at HeroUI's own colors.
  • fonts loads the eight fonts documents and decks can use. Leave it out if the host already serves them under the same family names.

A session

The editors edit a session, and the host decides where the content is stored.

import { SaveConflict, useVyvaSession } from '@pollium/vyva-react/use-vyva-session';

const session = useVyvaSession({
    initial: { content: material.content, revision: material.revision },
    save: async (change, baseRevision) => {
        const response = await fetch(`/materials/${id}`, { method: 'PATCH', body: JSON.stringify({ ...change, baseRevision }) });
        if(response.status === 409) throw new SaveConflict();
        if(!response.ok) throw new Error('The material could not be saved');
        return response.json();
    },
    load: async () => (await fetch(`/materials/${id}`)).json()
});
  • Saving. The session saves a moment after the last edit, and again before the page closes.
  • save sends the change and the revision it was made on, and resolves to the stored content and its new revision.
  • Conflicts. Throw SaveConflict when someone else saved first. The session stops saving until the user reloads or keeps their own version.
  • Unrecoverable failures. Throw SaveBlocked when retrying cannot help, such as when the user lost access.
  • SaveStatus shows the save state and offers those choices.

The components

import DocumentEditor from '@pollium/vyva-react/DocumentEditor';
import DeckEditor from '@pollium/vyva-react/DeckEditor';
import Viewer from '@pollium/vyva-react/Viewer';
import SaveStatus from '@pollium/vyva-react/SaveStatus';

<DocumentEditor session={session} readOnly={false} fileUrl={(fileId) => `/files/${fileId}`} />
<DeckEditor session={session} readOnly={false} fileUrl={fileUrl} imagePicker={MyImagePicker} />
<Viewer content={content} fileUrl={fileUrl} label='Unit 1' />
<SaveStatus session={session} />

| Prop | Editor | What it is | |---|---|---| | session | both | The session from useVyvaSession | | readOnly | both | Shows the content without letting anyone change it | | fileUrl | both | Turns a file id into the URL of the image. null leaves the image out | | imagePicker | both | A component the editor opens to choose an image. It gets isOpen, onOpenChange and onPick({ fileId, url, alt, credit }). Without it there is no image button | | panel | both | A tab the host adds beside the properties, such as an AI assistant: { label, icon, isBusy, actions?, content } | | onSelectionAction | document | Called with improve, shorten, simplify or ask and the selected text | | onImprove | deck | Called with the selected element and its slide number | | codeEditor | deck | The editor for code elements. A plain text area by default | | ref | both | showPanel() opens the host's tab. The deck editor also has present() |

PDF pages

A deck imported from a PDF has a page of that PDF behind each slide. Vyva does not read PDFs itself: the host draws each page through PdfPageContext, with the renderer of its choice, such as pdf.js.

import { PdfPageContext, type PdfPageProps } from '@pollium/vyva-react/contracts/pdf-page';

const renderPdfPage = (props: PdfPageProps) => <MyPdfPage {...props} />;

<PdfPageContext.Provider value={renderPdfPage}>
    <DeckEditor ... />
</PdfPageContext.Provider>

| Prop | What it is | |---|---| | url | What fileUrl returned for the PDF | | page | The page to draw, from 1 | | width, height | The box to fill, in slide units. A page of another shape fits inside it | | scale | How many screen pixels a slide unit takes, so the page can be drawn sharp | | isSelectable | Whether the text of the page should be selectable. Only reading views ask for it |

Without a provider the page is left blank. Canvas takes isSelectable for the same reason.

PresentMode shows a deck full screen and works with the keyboard and by touch. Canvas shows one page from @pollium/vyva-react/markup (slideMarkup or documentMarkup), scaled to the width it is given, which is what thumbnails need.

Code editing with Monaco

@pollium/vyva-react/MonacoCodeEditor is a ready code editor for decks. It needs @monaco-editor/react:

import MonacoCodeEditor from '@pollium/vyva-react/MonacoCodeEditor';

<DeckEditor codeEditor={MonacoCodeEditor} ... />

@monaco-editor/react loads Monaco from a CDN. To serve it yourself, install monaco-editor and call loader.config({ monaco }) from @monaco-editor/react before the editor first renders.

Language

The labels come in English and Spanish, and a host can bring its own. Numbers follow the locale of React Aria's I18nProvider.

import { MessagesContext } from '@pollium/vyva-react/messages/context';
import es from '@pollium/vyva-react/messages/es';
import { I18nProvider } from 'react-aria-components';

<I18nProvider locale='es'>
    <MessagesContext.Provider value={es}>
        <DeckEditor ... />
    </MessagesContext.Provider>
</I18nProvider>

A new language is an object typed as Messages from @pollium/vyva-react/messages/en, so TypeScript lists every label it still needs.