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

react-patternify

v0.2.0

Published

Animated canvas background patterns for React

Downloads

992

Readme

react-patternify

License: MIT npm version

Animated canvas background patterns for React. Drop a component into your layout and get a self-contained, GPU-friendly animated background, no dependencies beyond React, no DOM overhead, fully customizable via props.

Live demo

Install

npm install react-patternify

Next.js App Router: the components are already marked "use client" in the bundle — no wrapper needed.

Components

TetrisSkyline

An animated Tetris-inspired cityscape. Tetromino pieces spawn at the top and fall onto a procedurally generated skyline terrain. When a column grows too tall the blocks fade out and the terrain resets, keeping the animation running indefinitely.

Full-viewport background (default)

The canvas is fixed, full-viewport, placed behind your content (z-index: -1, pointer-events: none, aria-hidden) — a drop-in background with no layout impact.

import { TetrisSkyline } from 'react-patternify'

export default function App() {
  return (
    <>
      <TetrisSkyline />
      {/* your content */}
    </>
  )
}

Contained mode

Set contained to render the canvas inside a specific element instead of the full viewport. The parent must have position: relative (or any positioning context) and explicit dimensions.

import { TetrisSkyline } from 'react-patternify'

export default function Hero() {
  return (
    <section style={{ position: 'relative', height: '400px', overflow: 'hidden' }}>
      <TetrisSkyline contained />
      <h1 style={{ position: 'relative' }}>Hello</h1>
    </section>
  )
}

The canvas uses position: absolute; inset: 0 and a ResizeObserver on the parent, so it adapts automatically when the container resizes.

Props

| Prop | Type | Default | Description | | ----------------------- | ---------- | ----------------------------------- | ----------------------------------------------------------------------------------- | | contained | boolean | false | Fill the nearest positioned parent instead of the full viewport | | palette | string[] | ['#ff2d6d', '#a855f7', '#60a5fa'] | Block colors, cycled across pieces | | bg | string | '#0b1220' | Canvas background fill | | gridLine | string | 'transparent' | Cell border color | | minCell | number | 16 | Minimum auto-calculated cell size (px) | | maxCell | number | 24 | Maximum auto-calculated cell size (px) | | preferredCell | number | 20 | Target cell size; clamped to min/max to minimize edge gaps | | cellGap | number | 3 | Gap between cells (px) | | pieceDropMs | number | 90 | Time per one-cell drop (ms) — lower is faster | | spawnEveryMs | number | 520 | Interval between new piece spawns (ms) | | maxActivePieces | number | 7 | Max pieces falling at once | | initialTerrainPercent | number | 0.2 | Initial terrain height as a fraction of total rows (0 = no terrain) between 0 and 1 | | terrainRoughness | number | 2 | Skyline jaggedness — higher values create more variation | | topChipsChance | number | 0.05 | Per-cell probability of a surface notch on the terrain | | columnClearAnimMs | number | 260 | Duration of the column fade-out animation (ms) |


Tetris

A classic Tetris animation. Tetromino pieces spawn at the top and fall onto an empty grid. When a row is completely filled it fades out and the rows above shift down. When pieces stack to the top the board resets, keeping the animation running indefinitely.

Full-viewport background (default)

import { Tetris } from 'react-patternify'

export default function App() {
  return (
    <>
      <Tetris />
      {/* your content */}
    </>
  )
}

Contained mode

import { Tetris } from 'react-patternify'

export default function Hero() {
  return (
    <section style={{ position: 'relative', height: '400px', overflow: 'hidden' }}>
      <Tetris contained />
      <h1 style={{ position: 'relative' }}>Hello</h1>
    </section>
  )
}

Props

| Prop | Type | Default | Description | | ----------------- | ---------- | ----------------------------------- | --------------------------------------------------------------- | | contained | boolean | false | Fill the nearest positioned parent instead of the full viewport | | palette | string[] | ['#ff2d6d', '#a855f7', '#60a5fa'] | Block colors, cycled across pieces | | bg | string | '#0b1220' | Canvas background fill | | gridLine | string | 'transparent' | Cell border color | | minCell | number | 16 | Minimum auto-calculated cell size (px) | | maxCell | number | 24 | Maximum auto-calculated cell size (px) | | preferredCell | number | 20 | Target cell size; clamped to min/max to minimize edge gaps | | cellGap | number | 3 | Gap between cells (px) | | pieceDropMs | number | 90 | Time per one-cell drop (ms) — lower is faster | | spawnEveryMs | number | 520 | Interval between new piece spawns (ms) | | maxActivePieces | number | 7 | Max pieces falling at once | | rowClearAnimMs | number | 260 | Duration of the row fade-out animation (ms) | | rowShiftAnimMs | number | 180 | Duration of the rows-above sliding down after a clear (ms) |