Cansu Arı Logo
Blog
What is it?

Why Does nextTick() Exist and What Does It Really Do?

DOM updates in Vue aren’t applied instantly—they’re batched. nextTick() lets you hook into those async updates at the right moment.

  • #Vue.js

Skip to content

How does nextTick() work?

Vue’s reactivity is fast but not immediate. Yes, you usually see changes right away, but Vue actually processes updates in batches. That’s why sometimes your code runs before the DOM has caught up.

Enter Vue’s not-so-secret hero: nextTick().

Simple definition

The nextTick() function lets you run a callback after Vue has finished its next DOM update cycle. In other words: a shorthand for “let Vue update the DOM, then do this.”
import { nextTick, ref } from 'vue'

const show = ref(false)

function toggleModal() {
show.value = !show.value
nextTick(() => {
console.log('The DOM is now updated!')
})
}

When show.value changes, Vue updates the DOM in the next render tick, not immediately. If you try to measure the DOM right after (e.g., getBoundingClientRect()), you’ll read stale values. nextTick() prevents that.

Why does Vue defer DOM updates?

Vue batches reactive changes to avoid redundant renders. For example:
count.value++
message.value = 'Hello'
Both changes are applied in a single render pass. If Vue updated the DOM per line, things would slow down. nextTick() gives you a safe point: “after the batch is done.”

TL;DR: nextTick() = “See you after render.”

What actually happens?

Internally, Vue uses the Microtask Queue (e.g., Promise.resolve().then(...)). So a nextTick() callback is scheduled as the next microtask in the event loop.

It looks similar to setTimeout(fn, 0), but nextTick() timing is more precise for Vue’s updates.

nextTick(() => console.log('After microtask'))
setTimeout(() => console.log('After macrotask'))
console.log('Immediate log')
// Output:
// Immediate log
// After microtask
// After macrotask

This precision matters: nextTick() runs as soon as Vue finishes its DOM batch.

Real-world scenario

Triggering an animation:
<template>
<div ref="box" class="box"></div>
</template>

<script setup>
import { ref, nextTick } from 'vue'

const box = ref(null)
const visible = ref(false)

function animateBox() {
visible.value = true
nextTick(() => {
box.value.classList.add('fade-in')
})
}
</script>

<style>
.box { opacity: 0; transition: opacity .5s; }
.box.fade-in { opacity: 1; }
</style>
If you add the class immediately after toggling visible, the element might not be in the DOM yet. nextTick() waits and the animation starts cleanly.

When should you use nextTick()?

SituationWhy
You need DOM measurementsAccess the element’s real size/position
You will trigger an animationAdd classes after the element is in the DOM
You initialize third-party libs (Chart.js, maps)Init after the canvas/node actually exists
You scroll/focus after a dynamic list updateEnsure the target element is rendered first

await nextTick

In Vue 3, nextTick() returns a promise. You can await it instead of passing a callback:
show.value = true
await nextTick()
console.log('DOM updated—safe to measure!')
Great for async/await flows in setup.

Things to watch out for

  1. You don’t need nextTick() after every change—Vue already batches updates.
  2. nextTick() only waits for Vue’s reactive updates. External DOM changes (from non-Vue libs) may need their own waits.
  3. await nextTick() is meaningful within Vue’s lifecycle; outside of it, it may do nothing.

Vue lifecycle and nextTick

Often paired with onMounted/onUpdated:
onMounted(async () => {
await nextTick()
console.log('Component rendered!')
})
Run measurements or focus right after mount.

Conclusion

Vue defers DOM updates to optimize performance—that’s the secret sauce. Sometimes you need to wait for those updates. That’s nextTick()’s job.

In short:

  • nextTick() → “Let Vue finish the DOM, then continue.”
  • Microtask timing for ultra-precise scheduling
  • Perfect for measurements, animations, and third-party inits

Vue’s nextTick() is a blink-and-you-miss-it optimization—measured in milliseconds, not seconds.

All tags
  • Vue.js