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

@silverpoint/react

v0.6.0

Published

React adapter of silverpoint: translates core geometry into JSX, and nothing else.

Readme

@silverpoint/react

React components for silverpoint: charts drawn in the manner of a Renaissance silverpoint drawing, with a fine silver line on a prepared ground, tone built from hatching, and white heightening on the live value. The hand-drawn irregularity is only in the ornament. The data geometry is exact, and every chart has a precision mode that turns the inking off.

  • 60 charts, each importable on its own subpath so you only ship the charts you use.
  • React 18.2+ and 19. Client components ("use client") and server entry points for React Server Components.
  • Accessible: an accessible name, a hidden data table, keyboard navigation, and a prefers-contrast / forced-colors fallback to precision.

Installation

npm install @silverpoint/react @silverpoint/grounds @silverpoint/fonts

| Package | Why | |---|---| | @silverpoint/react | The components. Brings @silverpoint/core with it. | | @silverpoint/grounds | The stylesheet (styles.css) that colours the strokes. Required. | | @silverpoint/fonts | Optional. Self-hosted EB Garamond, the typeface the charts are designed for. |

Peer dependencies: react and react-dom ^18.2.0 || ^19.0.0. You need a bundler (Vite, Next.js, or anything else that resolves exports and CSS imports). No optimizeDeps entry and no extra configuration are needed.

Import the two stylesheets once, at the root of the app.

Quickstart (Vite)

npm create vite@latest my-charts -- --template react-ts
cd my-charts
npm install @silverpoint/react @silverpoint/grounds @silverpoint/fonts

Replace src/App.tsx with:

import '@silverpoint/fonts/fonts.css';
import '@silverpoint/grounds/styles.css';
import { LineChart } from '@silverpoint/react/line-chart';

const data = [
  { hour: '00', hits: 18 },
  { hour: '04', hits: 11 },
  { hour: '08', hits: 42 },
  { hour: '12', hits: 64 },
  { hour: '16', hits: 57 },
  { hour: '20', hits: 30 },
];

export default function App() {
  return (
    <div style={{ width: 480 }}>
      <LineChart data={data} xKey="hour" valueKey="hits" title="Hits per hour" />
    </div>
  );
}

Then run npm run dev. The chart takes the width of its container. height is the height of the drawing area and defaults to 160 px.

Examples

One ground for the whole app

SilverpointProvider sets the ground, the substrate, the mode and the locale for every chart below it. A prop on a chart overrides the provider.

import '@silverpoint/fonts/fonts.css';
import '@silverpoint/grounds/styles.css';
import { SilverpointProvider } from '@silverpoint/react';
import { BarChart } from '@silverpoint/react/bar-chart';
import { DonutChart } from '@silverpoint/react/donut-chart';

const sales = [
  { month: 'Jan', units: 120 },
  { month: 'Feb', units: 98 },
  { month: 'Mar', units: 143 },
];

const channels = [
  { channel: 'Web', share: 54 },
  { channel: 'Stores', share: 31 },
  { channel: 'Partners', share: 15 },
];

export function Dashboard() {
  return (
    <SilverpointProvider ground="silverpoint" substrate="green" locale="en-GB">
      <BarChart data={sales} xKey="month" valueKey="units" title="Units sold" unit="units" />
      <DonutChart data={channels} nameKey="channel" valueKey="share" title="Sales by channel" centerLabel="%" />
    </SilverpointProvider>
  );
}

Substrates: cream (the default), green, blue, ochre.

Precision mode

mode="precision" switches the inking off entirely and draws exact, even strokes. It suits print, dense dashboards, and readers who prefer it. The chart switches to it by itself when the system asks for more contrast (prefers-contrast: more or forced-colors: active). No prop can override that.

<LineChart data={data} xKey="hour" valueKey="hits" title="Hits per hour" mode="precision" />

Interaction and a custom readout

import { useState } from 'react';
import { LineChart } from '@silverpoint/react/line-chart';

export function Explorer({ data }: { data: { hour: string; hits: number }[] }) {
  const [active, setActive] = useState<string>('—');
  return (
    <>
      <LineChart
        data={data}
        xKey="hour"
        valueKey="hits"
        title="Hits per hour"
        onActiveChange={(item) => setActive(item ? `${item.datum.hour}: ${item.value}` : '—')}
        onSelect={(item) => console.log('selected', item.datum)}
        tooltip={(item) => <strong>{item.value} hits</strong>}
      />
      <p>Under the pointer: {active}</p>
    </>
  );
}

