Animated border beam effects for Flutter — a traveling or breathing glow around any widget: cards, buttons, inputs, or search bars.
A faithful Flutter port of the border-beam React library by Jakub Antalik (live demo). Every palette, gradient, mask, blur, and timing curve is transcribed from the original source, so the effects are pixel-matched — with Flutter-native additions on top: superellipse (squircle) borders, custom color palettes, a playback controller, and spring-eased fades.
![]() Rotate — a beam travels around the border |
![]() Pulse outside — a breathing halo blooms behind the child |
![]() Line — the beam rides the bottom edge |
![]() Superellipse — Apple-style squircle borders, ocean palette
|
Run the example app for the full animated gallery (cd example && flutter run); demo videos are recorded with tool/record_demo.sh (see Recording demos).
- Five variants, each a named constructor with tuned defaults:
rotate,small,line,pulseInside,pulseOutside. - Four palettes from the original (
colorful,mono,ocean,sunset), plusBeamColors.custom(...)for your own colors andBeamColors.spec(...)for per-blob control. - Superellipse borders — one flag switches the beam to an Apple-style squircle.
- Playback control — declarative
activetoggling with spring-eased fades,autoPlay/startAfter/durationscheduling, or a fullBorderBeamController. - Dark & light themes per variant, following your app theme automatically.
- Decorative-only — beam layers never intercept pointers; your child lays out and hit-tests normally.
- Performance-minded — one
Tickerper beam, ~30fps cap for pulse variants,RepaintBoundary-isolated painting (your child never re-rasterizes), CPU-folded color filters (≤3saveLayers per frame). - Accessible — honors
MediaQuery.disableAnimationsout of the box.
- Flutter ≥ 3.35 (stable
RoundedSuperellipseBorder/RSuperellipse) - Dart ≥ 3.9
dependencies:
border_beam: ^0.1.0Wrap any widget:
import 'package:border_beam/border_beam.dart';
BorderBeam.rotate(
child: Card(child: content),
)BorderBeam.rotate(child: card) // full border beam — cards, surfaces
BorderBeam.small(child: iconButton) // compact — buttons, chips (32px radius)
BorderBeam.line(child: searchBar) // travels the bottom edge — inputs
BorderBeam.pulseInside(child: card) // contained breathing glow
BorderBeam.pulseOutside(child: card) // halo blooming outward behind the childpulse-outside contract (same as the original): the child must be opaque so only the outward spill shows, should have its own 1px border for a defined idle edge, and needs clip-free room around it — padding in the parent, no tight
ClipRRect.
// Presets
BorderBeam.rotate(colors: BeamColors.ocean, child: card) // also: colorful (default), mono, sunset
// Your own colors, distributed over the preset blob geometry
BorderBeam.rotate(
colors: BeamColors.custom([Colors.pink, Colors.cyan, Colors.amber]),
child: card,
)
// Advanced: position every blob yourself
BorderBeam.rotate(
colors: BeamColors.spec(border: [
BeamBlob(color: Colors.pink, position: Offset(0.3, 0), size: Size(70, 40)),
// ...
]),
child: card,
)mono disables the hue animation and halves layer opacity, exactly like the source.
BorderBeam.rotate(
borderRadius: 24, // match your child's decoration radius
useSuperellipse: true, // Apple-style squircle contour
child: card,
)borderRadius defaults to the variant preset (16, or 32 for small). There is no auto-detection of the child's radius — pass the same value your child uses.
BorderBeam.pulseInside(
active: isLoading, // fades in 0.6s / out 0.5s (spring-eased)
startAfter: Duration(milliseconds: 500), // delay before autoplay
duration: Duration(seconds: 10), // total play time; null = loop forever
onActivate: () => print('visible'), // fires when the fade-in completes
onDeactivate: () => print('hidden'),
child: card,
)Attach a BorderBeamController for programmatic playback. The controller takes full ownership — startAfter/duration must not be set, and the beam starts hidden until you start():
final controller = BorderBeamController();
BorderBeam.rotate(controller: controller, child: card);
controller.start(); // fade in, play
controller.pause(); // freeze the current frame
controller.resume();
controller.speed = 2; // playback rate
controller.seek(Duration(seconds: 1));
controller.stop(); // fade out, haltEvery tuning hook of the original is a parameter:
| Parameter | Default | Purpose |
|---|---|---|
strength |
1.0 |
Overall effect opacity (0–1); only affects beam layers |
cycleDuration |
1.96s / 3.1s / 2.3s | One animation cycle (rotate·small / line / pulse) |
theme |
BeamTheme.auto |
dark, light, or follow Theme.of(context) |
brightness, saturation |
per variant/theme | Glow filter multipliers |
hueRange |
30 (line caps at 13) |
Hue animation amplitude in degrees |
hueBase |
0 |
Static hue offset for the whole palette |
staticColors |
false |
Disable the hue animation |
respectReducedMotion |
true |
Static frame under MediaQuery.disableAnimations |
strokeOpacityFactor, innerOpacityFactor, bloomOpacityFactor |
1 |
Per-layer opacity multipliers |
glowBoost (pulse) |
1 |
Halo prominence |
coreBlur, bloomBlur, glowBrightness, glowSaturation (pulse-outside) |
preset | Glow tuning overrides |
example/ contains a full gallery recreating the original demo — Rotate/Pulse example tabs with mock chat inputs, task cards, and search bars, plus an interactive playground with live code snippets:
cd example && flutter runDemo reels live in example/lib/*.dart and use the marker-based harness in example/lib/demo_harness.dart. Record on a booted iOS simulator (requires ffmpeg):
tool/record_demo.sh --target lib/showcase.dart --prefix SHOWCASE --contactOutputs land in .demos/ (gitignored) as 60fps center-cropped mp4s with a contact sheet for review.
This package is a port of border-beam — created and designed by Jakub Antalik and released under the MIT license. All visual design — the five effects, color palettes, gradient geometry, animation timings, and the demo it ships with — is his work. If you like the effect, go star the original.
The Flutter port adds the widget/controller architecture, superellipse shapes, custom palette API, and the canvas rendering engine.
MIT — includes the original work's copyright notice.



