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

@rific/heatmap

v0.1.3

Published

A GitHub-style activity heatmap for React Native with SVG rendering and customizable cell modes

Readme

@rific/heatmap

GitHub-style activity heatmap for React Native. SVG cells with multiple visualization modes, touch tooltips, animations, and a flexible color scale API.

Installation

npm install @rific/heatmap

Peer dependencies

npm install react-native-svg

Follow the react-native-svg installation guide to link the native module.

Usage

import Heatmap from '@rific/heatmap'

const data = [
  { date: '2026-01-15', value: 3 },
  { date: '2026-03-08', value: 14 },
  { date: '2026-05-01', value: 7 },
]

export default function App() {
  return (
    <Heatmap.Calendar
      data={data}
      onDayPress={(point, date) => console.log(date, point)}
    />
  )
}

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | data | DataPoint[] | required | Array of { date, value } objects. date is YYYY-MM-DD. | | startDate | Date | 1 year ago | First day shown on the grid. | | endDate | Date | Today | Last day shown on the grid. | | cellMode | 'solid' \| 'gradient' \| 'density' \| 'stacked' \| 'dots' \| 'priority' | 'solid' | Visual style of each cell. | | colorScale | Partial<ColorScale> | GitHub greens | Thresholds and colors used to shade cells. | | color | string | — | Single accent color. Overrides the default color scale. | | colorScheme | 'light' \| 'dark' | — | Switch between built-in light and dark palettes. | | autoScale | boolean | true | Scale cell intensity relative to the max value in data. | | theme | Partial<HeatmapTheme> | See below | Size, spacing, and color overrides. | | showMonthLabels | boolean | true | Show month name labels above the grid. | | showDayLabels | boolean | true | Show Mon / Wed / Fri labels on the left. | | animated | boolean | false | Enable all animations (load ripple, today pulse, press spring). | | scrollToToday | boolean | true | Scroll to the current week on mount. | | scrollEnabled | boolean | true | Enable or disable horizontal scrolling. | | onDayPress | (point: DataPoint \| null, date: string) => void | — | Called when a cell is tapped. | | onEndReached | () => void | — | Called when the user scrolls near the right edge. Use for infinite scroll. | | onEndReachedThreshold | number | 0.1 | Fraction of total width from the right edge that triggers onEndReached. | | renderTooltip | (data: TooltipData) => ReactNode | — | Replace the default tooltip with a custom component. | | renderCell | (data: DataPoint \| null, date: string) => ReactNode | — | Replace the default cell with a custom component. | | tooltipLabel | string | 'event' | Unit label in the default tooltip. Pluralized automatically (e.g. 'workout''3 workouts'). | | tooltipEmptyLabel | string | 'No events' | Label shown in the tooltip for days with no data. |

Cell modes

solid (default)

Each cell is a flat colored rectangle, identical to the GitHub contribution graph.

gradient

A radial gradient blooms from the center of each cell — dim at the center, full color at the edges.

density

A circle grows inside a neutral background rectangle. A small dot means low activity; a filled square means high activity.

stacked

Horizontal slices represent proportional segments from the segments array on each DataPoint.

dots

Each segment in the segments array is drawn as a dot sized by its relative weight.

priority

The dominant segment's color fills the cell at an opacity proportional to its value.

<Heatmap.Calendar data={data} cellMode='density' />

Animations

Pass animated to enable all animations. No extra dependencies — uses the built-in Animated API.

<Heatmap.Calendar data={data} animated />
  • Load ripple — cells fade and scale in on mount, radiating outward from today's column.
  • Today pulse — the current day cell breathes with a looping scale animation.
  • Press spring — cells scale down on press and spring back on release.

The current day always receives a border indicator regardless of the animated prop.

Infinite scroll

<Heatmap.Calendar
  data={data}
  startDate={startDate}
  endDate={endDate}
  onEndReached={() => setEndDate(extendedDate)}
  onEndReachedThreshold={0.15}
/>

When the user scrolls within onEndReachedThreshold of the right edge, onEndReached fires. Update endDate to append more weeks.

Segments

For multi-category data, pass a segments array on each DataPoint. Works with stacked, dots, and priority cell modes.

const data = [
  {
    date: '2026-05-01',
    value: 10,
    segments: [
      { color: '#40c463', value: 6 },
      { color: '#216e39', value: 4 },
    ],
  },
]

<Heatmap.Calendar data={data} cellMode='stacked' />

Color scale

<Heatmap.Calendar
  data={data}
  colorScale={{
    thresholds: [1, 4, 8, 16],   // 4 thresholds → 5 colors
    colors: ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39'],
    emptyColor: '#ebedf0',
  }}
/>

Values below the first threshold use colors[0]. Values at or above threshold n use colors[n + 1]. Values above the last threshold use the last color.

Theme

<Heatmap.Calendar
  data={data}
  theme={{
    cellSize: 14,
    cellRadius: 2,
    gutterSize: 2,
    monthLabelColor: '#57606a',
    dayLabelColor: '#57606a',
    backgroundColor: 'transparent',
    tooltipBackgroundColor: '#1b1f23',
    tooltipTextColor: '#ffffff',
    todayColor: '#4183c4',
    todayBorderColor: '#4183c4',
  }}
/>

Custom tooltip

<Heatmap.Calendar
  data={data}
  renderTooltip={({ date, value }) => (
    <View style={styles.tooltip}>
      <Text>{date} — {value} events</Text>
    </View>
  )}
/>

Custom cell

<Heatmap.Calendar
  data={data}
  renderCell={(point, date) => (
    <View style={{ width: 14, height: 14, backgroundColor: point ? 'tomato' : '#eee', borderRadius: 2 }} />
  )}
/>

TypeScript

All types are exported:

import Heatmap, { type CellMode, type ColorScale, type DataPoint, type HeatmapProps, type HeatmapTheme, type TooltipData } from '@rific/heatmap'

Development

npm run typecheck   # TypeScript
npm run lint        # ESLint
npm run fix         # ESLint --fix
npm test            # Jest
npm run test:watch  # Jest watch mode

License

MIT © Jay Deaton