Bit.Bmotion
10.6.0
dotnet add package Bit.Bmotion --version 10.6.0
NuGet\Install-Package Bit.Bmotion -Version 10.6.0
<PackageReference Include="Bit.Bmotion" Version="10.6.0" />
<PackageVersion Include="Bit.Bmotion" Version="10.6.0" />
<PackageReference Include="Bit.Bmotion" />
paket add Bit.Bmotion --version 10.6.0
#r "nuget: Bit.Bmotion, 10.6.0"
#:package Bit.Bmotion@10.6.0
#addin nuget:?package=Bit.Bmotion&version=10.6.0
#tool nuget:?package=Bit.Bmotion&version=10.6.0
Bit.Bmotion
A Blazor-native animation library inspired by Motion (Framer Motion): springs, gestures, keyframes, variants, drag, layout (FLIP) animations, shared-element transitions and exit animations - no manual JavaScript wiring required. All animation math (spring, tween, inertia, keyframes, easing, color interpolation, gesture state, transform composition) runs in C#; JavaScript is used only as a thin bridge to browser-native APIs.
Quick start
// Program.cs
builder.Services.AddBitBmotionServices();
@using Bit.Bmotion
<Bmotion Initial="Bm.To(opacity: 0, y: 20)"
Animate="Bm.To(opacity: 1, y: 0)"
Transition="Bm.Spring(bounce: 0.4, duration: 0.6)">
<div>Hello, Bmotion!</div>
</Bmotion>
The Bm facade is the entry point for the whole hot path: Bm.To(...) builds animation
targets (single values or keyframe sequences), Bm.Spring / Bm.Tween / Bm.Inertia build
transitions, Bm.Stagger builds multi-element delay generators, Bm.SnapTo builds the
snap-to-grid / snap-to-page hook a drag release settles on, Bm.Value creates reactive
motion values, and Bm.Template composes them into CSS strings. Components:
<Bmotion>, <BmotionAnimatePresence>, <BmotionPresenceSwitch>, <BmotionPresenceGroup>
(keyed list presence, with a popLayout mode), <BmotionReorderGroup> (drag-to-reorder lists),
<BmotionSplitText> (staggered per-character/word/line text animation, split in C# rather than by
DOM surgery), <BmotionLayoutGroup> and <BmotionConfig>. Programmatic
animation is available through BmotionAnimateService (selector / ElementReference based,
supports sequences and staggers) and BmotionScrollTracker (scroll-linked motion values).
A BmSequence timeline runs on a single playhead driven by the animation clock, so the controls it
returns govern the gaps between steps as well as the steps themselves - pausing a sequence really
holds it, and SetSpeed(3) compresses the silences by the same factor as the movement.
Scroll-linked animation has a fast path of its own: Timeline="BmScrollTimeline.Page()" (or
View(), Container(...), ViewOf(...)) hands the animation to the browser's native
ScrollTimeline / ViewTimeline, so scrubbing it costs no scroll handler, no frame loop and no
interop at all. Browsers without those APIs get a scroll-scrub fallback over the same Web Animation.
See the repository README for the full guide, and the XML documentation on Bmotion, Bm,
and BmotionAnimateService for the complete API surface.
Platform support
- ✅ Blazor WebAssembly - fully supported. Compositor-eligible animations (tweens and zero-velocity springs on transform/opacity) are pre-sampled in C# and run on the browser's Web Animations API off the main thread; everything else runs on the C# rAF engine over synchronous interop.
- ⚠️ Blazor Server - the compositor path works (it needs only async interop), so enter/exit/hover/tap/variant animations on transform + opacity play normally. Features that require the per-frame loop - inertia, color/dimension interpolation, keyframe arrays, drag, motion values - degrade to instant state changes.
- ⏸️ Server-side prerendering - components render their initial styles; animations start once the circuit/runtime becomes interactive.
Inject BmotionCapabilities to detect the current mode instead of guessing:
Caps.SupportsFrameLoop is false on Server (drag/inertia/interpolation degrade to instant),
Caps.SupportsCompositor is always true. On Server, the first animation that collapses to an
instant change also logs a one-time warning so the degradation is diagnosable.
Accessibility: reduced motion
Choose how the library honours the OS prefers-reduced-motion setting globally at registration:
builder.Services.AddBitBmotionServices(o => o.ReducedMotion = BmReducedMotionMode.User);
BmReducedMotionMode |
Behaviour |
|---|---|
IgnoreUnlessConfigured |
Default (back-compat). OS preference respected only inside a <BmotionConfig>. |
User |
Recommended. Respect the OS preference everywhere - the web-platform default. |
Always |
Always reduce, regardless of the OS. |
Never |
Never reduce, regardless of the OS. |
When motion is reduced, Bit.Bmotion follows Motion's "user" semantics: transforms, layout and
dimension changes snap to their target instantly, while opacity and colour still animate - a
softer, more correct reduction than collapsing every property to instant.
A local <BmotionConfig ReduceMotion="true|false"> always overrides the global mode for its subtree
(null = follow the mode):
<BmotionConfig ReduceMotion="true"> @* force-reduce this subtree *@
...
</BmotionConfig>
Migration note. The default remains
IgnoreUnlessConfiguredso existing apps are unaffected. New apps should setReducedMotion = BmReducedMotionMode.Userto match the platform default; this is planned to become the default in a future major version.
Security note
String-valued animation properties (backgroundColor, width, boxShadow, color, custom
cssVars, …) are written verbatim into the element's inline style. They are meant for
developer-authored values. Do not bind untrusted end-user input to them, or you risk CSS
injection into the element's style.
If you must bind untrusted input, enable CSS safe mode to validate those values against a
conservative injection check (rejecting ;, }, <, javascript:, expression(, comments, …):
builder.Services.AddBitBmotionServices(o => o.CssSafeMode = BmCssSafeMode.Throw); // or .Warn
It is Off by default (for performance/parity); Warn logs and still applies, Throw rejects.
Threading
The animation engine is intentionally lock-free and assumes a single (the WebAssembly UI) thread.
Do not enable WebAssembly multithreading (<WasmEnableThreads>) with this library.
Disposing the programmatic helpers
BmotionScrollTracker is registered Transient and is owned by the consuming component. When
obtained via @inject, Blazor does not dispose it per component - the consuming component
must dispose it itself (call its DisposeAsync from the component's own DisposeAsync),
otherwise its JS subscription leaks until the app shuts down.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Components.Web (>= 10.0.0 && < 11.0.0)
-
net8.0
- Microsoft.AspNetCore.Components.Web (>= 8.0.0 && < 9.0.0)
-
net9.0
- Microsoft.AspNetCore.Components.Web (>= 9.0.0 && < 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.6.0 | 36 | 9/13/2026 |
| 10.6.0-pre-06 | 41 | 9/13/2026 |
| 10.6.0-pre-05 | 45 | 9/11/2026 |
| 10.6.0-pre-04 | 90 | 8/31/2026 |
| 10.6.0-pre-03 | 93 | 8/25/2026 |
| 10.6.0-pre-02 | 107 | 8/14/2026 |
| 10.6.0-pre-01 | 106 | 8/4/2026 |
| 10.5.0 | 144 | 7/20/2026 |
| 10.5.0-pre-10 | 107 | 7/20/2026 |
| 10.5.0-pre-09 | 102 | 7/19/2026 |
| 10.5.0-pre-08 | 103 | 7/11/2026 |
| 10.5.0-pre-07 | 103 | 7/10/2026 |
| 10.5.0-pre-06 | 111 | 7/7/2026 |
| 10.5.0-pre-05 | 110 | 6/28/2026 |