onActiveChange receives the item under the pointer or keyboard focus, and null when it leaves. onSelect fires on click, Enter or Space.

Imperative handle

import { useRef } from 'react';
import { LineChart, type ChartHandle } from '@silverpoint/react/line-chart';

export function Exportable({ data }: { data: { hour: string; hits: number }[] }) {
  const chart = useRef<ChartHandle>(null);
  const download = () => {
    const svg = chart.current?.toSVGString() ?? '';
    const url = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
    window.open(url);
  };
  return (
    <>
      <LineChart ref={chart} data={data} xKey="hour" valueKey="hits" title="Hits per hour" />
      <button onClick={download}>Export SVG</button>
    </>
  );
}

Next.js and React Server Components

The default subpaths are client components ("use client"). They work in the App Router and hydrate without a mismatch. For pure SVG with no client JavaScript, use the server entry point. It has no interaction, and id, width and height are required:

// app/page.tsx — a Server Component
import '@silverpoint/fonts/fonts.css';
import '@silverpoint/grounds/styles.css';
import { LineChart } from '@silverpoint/react/server/line-chart';

const data = [
  { hour: '00', hits: 18 },
  { hour: '12', hits: 64 },
  { hour: '20', hits: 30 },
];

export default function Page() {
  return <LineChart id="hits" width={480} height={160} data={data} xKey="hour" valueKey="hits" title="Hits per hour" />;
}

Props every chart shares

| Prop | Default | | |---|---|---| | data | demo dataset | The rows to draw. | | ground / substrate / mode | 'silverpoint' / 'cream' / 'ink' | Style; mode: 'precision' turns off inking. | | seed, id | derived, stable | The hand drawing is deterministic: same props, same strokes. | | height, width | 160, container width | Size of the drawing area in px. | | chrome | 'card' | 'bare' draws only the plot. | | title, badge, value, unit, footerLeft, footerRight | — | The card's text. | | label, description, dataTable | from title, —, 'hidden' | Accessibility. | | locale, numberFormat | environment | Number formatting. | | hatchFill | 'tile' | 'per-shape' gives richer hatching at a much greater weight. |

The 60 charts

Every chart is available as @silverpoint/react/<kebab-case-name> (and from the barrel @silverpoint/react):

LineChart, StepChart, SparklineRows, KpiCard, BarChart, StackedBarChart, ComposedChart, WaterfallChart, FunnelChart, BulletChart, PyramidChart, CandlestickChart, AreaChart, RangeBandChart, StreamChart, DonutChart, RadarChart, PolarBarChart, RadialArcGroup, RadialRings, GaugeArc, MeterChart, ScatterChart, BubbleChart, HeatmapChart, TreemapChart, SankeyChart, ActivityGrid, CoxcombChart, WindRose, VolvelleChart, ChordRing, OrbitChart.

The second catalog, for distributions, comparisons, ranks and uncertainty (since 0.6.0):

HistogramChart, EcdfChart, BoxPlotChart, ViolinChart, RidgelineChart, BeeswarmChart, LollipopChart, DumbbellChart, SlopeChart, BumpChart, ErrorBarChart, IntervalChart, DivergingBarChart, ConnectedScatterChart.

Hierarchies, parts of a whole, many dimensions and polar charts (since 0.6.0):

WaffleChart, MarimekkoChart, SquarifiedTreemap, SunburstChart, TreeChart, ParallelCoordinatesChart, PolarLineChart, PolarScatterChart.

Fields and networks (since 0.6.0):

DensityBinChart, ContourChart, DelaunayChart, VectorFieldChart, NetworkChart.

RidgelineChart needs groupKey, DivergingBarChart needs levels and ParallelCoordinatesChart needs dimensions, even with the demo dataset, which ignores them.

SquarifiedTreemap and SunburstChart drill down under your control: pass rootId and update it from onRootChange, which a click, Enter or Space on a node emits with its id (its centre or frame emits the parent's, null for the top). The chart keeps no root of its own, so it renders the same on the server.

NetworkChart lays out its nodes by force, the same on the server and in every browser for a given seed; give every node in nodes an x and a y and it draws them there instead.

Each chart's own props (xKey, valueKey, nameKey…) are typed and documented in its *Props type. The repository holds the API specification and the documentation site with the gallery.

Related packages

@silverpoint/vue · @silverpoint/angular · @silverpoint/grounds · @silverpoint/fonts · @silverpoint/core

MIT.