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

@candiesocean/rnconfetti

v0.2.0

Published

Confetti for React Native & Expo — physics-simulated polar spawn and gravity trajectories, animated with react-native-ease. Gold, purple and indigo presets.

Readme

@candiesocean/rnconfetti

Confetti for React Native & Expo. Physics-simulated — each piece gets a polar spawn angle, a velocity, and a gravity + air-resistance trajectory solved ahead of time, then animated through rise → fall → fade with react-native-ease.

Sprites are real multicolor glyphs (party popper, wrapped candy, lollipop, star, heart, gem, jelly bean, rect, dot) rendered from a native font via react-native-nano-icons — not <View> rectangles.

Three color presets — gold (default), purple, indigo — plus a raw colors array if you want your own ramp. Presets are colors only; the physics never changes.

Install

npm install @candiesocean/rnconfetti react-native-ease react-native-nano-icons

Setup

The sprite font is generated at prebuild from the SVGs shipped inside this package, then linked into your native app. Add the react-native-nano-icons config plugin to app.json, pointing at this package's sprites/ folder:

{
  "expo": {
    "plugins": [
      [
        "react-native-nano-icons",
        {
          "iconSets": [
            {
              "inputDir": "./node_modules/@candiesocean/rnconfetti/sprites",
              "fontFamily": "confetti-gold"
            }
          ]
        }
      ]
    ]
  }
}

fontFamily must be confetti-gold — it's the family the bundled glyphmap resolves against. Then:

npx expo prebuild
npx expo run:ios   # or run:android

A native rebuild is required because the font is linked natively. This will not run in Expo Go. If you already have other nano-icons sets, add this one alongside them in the same iconSets array.

Codepoints are assigned deterministically from the sorted SVG set starting at 0xE900, so the TTF the plugin generates matches the glyphmap shipped here.

Setup is one-time and preset-independent. The font carries shapes, not colors — layer colors are supplied at runtime — so fontFamily stays confetti-gold whichever preset you use, and switching presets needs no prebuild and no native rebuild.

Usage

Two pieces: a hook that owns the particle state, and an overlay that draws it.

Cannons — dual bottom corners firing inward

import { useEffect } from 'react';
import { useWindowDimensions, View } from 'react-native';
import { ConfettiOverlay, useConfetti } from '@candiesocean/rnconfetti';

export default function BookingConfirmed() {
  const { width, height } = useWindowDimensions();
  const { pieces, cannon, removePiece } = useConfetti();

  useEffect(() => {
    cannon({ stageWidth: width, stageHeight: height });
  }, [cannon, width, height]);

  return (
    <View style={{ flex: 1 }}>
      {/* your screen */}
      <ConfettiOverlay pieces={pieces} onPieceDone={removePiece} />
    </View>
  );
}

Burst — radiating from one point

const { pieces, burst, removePiece } = useConfetti();

burst({ originX: width / 2, originY: height / 3 });

ConfettiOverlay is position: absolute, fills its parent, and is pointerEvents="box-none", so it never blocks taps. Render it last inside a positioned parent.

Presets

<ConfettiOverlay pieces={pieces} onPieceDone={removePiece} preset="indigo" />

gold (default), purple, indigo — the names are in CONFETTI_PRESETS, the ramps in CONFETTI_PRESET_COLORS. For a custom ramp, pass colors instead; it overrides preset:

<ConfettiOverlay pieces={pieces} onPieceDone={removePiece} colors={myRamp} />

A ramp is up to six colors ordered deepest → highlight, sized to the widest sprite (party-popper, 6 layers). Sprites with fewer layers use the leading entries, so order is load-bearing — a light color in slot 1 makes shadows read as highlights.

API

useConfetti()

| Returns | Type | Notes | | ------------- | ----------------------------------- | -------------------------------------------- | | pieces | ConfettiPieceSpec[] | Live particles. Pass to ConfettiOverlay. | | cannon | (opts: ConfettiCannonAt) => void | Dual bottom-corner cannons. | | burst | (opts: ConfettiBurstAt) => void | Single point burst. | | removePiece | (id: string) => void | Pass as onPieceDone; retires a dead piece. | | clear | () => void | Drop every live particle immediately. |

type ConfettiCannonAt = { stageWidth: number; stageHeight: number; count?: number };
type ConfettiBurstAt = { originX: number; originY: number; count?: number };

count defaults to 72 (DEFAULT_PARTICLE_COUNT). Concurrent particles are capped at 240 — spawning past that drops the oldest, so repeated firing can't grow unbounded.

<ConfettiOverlay />

| Prop | Type | Notes | | -------------- | --------------------------- | ---------------------------------------- | | pieces | ConfettiPieceSpec[] | | | onPieceDone | (id: string) => void | | | preset | ConfettiPreset | 'gold' (default) · 'purple' · 'indigo' | | colors | readonly string[] | Raw ramp, deepest → highlight. Wins over preset. |

Also exported

ConfettiParticle, ConfettiIcon, CONFETTI_FONT_FAMILY, CONFETTI_PRESETS, CONFETTI_PRESET_COLORS, CONFETTI_GOLD_COLORS, CONFETTI_PURPLE_COLORS, CONFETTI_INDIGO_COLORS, CONFETTI_SPRITES, CONFETTI_SPRITE_SIZES, createBurstSpecs, createCannonSpecs, DEFAULT_PARTICLE_COUNT — plus the ConfettiPreset type, for driving the simulation yourself.

Peer dependencies

react · react-native · expo · react-native-ease · react-native-nano-icons

License

MIT © candiesocean