Skip to content
All components
  • Clear Sky
  • Autumn
  • Blossom
  • Monsoon

Weather

Ambient Weather

Butterflies, rain, snow and falling leaves that land on your own views: water collects on cards, snow piles up, butterflies perch.

$29

Or get it with Pro

Features

  • Five effects in one kit: butterflies, rain, snow, falling leaves and a visible breeze
  • Mark a view once and every effect lands on it
  • Rain collects as water on your cards and drips off the edges, with lightning
  • Snow piles up on everything and slides off in clumps
  • Leaves fall from a tree, settle on your cards and blow away in gusts
  • Butterflies perch on your cards, your numbers, even your text, and fly off when touched
  • Touch a card and whatever lies on it falls off; tilt the phone and the water pours away
  • Ready-made presets for each, from a drizzle to a storm and a flurry to a blizzard
  • Costs nothing while paused or in the background, and holds still with Reduce Motion

Built with

  • Skia
  • Reanimated

Installation

1Install dependencies
npx expo install @shopify/react-native-skia react-native-reanimated react-native-worklets
2Run a development build (Expo Go can't load Skia)
npx expo run:ios   # or: npx expo run:android

Usage

Each look is one provider around your screen. Wrap a view in Surface (or Spot for butterflies) and the effect lands on it. These are the four scenes in the video.

Clear Sky

Butterflies fly around the screen and settle on the views you mark. Touch one and they take off.

import { StyleSheet, Text, View } from 'react-native';
import {
  ButterflyProvider,
  Spot,
} from '@/components/ambient-weather/butterfly';

export function ClearSky() {
  return (
    <ButterflyProvider preset="confetti" style={styles.screen}>
      <Spot butterflies={3} radius={16} on={['top']} interactive>
        <View style={styles.card}>
          <Text style={styles.reading}>26°</Text>
        </View>
      </Spot>
    </ButterflyProvider>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1, justifyContent: 'center', padding: 24 },
  card: { borderRadius: 16, padding: 20, backgroundColor: '#fff' },
  reading: { fontSize: 48, fontWeight: '600' },
});

Autumn

Leaves grow at the tips of a tree picture, let go one at a time, land on your cards and blow away in the gusts.

import { Image, StyleSheet, Text, View } from 'react-native';
import { LeafProvider, LeafTree } from '@/components/ambient-weather/leaves';
import { Surface } from '@/lib/motion';

// Twig tips as x,y,angle in the tree picture's own pixels.
const TWIGS = '708,41,-83 647,47,-98 580,88,-135';
const TREE_SIZE = { width: 1024, height: 1536 };

export function Autumn() {
  return (
    <LeafProvider
      leaf={require('./leaf.png')}
      gusts="windy"
      style={styles.screen}
    >
      <LeafTree twigs={TWIGS} viewBox={TREE_SIZE} style={styles.tree}>
        <Image source={require('./tree.png')} style={styles.fill} />
      </LeafTree>
      <Surface radius={16} interactive>
        <View style={styles.card}>
          <Text>Breezy all afternoon</Text>
        </View>
      </Surface>
    </LeafProvider>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1, justifyContent: 'flex-end', padding: 24 },
  tree: { position: 'absolute', top: 0, right: 0, width: 260, height: 390 },
  fill: { width: '100%', height: '100%' },
  card: { borderRadius: 16, padding: 20, backgroundColor: '#fff' },
});

Blossom

Butterflies perch along the branches of a tree, traced as lines in an SVG, while a breeze carries glittering dust across the screen.

import { Image, StyleSheet } from 'react-native';
import { Breeze } from '@/components/ambient-weather/breeze';
import {
  ButterflyProvider,
  Spot,
} from '@/components/ambient-weather/butterfly';

// The branches as lines, in the tree picture's own pixels.
const BRANCHES = `<svg viewBox="0 0 1024 1536">
  <polyline points="801,1250 761,966 702,764 656,561 592,441" />
  <polyline points="691,752 609,710 486,663 335,619 256,592" />
</svg>`;

export function Blossom() {
  return (
    <ButterflyProvider preset="monarch" mood="calm" style={styles.screen}>
      <Spot
        butterflies={12}
        size={18}
        svg={BRANCHES}
        on={['top', 'sides']}
        interactive
        style={styles.tree}
      >
        <Image source={require('./tree.png')} style={styles.fill} />
      </Spot>
      <Breeze
        wind={-30}
        dust={{ density: 0.7, vibrancy: 0.6 }}
        style={StyleSheet.absoluteFill}
      />
    </ButterflyProvider>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1 },
  tree: { position: 'absolute', top: 40, right: 0, width: 260, height: 390 },
  fill: { width: '100%', height: '100%' },
});

Rain

Rain collects as water along the top of your cards and drips off the edges. Lightning flashes in the sky behind them.

import { StyleSheet, Text, View } from 'react-native';
import { Lightning, RainProvider } from '@/components/ambient-weather/rain';
import { Surface } from '@/lib/motion';

export function Monsoon({ onThunder }: { onThunder: () => void }) {
  return (
    <RainProvider preset="storm" onStrike={onThunder} style={styles.screen}>
      <View style={styles.sky}>
        <Lightning />
      </View>
      <Surface radius={16} interactive>
        <View style={styles.card}>
          <Text style={styles.text}>Heavy rain until 9 pm</Text>
        </View>
      </Surface>
    </RainProvider>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1, padding: 24, backgroundColor: '#11151B' },
  sky: { height: 280 },
  card: { borderRadius: 16, padding: 20, backgroundColor: '#232A33' },
  text: { color: '#ECF0F5' },
});

How it works

Each effect runs on one frame loop on the UI thread and draws with Skia, so nothing re-renders in React while it moves. A shared scene keeps one list of the views you mark: rain fills a pool of water along each top edge, leaves lie on a ledge until a gust takes them, and butterflies pick landing spots from the view's box, outline or SVG. Particles are parked and reused rather than freed, and the clock stops while paused, in the background or under Reduce Motion.

More once you own it

Examples, the full list of props and every advanced option for Ambient Weather are here for owners.

Next componentRolling Carousel
TesseraUI

Welcome back

Sign in to TesseraUI

Your purchases live in your account, so they open on every device you sign in on.

Sign-in isn’t available right now. Please try again in a moment.

By continuing you agree to the Terms, Licence and Privacy Policy.