Backprop Flow
A feed-forward neural-network visualisation that animates the two passes of training: activations flowing left → right (forward), then gradients flowing right → left (backward). One layer cursor drives the entire timeline — in auto mode it cycles forward then backward, so the user just presses play to see a full step.
Forward pass. Layer 1 of 4 activation highlighted.
Forward passlayer 01 / 04
Customize
Architecture
3-4-4-2
Pass
auto
0
Playback
Installation
npx shadcn@latest add https://craftbits.dev/r/backprop-flow.jsonUsage
import { BackpropFlow } from "@craft-bits/core";
<BackpropFlow layers={[3, 4, 4, 2]} />Pass your own activations and gradients from a real training loop:
<BackpropFlow
layers={[3, 4, 2]}
activations={[
[0.1, 0.5, 0.9],
[0.3, 0.7, 0.2, 0.8],
[0.6, 0.4],
]}
gradients={[
[0.01, 0.02, 0.005],
[0.04, 0.08, 0.06, 0.05],
[0.3, 0.4],
]}
/>Drive playback from outside the component:
const [layer, setLayer] = useState(0);
<BackpropFlow
layers={[3, 4, 2]}
direction="forward"
currentLayer={layer}
onCurrentLayerChange={setLayer}
playing={false}
/>Understanding the component
- One cursor, two passes. The
currentLayercursor advances 0 → N during the forward pass and N → 0 during the backward pass. Inautomode the cursor span is2N, so a single integer drives the whole animation —forwardandbackwardare slices of the same timeline. - Same DOM for both passes. Forward and backward share the same nodes and edges; only the active-edge highlight, label, and stroke direction change. Switching
directionis purely a style flip — no remount, no DOM churn. - Synthesised values when shape-only. Pass
layers={[3,4,2]}with noactivations/gradientsand the component renders deterministic placeholder values that mimic real-world shapes (gradients shrink toward earlier layers — the vanishing-gradient intuition). SPRINGS.smoothon the active edge / node. Layer transitions use the smooth spring from@craft-bits/core/motionso the cursor settles rather than snaps.- Reduced-motion fallback. With
prefers-reduced-motion: reduce, the diagram renders fully lit on mount with no autoplay and no per-layer animation. - Auto layout from
layersalone. Node positions are derived from the layer-shape array — change the architecture and the diagram re-flows. No coordinates to maintain.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
layers | readonly number[] | — | Neuron count per layer (left → right). Required. |
activations | readonly (readonly number[])[] | — | Forward-pass values per layer. Synthesised if omitted. |
gradients | readonly (readonly number[])[] | — | Backward-pass values per layer. Synthesised if omitted. |
direction | 'forward' | 'backward' | 'auto' | — | Controlled direction. Pair with onDirectionChange. |
defaultDirection | 'forward' | 'backward' | 'auto' | 'auto' | Uncontrolled initial direction. |
onDirectionChange | (direction) => void | — | Fires when the direction toggle cycles. |
currentLayer | number | — | Controlled cursor. Pair with onCurrentLayerChange. |
defaultCurrentLayer | number | 0 | Uncontrolled initial cursor. |
onCurrentLayerChange | (layer) => void | — | Fires on tick and on manual scrub. |
playing | boolean | — | Controlled play state. Pair with onPlayingChange. |
defaultPlaying | boolean | true | Uncontrolled initial play state. |
onPlayingChange | (playing) => void | — | Fires when play / pause flips. |
playSpeed | number | 600 | Milliseconds between layer advances. |
transition | Transition | SPRINGS.smooth | Spring for active-edge / node transitions. |
className | string | — | Merged onto the root <div> via cn(). |
Accessibility
- The figure is
role="figure"witharia-label="Backpropagation flow visualization". - An
aria-live="polite"summary announces the current pass and active layer whenever the cursor advances. - The play / pause button is
aria-pressed; the label flips between "Play flow" and "Pause flow". - The direction toggle's
aria-labelnames the current direction and that clicking will cycle. - The scrubber is a native
<input type="range">with an explicitaria-label, so keyboard arrows nudge the cursor and screen readers narrate the value. - Color is never the only signal — pass label, active-layer count, and value labels are all textual.
prefers-reduced-motion: reducerenders the network fully lit on mount and disables autoplay.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/viz/BackpropFlow.tsx). Stripped the lesson-specificWidgetchrome, predict-quiz, multi-step narration heuristics, slider-bounda/b/cinputs, and the bespokea × b + c → σcomputation graph. Generalised to an arbitrarylayers: number[]feed-forward network with controlled / uncontrolled state pairs fordirection,currentLayer, andplaying.