Composables

useGsap()

Access the GSAP instance or create a scoped animation context with automatic cleanup.

useGsap() is auto-imported in every component and composable. It supports two call signatures.

Zero-argument form

Returns the raw gsap instance. Use this when you want full control and will manage cleanup manually.

components/AnimatedBox.vue
<script setup lang="ts">
const gsap = useGsap()
const boxRef = ref<HTMLElement | null>(null)

onMounted(() => {
  gsap.from(boxRef.value, { opacity: 0, scale: 0.8, duration: 0.5 })
})
</script>

<template>
  <div ref="boxRef" class="box">Hello!</div>
</template>

You can also use the auto-imported gsap global directly — both are equivalent.

Timeline example:

components/TimelineBox.vue
<script setup lang="ts">
const gsap = useGsap()
const boxRef = ref<HTMLElement | null>(null)

onMounted(() => {
  const tl = gsap.timeline({ repeat: -1, yoyo: true })
  tl.to(boxRef.value, { x: 200, duration: 1, ease: 'power2.inOut' })
    .to(boxRef.value, { rotation: 360, duration: 0.8 })
})
</script>

<template>
  <div ref="boxRef" class="box" />
</template>

Pass a setup function to wrap your animations in a gsap.context(). The context is automatically reverted when the component scope is disposed — no onUnmounted boilerplate.

components/ContextBox.vue
<script setup lang="ts">
const containerRef = ref<HTMLElement | null>(null)

useGsap(() => {
  gsap.from('.box', { opacity: 0, y: 30, duration: 0.6, ease: 'power2.out' })
}, { scope: containerRef })
</script>

<template>
  <div ref="containerRef">
    <div class="box">I animate in safely</div>
  </div>
</template>

Options

OptionTypeDefaultDescription
scopeRef<HTMLElement | null>undefinedScopes class/id selectors inside the element
dependenciesWatchSource[][]Re-run setup when any source changes
revertOnUpdatebooleantrueRevert the previous context before re-running

contextSafe

The setup callback receives a self reference to the GSAP context. contextSafe is returned so you can wrap event handlers that create animations after mount:

const { contextSafe } = useGsap((self) => {
  // initial animations
}, { scope: containerRef })

const handleClick = contextSafe(() => {
  gsap.to('.box', { rotation: '+=90' })
})

With reactive dependencies

const color = ref('red')

useGsap(() => {
  gsap.to('.box', { backgroundColor: color.value, duration: 0.3 })
}, { dependencies: [color] })

Every time color changes the context reverts and re-runs (controlled by revertOnUpdate).

Manual cleanup patterns

When using the zero-argument form, clean up in onUnmounted.

gsap.context() — covers all child tweens, timelines, and ScrollTriggers:

<script setup lang="ts">
const gsap = useGsap()
let ctx: gsap.Context

onMounted(() => {
  ctx = gsap.context(() => {
    gsap.to('.box', { x: 100 })
  })
})

onUnmounted(() => ctx.revert())
</script>

Single timeline:

const gsap = useGsap()
const tl = gsap.timeline()
onUnmounted(() => tl.kill())

Plugin instance (e.g. Draggable):

const Draggable = useDraggable()
let draggables: ReturnType<typeof Draggable.create> = []

onMounted(() => {
  draggables = Draggable.create(boxRef.value)
})

onUnmounted(() => {
  draggables.forEach(d => d.kill())
  draggables = []
})
Plugin registration is handled once by the module at app startup. In components, only kill the instances you created (tweens, timelines, Draggables, ScrollTriggers). Do not call gsap.registerPlugin() manually.
Copyright © 2026