ViewTransitions

ViewTransitions is a namespace that wraps the browser's native View Transitions API, adding automatic batching and queue management so that rapid successive calls are coalesced into a single transition rather than overlapping.

When the View Transitions API is not supported by the browser, ViewTransitions.run falls back to executing the callback directly — no polyfill required.

ViewTransitions.run(callback, options?) executes a state update inside a view transition and returns a Promise that resolves with the callback's return value.

Multiple calls made in the same microtask tick are automatically batched into a single transition.

import { signal, ViewTransitions } from "kiru"

const Counter = () => {
  const count = signal(0)

  const increment = () => {
    ViewTransitions.run(() => {
      count.value++
    })
  }

  return () => (
    <div>
      <button onclick={increment}>Increment</button>
      <p style={{ viewTransitionName: "count" }}>Count: {count}</p>
    </div>
  )
}

Options

  • signal (optional): An AbortSignal. If aborted before the transition starts, the job is removed from the queue. If aborted while running, the current transition is skipped via skipTransition().

Pass an AbortSignal to cancel a pending or in-progress transition. This is useful when triggering rapid navigation — abort the previous signal before issuing the next call so stale transitions never play.

import { signal, ViewTransitions } from "kiru"

type Image = { src: string; alt: string }

function ImageGallery({ images }: { images: Image[] }) {
  const current = signal(images[0])
  let controller = new AbortController()

  const navigate = (next: Image) => {
    controller.abort()
    controller = new AbortController()

    ViewTransitions.run(() => {
      current.value = next
    }, { signal: controller.signal })
  }

  return () => (
    <div>
      <img src={current.value.src} alt={current.value.alt} />
      <div>
        {images.map((img) => (
          <button onclick={() => navigate(img)}>{img.alt}</button>
        ))}
      </div>
    </div>
  )
}

ViewTransitions.stop() immediately skips the active transition, clears the entire job queue, and resets internal state. Use this when you need to tear down transitions entirely — for example, when unmounting a section of the UI.

ViewTransitions.stop()