bezda-team/rhp

React Html Plots: A react component library for building plots with HTML and CSS

JavaScript

5

154 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

RHP 2.0: A charting library for building dynamic, interactive, infographic-style charts and plots! (r/webdev)

**rhp** (Reactive Html Plots) 2.0 is the successor of rhp 1.0 which was a react charting library I built 3 years ago. rhp 2.0 is now an open-source SolidJS library of reactive components. It does not use Canvas or SVG for building the entire chart but HTML elements, CSS, and Javascript. This makes…

1

Oct 4, 2026

README

rhp: reactive html plots

rhp builds charts out of HTML elements placed by CSS, with SolidJS, instead of drawing them into an SVG or a canvas. You describe one slat, the template for one row of data, from a few blocks (Bar, Dot, Tick, Label, Cell, Place, Area and Line), and rhp draws a slat for every row and keeps each one in its place. When a value changes, only what reads it runs again, and a block writes only the CSS variables that changed.

Guides, reference and a gallery of live charts: https://rhp.vercel.app

Install

npm install @bezda/rhp

Solid is its only peer dependency, and there is no stylesheet to import: rhp adds its CSS when the first chart appears. A Solid app's build (Vite, SolidStart, Astro) compiles rhp's source with the app. Anywhere else the package picks a ready build: one for browsers, and one for Node, Deno and workers that draws charts on a server.

  • No build step: import @bezda/rhp/standalone from a CDN, one module with Solid included (36 kB gzipped); Install shows a whole page.
  • React: @bezda/rhp-react, in react/, turns an rhp chart into a React component.

Example

A bar chart, as a Solid app's App.jsx (Install starts a new app):

import { Chart, Plot, Bar, Label, slat } from "@bezda/rhp";

const Fruit = slat({ thickness: 32, room: { start: 80, end: 40 } }, (d) => (
  <div>
    <Label edge="start">{d.name}</Label>
    <Bar to={d.sold} />
    <Label at={d.sold}>{d.sold}</Label>
  </div>
));

export default function App() {
  return (
    <Chart scale={[0, 30]}>
      <Plot name={["Apples", "Bananas", "Cherries"]} sold={[12, 18, 7]}>{Fruit}</Plot>
    </Chart>
  );
}

Each prop of the Plot is a column of data, and each slat reads its row's values as d.name and d.sold. Your first chart builds this up step by step.

Good to know

  • Charts are plain DOM with no shadow root: querySelector, Testing Library and your page's event listeners all work.
  • A slat's CSS reaches only its own slats, and the page's CSS can't change a chart's layout.
  • slat(settings, fn) returns a new function, the slat type, and leaves fn as it was, so one function can make several slat types with different settings. Give the Plot what slat() returns: fn itself carries no settings.

What's in the package

File
dist/index.jsthe browser build, one ES module, with Solid left to the app
dist/server.jsthe same for a server
dist/source/the source, for a Solid app's own build (the solid export condition)
dist/standalone.jsrhp and Solid in one module, for pages with no build step
dist/rhp.cssrhp's stylesheet, for a page that links it once itself (linkedCss())
dist/posters.cssthe gallery's poster looks, for <Poster> (optional)

Development

You need Node 22 or later.

npm install
npx playwright install    # the browsers the tests run in
npm run build             # dist/
npm test                  # builds the test pages and checks them in Chromium
npm run buildwrites dist/
npm testchecks the types with tsc, then the test pages in Chromium with Playwright. BROWSER=webkit or BROWSER=firefox runs them in that engine; CI runs all three on every pull request and on master.
npm run galleryexamples/gallery/out/slat-gallery.html, a page of plots the tests also check
bench/rhp against eleven other chart libraries: see bench/README.md

The code:

src/plot.jsxChart, Plot, Scale, Axis and Theme
src/blocks.jsxthe blocks
src/style.jshow CSS gets into the page: slat(), restyle(), scoping a slat's CSS, and the CSS a server writes
src/rhp.cssthe core CSS; gutters.css and cross.css are added when a chart first needs them
src/frame.js, src/animate.jswhen changes are written, and the JS version's clock
src/data.js, src/shape.jsthe data helpers and shape()
src/poster.jsx, src/posters.cssPoster and its looks
test/run.mjsevery check, including an app drawn on a server and taken over in the browser, and a Vite app built from rhp's source

Releasing

  1. Set the new version in package.json and react/package.json (and the @bezda/rhp version that react/ depends on).
  2. Run npm test, BROWSER=webkit npm test and BROWSER=firefox npm test.
  3. npm publish, then npm publish in react/ (each builds first).
  4. In rhp-documentation, npm run sync-rhp takes the new build for the website.

History

Version 2 is a rewrite of v1 ("react html plots"), a React library in three packages; v1's code is on the v1 branch.

License

MIT, see LICENSE. Some files came from elsewhere and keep their own licenses: see CREDITS.md.

bezda-team/rhp

