react-native-beam-border
v0.1.3
Published
Animated border beam for React Native, rendered with Skia. Port of Jakub Antalik's border-beam.
Maintainers
Readme
react-native-beam-border

Animated border beam for React Native. The effect is drawn with
Skia through the React Native bindings
(@shopify/react-native-skia).
Shopify publishes those bindings; this package is not a Shopify product and
does not talk to Shopify.
Port of border-beam by Jakub Antalik. The
preview above is a live CSS stand-in of the same families (md, pulse-inner,
pulse-outside, line). Native and RN web render them with Skia.
The clock is requestAnimationFrame on the JS thread. The package does not
use Reanimated or worklets.
Status: beta — iOS-verified only. All 5 types (
sm,md,line,pulse-outside,pulse-inner) × 4 color variants × dark/light. Visual parity against the web demo is still being tuned. Android is untested (pure Skia, no platform branches — please report what you find).
If you are shipping this in an app, read LIBRARY.md first. iPhone launch abort, native SkSL compile, and CanvasKit’s 2 GB WebGL flush are easy to reintroduce.
Install
npm install react-native-beam-border @shopify/react-native-skiaInstall both: this package is the beam; @shopify/react-native-skia is the
canvas it paints on (a peer dependency, not a nested Shopify SDK).
Skia is a native module. Use a development build / expo run:* / TestFlight —
not Expo Go.
Pin Skia to the version your Expo SDK already ships. Do not add
react-native-reanimated or react-native-worklets unless the host app
already needs them.
Usage
import { BorderBeam } from 'react-native-beam-border';
<BorderBeam size="md" colorVariant="ocean">
<View style={{ padding: 24, borderRadius: 16, backgroundColor: '#1d1d1d' }}>
<Text>Hello</Text>
</View>
</BorderBeam>Wrap any child. borderRadius is read from that child's style when you omit
the prop. active={false} fades the beam out.
Other props: size, colorVariant, theme ('auto' follows the system
scheme), staticColors, duration, brightness, saturation, hueRange,
strength, tintColor, tuning, plus style for the wrapping View.
| Want | size |
| --- | --- |
| Traveling conic on the border | sm / md |
| Bottom traveling glow | line |
| Breathing blobs inside a clipped card | pulse-inner |
| Halo outside an opaque child | pulse-outside |
pulse-outside needs an opaque child. The wrap adds margin for the halo.
pulse-inner should clip (overflow: 'hidden') on the child.
Tuning
import { BorderBeam, WEB_DEMO_PULSE_PRESET } from 'react-native-beam-border';
<BorderBeam size="pulse-outside" tuning={WEB_DEMO_PULSE_PRESET}>
…
</BorderBeam>The web demo’s pulse-outside card is not stock output — it applies a
1.05× glow boost with 1.71× layer opacity. Untuned beams are softer on
purpose.
Web (React Native Web)
Load CanvasKit before any Skia import, and serve canvaskit.wasm from the
web public root:
import { LoadSkiaWeb } from '@shopify/react-native-skia/lib/module/web';
LoadSkiaWeb({ locateFile: (file) => `/${file}` }).then(() => {
require('./App');
});Metro must emit .wasm (assetExts should include wasm). This package’s
.web.tsx entry uses WithSkiaWeb so CanvasKit is on global before the
shaders compile.
Expo host notes
Apps that do not otherwise need Reanimated should keep it out of the binary:
// babel.config.js
presets: [['babel-preset-expo', { reanimated: false, worklets: false }]]// app.json / package.json expo.autolinking
"autolinking": { "exclude": ["react-native-reanimated", "react-native-worklets"] }Pause the beam when it is off-screen (active={false}). A background rAF
still costs. Verify launch on a physical iPhone release/TestFlight build —
Expo Go does not count.
License
MIT. Original border-beam by Jakub Antalik; this repository is the React Native Skia port.
