Core

immediateRender

immediateRender is a GSAP tween setting that controls whether a `from` or `fromTo` tween writes its starting values the moment the tween is created, or waits until playback begins. It defaults to `true` for `from()` and `fromTo()` and `false` for `to()`, which is why an entrance tween can park an element at `opacity: 0` on creation and never flash it visible first.

Updated July 1, 2026

Mechanics

How immediateRender works

When you create a from() or fromTo() tween, GSAP writes the start values into the element's inline style right away, before the next paint. That is immediateRender: true, the default for both. A to() tween defaults to false, so it leaves the element alone until the tween actually plays.

This is the reason a from() entrance does not flash. GSAP sets opacity: 0 at creation, the browser paints the hidden state on the very first frame, and then the tween animates up to the natural value. You do not need a separate gsap.set() to hide the element first, the from tween already did it.

script.js

The same applies with a delay. Because the start values render immediately, the element sits parked at opacity: 0 for the whole delay and only moves when the delay ends. That is usually what you want, but it surprises people who expect the delay to hold the element in its natural state.

Stacking from tweens on the same property

If two from() or fromTo() tweens target the same property of the same element, the second one's immediateRender overwrites the first's end state at creation, so the first tween looks like it never ran. Set immediateRender: false on the later tween(s) so it waits its turn.
When

Rely on the default (true) for

  • Entrance reveals, where the element must be parked hidden or offset on the first frame so it never flashes
  • Below-the-fold content driven by ScrollTrigger, where the start state should apply on creation and hold until the user scrolls to it
  • Staggered timelines, where every child needs its start state locked in before the sequence begins
  • Anything replacing a gsap.set() + gsap.to() pair, since one from() does both
Alternatives

Flip it to false, or use something else, when

  • A second or third from()/fromTo() hits the same property, set immediateRender: false on the later ones so they animate instead of getting clobbered
  • You genuinely want the element to stay in its natural painted state until the tween plays, then accept that it can flash from natural to start value on the first play frame
  • You only need a start state with no animation, use gsap.set() (a zero-duration tween that always renders immediately)
  • You are animating toward a target rather than from one, gsap.to() already defaults to immediateRender: false
  • In CSS, the equivalent of parking the start state during a delay is animation-fill-mode: backwards, which applies the first keyframe's styles before the animation starts
In production

Used in these Annnimate components

Every reveal in the Annnimate library leans on immediateRender. The reveal components build a paused fromTo timeline, and immediateRender: true is what parks each target at its hidden start state on mount, so the content is already invisible before the browser's first paint and there is no flash of the finished layout.

  • Element Reveal parks the element at its offset, clipped start state on creation via a fromTo, then plays it in on trigger
  • Mask Reveal locks the clip-path start value immediately so the masked content never shows through before the wipe runs
  • Text Reveal parks each split line below its mask at creation, so the lines are hidden on the first frame and slide up when the timeline plays

Why this matters more with a JS library

As of the HTTP Archive Web Almanac 2024, 91.7% of mobile pages use a CSS transition and only 18.4% load a JavaScript animation library. CSS handles the parking problem declaratively with animation-fill-mode: backwards. When you reach for GSAP instead, immediateRender is the setting doing that job, and forgetting it is a common cause of the entrance flash.
Used in components

See it running in production

FAQ

Common questions

Why does my gsap.from() apply its start values before it plays?
Because from() defaults to immediateRender: true. GSAP writes the start values into the element's inline style the instant the tween is created, before the first paint. That is deliberate, it is what stops entrance animations from flashing the finished state first. If you do not want that, pass immediateRender: false, but then the element paints in its natural state until the tween plays.
Why does my second from() tween not animate?
When two from() or fromTo() tweens target the same property of the same element, the second one renders its start value immediately on creation and overwrites the first tween's end state, so the first looks like it did nothing. Set immediateRender: false on the later tween so it holds off until it is its turn to play.
What's the difference in immediateRender between from and to?
from() and fromTo() default to true, so they set the start values on creation. to() defaults to false, so it does not touch the element until playback begins. That default split exists because a from tween is usually an entrance that needs to be parked at its start, while a to tween is usually animating away from wherever the element already is.
How do I stop a from tween from parking the element until it plays?
Pass immediateRender: false. The element then keeps its natural painted state until the tween starts, at which point it jumps to the start value and animates. The tradeoff is a possible one-frame flash from the natural state to the start value, which is exactly the flash the default true avoids.
Does immediateRender matter with ScrollTrigger?
Yes. A from() tween wired to a ScrollTrigger still renders its start value on creation by default, so a below-the-fold element is set to its hidden start state immediately and stays parked there until you scroll to it. That is what you want for scroll reveals. If it is parking something you did not expect, immediateRender: false defers the start state, but check first that you are not just seeing the intended pre-parking.