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
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.
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
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.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 onefrom()does both
Flip it to false, or use something else, when
- A second or third
from()/fromTo()hits the same property, setimmediateRender: falseon 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 toimmediateRender: 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
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
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.See it running in production
Common questions
- Why does my gsap.from() apply its start values before it plays?
- Because
from()defaults toimmediateRender: 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, passimmediateRender: 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()orfromTo()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. SetimmediateRender: falseon 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()andfromTo()default totrue, so they set the start values on creation.to()defaults tofalse, so it does not touch the element until playback begins. That default split exists because afromtween is usually an entrance that needs to be parked at its start, while atotween 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 defaulttrueavoids. - 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: falsedefers the start state, but check first that you are not just seeing the intended pre-parking.
clamp, mapRange, random, snap, interpolate, wrap, and toArray, among others.Nextsnapsnap is a GSAP helper that rounds a value to the nearest step in an increment or the nearest entry in an array of allowed values.