Every app eventually wants to throw a party. A purchase clears, an onboarding flow finishes, a user hits a streak, and suddenly you need confetti to rain down and make the moment feel earned. The trouble is that confetti has historically been expensive: most older libraries mount one animated view per piece, and once you ask for a few hundred pieces the frame rate falls off a cliff.
React Native Fast Confetti takes a different route. Instead of one view per piece, it draws all of your confetti in a single Skia draw call using Skia's Atlas API, and it runs a real physics simulation on the UI thread via Reanimated worklets. The result is hundreds of pieces tumbling, drifting, and flipping at 60fps without ever crossing the JS bridge per frame. The react-native-fast-confetti package is the fastest way to make a celebration feel genuinely alive.
Why It Feels So Smooth
The headline feature is the rendering strategy. Skia's drawAtlas lets the library batch every confetti sprite into one GPU draw call, so a screen full of 500 pieces costs roughly what a handful would in a per-view library. That single-call approach is what unlocks the dense, busy celebrations that older libraries simply choke on.
The second pillar, new in the 2.0 rewrite, is the physics engine. Earlier versions animated pieces along easing curves, which meant motion was smooth but a little mechanical. Version 2 drives every flake with a real simulation: gravity, drag (air resistance), tumble dynamics, drift, wobble, depth-based perspective scaling, and flip behavior. Fall duration is no longer a number you set; it emerges naturally from the physics. The payoff is motion that looks varied and organic rather than scripted.
On top of that, the v2 API is composable. Flake sizes, textures, colors, and launch origins are all declared as child components, which makes it trivial to mix several shapes and sizes in one burst or to aim multiple cannons independently. And because everything is Skia-based, you can swap the default rectangular flakes for your own images or SVGs to make money rain or snow fall.
Getting It Into Your Project
Install the package with your favorite manager:
npm install react-native-fast-confetti
yarn add react-native-fast-confetti
Version 2 sits on top of a modern native stack, so you need a few peer dependencies installed first. The library expects @shopify/react-native-skia, react-native-reanimated (version 4), and react-native-worklets, alongside react and react-native:
yarn add @shopify/react-native-skia react-native-reanimated react-native-worklets
A quick compatibility note worth internalizing: v2 is tied to the Reanimated 4, Worklets, Skia 2.x, and React 19 generation, which in practice means React Native 0.79 or newer. If your project is still on an older React Native or React 18, stay on the v1 line instead. Because the stack includes Skia and Reanimated, this is a dev-build library rather than something you can drop into Expo Go.
Making It Rain
The simplest celebration is confetti falling straight down from the top of the screen. You declare a Confetti component and give it one or more Confetti.Flake children to describe what the pieces look like. Each flake group can specify a size (which sets both width and height), explicit width and height, and a corner radius. Mixing several flake groups gives you natural-looking variety:
import { Confetti } from 'react-native-fast-confetti';
export function PurchaseSuccess() {
return (
<Confetti autoplay>
<Confetti.Flake size={12} radius={6} />
<Confetti.Flake width={8} height={14} />
<Confetti.Flake width={8} height={14} radius={6.5} />
<Confetti.Flake width={8} height={14} radius={4} />
</Confetti>
);
}
By default the component plays the moment it mounts and drops 200 pieces. You can tune the count, the gravity, and the palette with colors, and you can hook into the lifecycle with onAnimationStart and onAnimationEnd callbacks. Note that sizing for the container now lives on containerStyle rather than separate width and height props.
If you want a celebration that never stops, reach for ContinuousConfetti. It produces a seamless, infinite stream from the top, which is perfect for a festive seasonal screen or a background flourish:
import { ContinuousConfetti } from 'react-native-fast-confetti';
export function FestiveBackdrop() {
return (
<ContinuousConfetti autoplay>
<ContinuousConfetti.Flake size={12} radius={6} />
</ContinuousConfetti>
);
}
Because it is always infinite, ContinuousConfetti deliberately drops the infinite, onAnimationEnd, and fadeOutOnEnd props that the standard component offers.
Bursting From a Point
A gentle rain is great for ambient celebration, but sometimes you want a sharp "tap and pop" moment, like confetti exploding out of a button. That is what PIConfetti (point-implosion/explosion) is for. Pieces burst outward from one or more origin points and then drift down under gravity. In v2 each origin is its own PIConfetti.Origin child, which makes multi-origin bursts straightforward:
import { PIConfetti } from 'react-native-fast-confetti';
export function RewardReveal() {
return (
<PIConfetti autoplay>
<PIConfetti.Origin blastPosition="center" count={200}>
<PIConfetti.Flake size={12} />
</PIConfetti.Origin>
</PIConfetti>
);
}
Each origin takes a required blastPosition, plus a count, an initialSpeed, and a spread measured in radians (a full 2 * PI spread fires in all directions). The default gravity for burst components is higher than for falling confetti, which gives the launch-then-fall arc its snappy feel. Positions accept either a named string like center, top-left, or bottom-right, or an explicit { x, y } coordinate so you can aim a burst at the exact element a user tapped.
Firing the Cannons
For the most directional, dramatic effect, CannonConfetti launches pieces from one or more cannon origins, each aimed at a target and each independently controllable. This is the tool for staged, asymmetric celebrations, like two cannons firing inward from the bottom corners of the screen:
import { CannonConfetti } from 'react-native-fast-confetti';
export function GrandFinale() {
return (
<CannonConfetti autoplay gravity={3}>
<CannonConfetti.Origin position="bottom-left" count={150} initialSpeed={3}>
<CannonConfetti.Flake size={12} radius={6} />
</CannonConfetti.Origin>
<CannonConfetti.Origin position="bottom-right" count={150} initialSpeed={3}>
<CannonConfetti.Flake size={12} />
</CannonConfetti.Origin>
</CannonConfetti>
);
}
Each CannonConfetti.Origin has a required position and accepts a target aim point, an initialSpeed, a spread, and a speedVariation range so the launched pieces do not all move in lockstep. The component as a whole adds a drag setting (a single number, or separate horizontal and vertical values) and a sprayDuration that staggers the launches over time so a cannon sprays rather than dumps everything in one frame.
Dressing Up the Flakes
Default flakes are colored rectangles, but the Skia backend means you can hand the library any image or SVG to use as a sprite. You set a default texture on the parent and override it on individual flake groups. This is how you make a stack of dollar bills rain or a flurry of snowflakes drift down:
import { useImage, useSVG } from '@shopify/react-native-skia';
import { Confetti } from 'react-native-fast-confetti';
export function MoneyRain() {
const moneyImage = useImage(require('./money.png'));
const snowSvg = useSVG(require('./snowflake.svg'));
return (
<Confetti autoplay image={moneyImage}>
<Confetti.Flake size={50} />
<Confetti.Flake size={30} svg={snowSvg} />
<Confetti.Flake width={8} height={14} />
</Confetti>
);
}
Colors work the same way: pass a default palette on the parent and override it per flake group when you want a specific group of pieces to stand out:
<Confetti autoplay colors={['#FF0000', '#00FF00']}>
<Confetti.Flake width={8} height={14} />
<Confetti.Flake size={12} colors={['#0000FF', '#FFFF00']} />
</Confetti>
Taking the Controls
Autoplay covers a lot of cases, but real celebrations are usually triggered by user actions, so you will often want imperative control. All four components share the same ref surface, typed as ConfettiMethods. Set autoplay to false, grab a ref, and call the methods when the moment arrives:
import { useRef } from 'react';
import { Button, View } from 'react-native';
import { Confetti, type ConfettiMethods } from 'react-native-fast-confetti';
export function CelebrateOnTap() {
const ref = useRef<ConfettiMethods>(null);
return (
<View>
<Confetti ref={ref} autoplay={false}>
<Confetti.Flake size={12} />
</Confetti>
<Button title="Celebrate" onPress={() => ref.current?.restart()} />
</View>
);
}
The control surface is small and predictable: restart plays from the beginning, pause and resume do exactly what they say, and reset stops and clears the animation. For the burst components, restart can take an options object to override origins on the fly, so you can fire the next celebration from a different spot without re-rendering anything.
Choosing It Wisely
It is worth being honest about the trade-off. The incumbent in this space, react-native-confetti-cannon, has several times the downloads and needs no heavy native peers, which makes it the easy default for low piece counts or projects that are not already on Skia. React Native Fast Confetti asks more of your stack, requiring Skia, Reanimated 4, and Worklets together.
What you get in return is decisive when you need it: hundreds of pieces at a locked 60fps, physics-driven motion that looks natural instead of scripted, textured flakes, and multi-origin cannons, all from a clean composable API. If your celebrations are dense, branded, or central to the experience, that single Skia draw call and the UI-thread physics engine are exactly the upgrade worth reaching for. Throw the party, and let the confetti do the heavy lifting.