npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

transition-lit

v3.2.0

Published

Rudimentary animation/transition library written for React applications

Readme

transition-lit

transition-lit is a rudimentary animation/transition library written for React applications. It is not an animation library like react-spring and it doesn't animate styles by itself. Instead, it reveals transition stages, manages classes and group elements, and manipulates the DOM, hopefully making it easier to build actual visual transitions on top.

Install

# Using npm
npm install transition-lit

# Using yarn (v1.xx)
yarn add transition-lit

Examples

transition-lit exposes a handful of components demonstrated in this section.

<Transition />

The <Transition /> component is the base component and lets you describe a transition from one state to another over a fixed period of time.

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Transition } from 'transition-lit';

const App = () => {
  const [inProp, setInProp] = React.useState(false);

  // [1] Define the duration of the transition.
  const duration = {
    enter: 150,
    exit: 75,
  };

  // [2] Define the component's default styling. Notice that we aren't using the
  // `transition` shorthand property because we want to use different transition
  // durations for enter and exit transitions as defined in [1].
  const defaultStyle = {
    transitionProperty: 'opacity',
    transitionTimingFunction: 'cubic-bezier(0.4, 0.0, 0.2, 1)',
    opacity: 0,
  };

  // [3] Define styles for each transition phase.
  const transitionStyles = {
    entering: { opacity: 1, transitionDuration: `${duration.enter}ms` },
    entered: { opacity: 1, transitionDuration: `${duration.enter}ms` },
    exiting: { opacity: 0, transitionDuration: `${duration.exit}ms` },
    exited: { opacity: 0, transitionDuration: `${duration.exit}ms` },
  };

  // [4] Use the <Transition /> component to expose the different transition
  // states for you to act on. The transition state is toggled by the `in` prop.
  return (
    <div>
      <button onClick={() => setInProp(v => !v)}>Toggle</button>
      <Transition in={inProp} timeout={duration}>
        {state => (
          <div
            style={{
              ...defaultStyle,
              ...transitionStyles[state],
            }}
          >
            This is a fade transition!
          </div>
        )}
      </Transition>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);

Props

children

Use the function as a child pattern to expose the current transition state to your child components. Possible transition states are: entering, entered, exiting and exited.

<Transition in={inProp} timeout={200}>
  {state => <Component className={`animation animation-${state}`} />}
</Transition>

type: Function | Element
required

in

Triggers enter or exit transitions. true triggers the enter transition, false triggers the exit transition.

type: boolean
default: false

mountOnEnter

By default a child component is mounted immediately along the Transition component. Set the mountOnEnter prop if you want to defer mounting to the first enter transition.

type: boolean
default: false

unmountOnExit

By default a child component stays mounted even after the exit transition ends. Set the unmountOnExit prop to disable this behaviour and unmount the child component after it finishes exiting.

type: boolean
default: false

appear

By default a child component is not transitioned in if it is shown when the Transition component mounts. By setting the appear prop you can force a enter transition on mount.

Note: For <Transition /> there are no additional appear states — the same entering/entered states are used. <CSSTransition /> does add dedicated *-appear, *-appear-active, and *-appear-done CSS classes.

type: boolean
default: false

enter

Enable/disable enter transitions.

type: boolean
default: true

exit

Enable/disable exit transitions.

type: boolean
default: true

timeout

Duration of a transition in milliseconds.
You can provide a single number for all transition phases or an object defining individual timeouts.

timeout={200}

// or

timeout={{
  appear: 100,
  enter: 200,
  exit: 75,
}}

type: number | { enter?: number, exit?: number, appear?: number }
required

onEnter

Callback fired before the entering status is applied. The node argument is the currently transitioned DOM element. The isAppearing parameter indicates if the transition happens on initial mount.

type: Function(node: HTMLElement, isAppearing: boolean): void
default: Function(): void

onEntering

Callback fired after the entering status is applied. The node argument is the currently transitioned DOM element. The isAppearing parameter indicates if the transition happens on initial mount.

type: Function(node: HTMLElement, isAppearing: boolean): void
default: Function(): void

onEntered

Callback fired after the entered status is applied. The node argument is the currently transitioned DOM element. The isAppearing parameter indicates if the transition happens on initial mount.

type: Function(node: HTMLElement, isAppearing: boolean): void
default: Function(): void

onExit

Callback fired before the exiting status is applied.

type: Function(node: HTMLElement): void
default: Function(): void

onExiting

Callback fired after the exiting status is applied.

type: Function(node: HTMLElement): void
default: Function(): void

onExited

Callback fired after the exited status is applied.

type: Function(node: HTMLElement): void
default: Function(): void


<TransitionGroup />

The <TransitionGroup> component manages a set of transition components (<Transition> and <CSSTransition>) in a list. Like with the transition components, <TransitionGroup> is a state machine for managing the mounting and unmounting of components over time.

Consider the example below. As items are removed or added to the TodoList the in prop is toggled automatically by the <TransitionGroup>.

Note: <TransitionGroup> does not define any animation behavior! Exactly how a list item animates is up to the individual transition component. This means you can mix and match animations across different list items.

import React from 'react';
import ReactDOM from 'react-dom/client';
import { CSSTransition, TransitionGroup } from 'transition-lit';

const App = () => {
  const [items, setItems] = React.useState([
    { id: crypto.randomUUID() },
    { id: crypto.randomUUID() },
    { id: crypto.randomUUID() },
    { id: crypto.randomUUID() },
  ]);

  const addItem = () => {
    setItems(items => [...items, { id: crypto.randomUUID() }]);
  };

  const removeItem = id => {
    setItems(items => items.filter(item => item.id !== id));
  };

  return (
    <>
      <button onClick={() => addItem()}>Add</button>

      <TransitionGroup>
        {items.map(({ id }) => (
          <CSSTransition key={id} timeout={200} classNames="my-node">
            <div>
              <span>{id}</span>
              <button onClick={() => removeItem(id)}>Remove</button>
            </div>
          </CSSTransition>
        ))}
      </TransitionGroup>
    </>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);

Props

children

A set of <Transition> components, that are toggled in and out as they leave. The <TransitionGroup> will inject specific transition props, so remember to spread them through if you are wrapping the <Transition> component.

In case you want to transition content of a single transition child (e.g. route- transitions or carousel-/image-transitions) you have to change the key prop of the transition child which forces <TransitionGroup> to transition the child out and back in again.

type: any

appear

A convenience prop that enables or disables appear animations for all children.

Note: Specifying this will override any defaults set on individual children <Transitions>.

type: boolean

enter

A convenience prop that enables or disables enter animations for all children.

Note: Specifying this will override any defaults set on individual children <Transitions>.

type: boolean

exit

A convenience prop that enables or disables exit animations for all children.

Note: Specifying this will override any defaults set on individual children <Transitions>.

type: boolean

childFactory

You may need to apply reactive updates to a child as it is exiting. This is generally done by using cloneElement however in the case of an exiting child the element has already been removed and not accessible to the consumer.

If you do need to update a child as it leaves you can provide a childFactory to wrap every child, even the ones that are leaving.

type: Function(child: ReactNode) -> ReactNode
default: child => child

<CSSTransition />

A transition component inspired by ng-animate. It should be used if animations are being done by declaring transitions via CSS classes.

CSSTransition applies a pair of class names during the appear, enter, and exit states of the transition. The first class is applied and then a second *-active class in order to activate the CSS transition. After the transition, matching *-done class names are applied to persist the transition state.

function App() {
  const [show, setShow] = React.useState(false);

  return (
    <div>
      <CSSTransition in={show} timeout={200} classNames="my-node">
        <div>I'll receive my-node-* classes</div>
      </CSSTransition>
      <button onClick={() => setShow(show => !show)}>Toggle</button>
    </div>
  );
}

When the in prop is set to true, the child component will first receive the the class my-node-enter, then the my-node-enter-active will be added in the next tick.

Note: CSSTransition forces a reflow before adding the my-node-enter-active. This is an important trick because it allows us to transition between my-node-enter and my-node-enter-active even though they were added immediately one after another. Most notably, this is what makes it possible for us to animate appearance.

.my-node-enter {
  opacity: 0;
}
.my-node-enter-active {
  opacity: 1;
  transition: opacity 200ms;
}
.my-node-enter-done,
.my-node-exit {
  opacity: 1;
}
.my-node-exit-active {
  opacity: 0;
  transition: opacity 200ms;
}
.my-node-exit-done {
  opacity: 0;
}

Keep in mind: *-active classes represent which styles you want to animate to.

Note: If you're using the appear prop, make sure to define styles for appear-* classes as well.

Props

classNames

The animation classNames applied to the component as it appears, enters, exits or has finished the transition. A single name can be provided and it will be suffixed for each stage:

<CSSTransition in={show} timeout={200} classNames="fade">
  <div>I'll receive my-node-* classes</div>
</CSSTransition>

// applies fade-appear, fade-appear-active, fade-appear-done, fade-enter,
// fade-enter-active, fade-enter-done, fade-exit, fade-exit-active,
// and fade-exit-done.

Note: fade-appear-done and fade-enter-done will both be applied. This allows you to define different behavior for when appearing is done and when regular entering is done, using selectors like .fade-enter-done:not(.fade-appear-done).

Each individual classNames can also be specified independently like:

classNames={{
 appear: 'my-appear',
 appearActive: 'my-active-appear',
 appearDone: 'my-done-appear',
 enter: 'my-enter',
 enterActive: 'my-active-enter',
 enterDone: 'my-done-enter',
 exit: 'my-exit',
 exitActive: 'my-active-exit',
 exitDone: 'my-done-exit',
}}

type: string | { appear?: string, appearActive?: string, appearDone?: string, enter?: string, enterActive?: string, enterDone?: string, exit?: string, exitActive?: string, exitDone?: string }
default: ''

onEnter

A <Transition> callback fired immediately after the enter or appear class is applied.

type: Function(node: HTMLElement, isAppearing: boolean)

onEntering

A <Transition> callback fired immediately after the enter-active or appear-active class is applied.

type: Function(node: HTMLElement, isAppearing: boolean)

onEntered

A <Transition> callback fired immediately after the enter or appear classes are removed and the enter-done class is added to the DOM node.

type: Function(node: HTMLElement, isAppearing: boolean)

onExit

A <Transition> callback fired immediately after the exit class is applied.

type: Function(node: HTMLElement)

onExiting

A <Transition> callback fired immediately after the exit-active is applied.

type: Function(node: HTMLElement)

onExited

A <Transition> callback fired immediately after the exit classes are removed and the exit-done class is added to the DOM node.

type: Function(node: HTMLElement)