solid-transition-group
SolidJS components that animate elements as they enter, exit, or move in the DOM, in the spirit of Vue Transitions and React Transition Group.
Repository Health
Technical Analysis
solid-transition-group gives SolidJS applications declarative <Transition> and <TransitionGroup> components for animating elements as they mount, unmount, or reorder. <Transition> handles a single child at a time, automatically deriving CSS class names from a name prop (*-enter, *-enter-active, *-exit, and so on), while <TransitionGroup> extends the same model to lists, adding a FLIP-based move animation so reordered items glide to their new position instead of jumping.
Both components expose a matching set of lifecycle events (onBeforeEnter, onEnter, onAfterEnter, onBeforeExit, onExit, onAfterExit) so animations can be driven with plain CSS transitions or with JavaScript animation libraries via the Web Animations API, calling a done callback when finished. Built on top of the official @solid-primitives/transition-group and @solid-primitives/refs primitives rather than reimplementing transition state machines from scratch, it is a thin, well-tested layer that brings a Vue-familiar transition API to Solid’s fine-grained reactivity model.
What You Get
- A
<Transition>component for animating a single element or component as it is added or removed from the DOM, withappearandmode(inout/outin) options to control sequencing - A
<TransitionGroup>component for animating lists, including a FLIP-basedmovetransition so items smoothly slide to their new position when the list reorders - Automatic CSS class generation from a
nameprop (defaulting tos-enter,s-enter-active,s-exit, etc.), or fully custom class names viaenterClass/exitClass/enterActiveClass/etc. props - Lifecycle events (
onBeforeEnter,onEnter,onAfterEnter,onBeforeExit,onExit,onAfterExit) for driving animations with the Web Animations API or any JS animation library instead of CSS - SSR-safe behavior verified by a dedicated server-rendering test suite, so transitions don’t break when rendered outside the browser
Common Use Cases
- Fading or sliding a conditionally-rendered element (e.g. a modal, tooltip, or alert banner) in and out with
<Show>and<Transition> - Animating list insertions, removals, and reordering in a
<For>-rendered list with<TransitionGroup>, such as a todo list, notification stack, or Kanban column - Building route-change transitions between page views by wrapping router
<Outlet>output in<Transition mode="outin"> - Driving custom JS-based animations (spring physics, Web Animations API) by hooking into
onEnter/onExitinstead of relying on CSS classes alone
Under The Hood
Architecture
The package is a single-module wrapper: src/index.ts exports the Transition and TransitionGroup components along with two shared internal functions, enterTransition and exitTransition, that both components call to add/remove the enter/exit CSS classes and manage transitionend/animationend listeners. Rather than implementing its own scheduling logic, it delegates state transitions to createSwitchTransition (for Transition) and createListTransition (for TransitionGroup) from @solid-primitives/transition-group, and resolves DOM refs via resolveFirst/resolveElements from @solid-primitives/refs. A memoized createClassnames derives the full set of class names once per prop change, keeping both components’ rendering logic declarative and DOM-manipulation code centralized in the two shared transition functions; if the callback shape exposed by the underlying createSwitchTransition/createListTransition primitives changed, both components would need to be updated in lockstep since they pass matching onEnter/onExit handlers straight through.
Tech Stack
Written in strict-mode TypeScript, compiled with plain tsc (no bundler) to ESM-only output (type: module, no CJS build), with solid-js as a peer dependency and @solid-primitives/refs plus @solid-primitives/transition-group as the only runtime dependencies. Testing uses Vitest with vite-plugin-solid, running the same suite against a jsdom (browser-like) environment and a Node SSR environment via a --mode ssr flag, executed concurrently through the concurrently package. A companion demo/docs site is built with Astro, @astrojs/solid-js, and Tailwind CSS, deployed to Netlify.
Code Quality
The test suite manually queues and flushes requestAnimationFrame callbacks to deterministically assert the exact frame-by-frame timing of enter/exit transitions (matching Vue’s documented out-in timing behavior) rather than relying on real timers, plus a dedicated SSR test file confirming the components render safely outside the browser. tsconfig.json enables strict and noUncheckedIndexedAccess, and every exported prop and event on TransitionProps/TransitionGroupProps/TransitionEvents carries a JSDoc comment. CI (GitHub Actions) runs the build and full test suite on every push and pull request to main. No dedicated ESLint configuration was found in the repo; formatting is enforced via Prettier only.
API Design
The API deliberately mirrors Vue’s Transition component conventions (a name prop auto-generating *-enter/*-enter-active/*-exit classes, an appear flag, mode values of "inout"/"outin"), which lowers the learning curve for developers arriving from Vue while adapting the surface to Solid’s JSX and component model. Zero props are required beyond children — a consumer can start animating with CSS alone by adding a name prop, and escalate to JavaScript-driven animation later by adding an onEnter/onExit callback without changing anything else. Inline JSDoc on every prop documents exactly which DOM state applies at each callback (e.g. whether the element is attached yet), reducing how often a developer needs to leave the editor to check the README.