React Html Plots: A react component library for building plots with HTML and CSS

JavaScript

5

154 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

RHP 2.0: A charting library for building dynamic, interactive, infographic-style charts and plots! (r/webdev)

**rhp** (Reactive Html Plots) 2.0 is the successor of rhp 1.0 which was a react charting library I built 3 years ago. rhp 2.0 is now an open-source SolidJS library of reactive components. It does not use Canvas or SVG for building the entire chart but HTML elements, CSS, and Javascript. This makes…

1

Oct 4, 2026

README

rhp: reactive html plots

rhp builds charts out of HTML elements placed by CSS, with SolidJS, instead of drawing them into an SVG or a canvas. You describe one slat, the template for one row of data, from a few blocks (Bar, Dot, Tick, Label, Cell, Place, Area and Line), and rhp draws a slat for every row and keeps each one in its place. When a value changes, only what reads it runs again, and a block writes only the CSS variables that changed.

Guides, reference and a gallery of live charts: https://rhp.vercel.app

Install

npm install @bezda/rhp

Solid is its only peer dependency, and there is no stylesheet to import: rhp adds its CSS when the first chart appears. A Solid app's build (Vite, SolidStart, Astro) compiles rhp's source with the app. Anywhere else the package picks a ready build: one for browsers, and one for Node, Deno and workers that draws charts on a server.

  • No build step: import @bezda/rhp/standalone from a CDN, one module with Solid included (36 kB gzipped); Install shows a whole page.
  • React: @bezda/rhp-react, in react/, turns an rhp chart into a React component.

Example

A bar chart, as a Solid app's App.jsx (Install starts a new app):

import { Chart, Plot, Bar, Label, slat } from "@bezda/rhp";

const Fruit = slat({ thickness: 32, room: { start: 80, end: 40 } }, (d) => (
  <div>
    <Label edge="start">{d.name}</Label>
    <Bar to={d.sold} />
    <Label at={d.sold}>{d.sold}</Label>
  </div>
));

export default function App() {
  return (
    <Chart scale={[0, 30]}>
      <Plot name={["Apples", "Bananas", "Cherries"]} sold={[12, 18, 7]}>{Fruit}</Plot>
    </Chart>
  );
}

Each prop of the Plot is a column of data, and each slat reads its row's values as d.name and d.sold. Your first chart builds this up step by step.

Good to know

  • Charts are plain DOM with no shadow root: querySelector, Testing Library and your page's event listeners all work.
  • A slat's CSS reaches only its own slats, and the page's CSS can't change a chart's layout.
  • slat(settings, fn) returns a new function, the slat type, and leaves fn as it was, so one function can make several slat types with different settings. Give the Plot what slat() returns: fn itself carries no settings.

What's in the package

File
dist/index.jsthe browser build, one ES module, with Solid left to the app
dist/server.jsthe same for a server
dist/source/the source, for a Solid app's own build (the solid export condition)
dist/standalone.jsrhp and Solid in one module, for pages with no build step
dist/rhp.cssrhp's stylesheet, for a page that links it once itself (linkedCss())
dist/posters.cssthe gallery's poster looks, for <Poster> (optional)

Development

You need Node 22 or later.

npm install
npx playwright install    # the browsers the tests run in
npm run build             # dist/
npm test                  # builds the test pages and checks them in Chromium
npm run buildwrites dist/
npm testchecks the types with tsc, then the test pages in Chromium with Playwright. BROWSER=webkit or BROWSER=firefox runs them in that engine; CI runs all three on every pull request and on master.
npm run galleryexamples/gallery/out/slat-gallery.html, a page of plots the tests also check
bench/rhp against eleven other chart libraries: see bench/README.md

The code:

src/plot.jsxChart, Plot, Scale, Axis and Theme
src/blocks.jsxthe blocks
src/style.jshow CSS gets into the page: slat(), restyle(), scoping a slat's CSS, and the CSS a server writes
src/rhp.cssthe core CSS; gutters.css and cross.css are added when a chart first needs them
src/frame.js, src/animate.jswhen changes are written, and the JS version's clock
src/data.js, src/shape.jsthe data helpers and shape()
src/poster.jsx, src/posters.cssPoster and its looks
test/run.mjsevery check, including an app drawn on a server and taken over in the browser, and a Vite app built from rhp's source

Releasing

  1. Set the new version in package.json and react/package.json (and the @bezda/rhp version that react/ depends on).
  2. Run npm test, BROWSER=webkit npm test and BROWSER=firefox npm test.
  3. npm publish, then npm publish in react/ (each builds first).
  4. In rhp-documentation, npm run sync-rhp takes the new build for the website.

History

Version 2 is a rewrite of v1 ("react html plots"), a React library in three packages; v1's code is on the v1 branch.

License

MIT, see LICENSE. Some files came from elsewhere and keep their own licenses: see CREDITS.md.

Languages

JavaScript

85.1%

CSS

13.3%

TypeScript

1.5%