How do Vue, Angular, and Svelte handle deep prop mutation re-rendering?
Deep reactivity vs zone-driven dirty checking.
Vue and Svelte detect nested mutations via Proxies; Angular default re-renders via Zone.js, but ngOnChanges misses it since the reference is unchanged.
What's really being asked
This question probes your understanding of how different reactivity models handle deep mutations. Vue and Svelte use proxy-based systems that observe nested property changes directly, while Angular relies on Zone.js to schedule top-down dirty checking cycles. The interviewer wants to see if you confuse reference equality with view updates, and whether you know which frameworks truly deep-watch props versus which ones brute-force re-evaluate templates.
The full answer
First, explain that Vue detects the change because its reactivity system recursively wraps objects in Proxies. When the parent mutates a nested property, the child's render effect is notified and the component updates precisely. Second, explain that Svelte with runes uses $state and Proxies for deep reactivity, so mutations like pushing to an array or setting a nested property automatically propagate to the child without requiring a new reference. Third, explain that Angular default change detection does not deep-watch objects; instead, Zone.js patches async APIs and triggers a full tree check after events. The child component will be visited and its template re-evaluated, so the UI does update, but ngOnChanges will not fire because the input binding reference is identical. Fourth, conclude that Angular is the framework that semantically fails to detect the deep mutation in its input lifecycle hooks, even though the default strategy ensures the view stays current.
The mistakes people make
A major red flag is claiming that Angular default change detection skips the child entirely. That is only true under OnPush. Another red flag is stating that Svelte requires immutable updates or that props are shallow by default; the canonical deep state tutorial explicitly shows Proxies enable deep reactivity. A third red flag is conflating Vue 2's Object.defineProperty limitations with Vue 3's Proxy behavior without clarifying which version you are discussing.
What usually comes next
The interviewer may ask how to force Angular to detect a deep change without switching to OnPush, which leads to ChangeDetectorRef.detectChanges or immutable data patterns. They may also ask how Vue's reactivity differs from React's explicit re-renders, or how Svelte compiled reactivity compares in bundle size and performance. Another follow-up is asking what happens if the parent mutates the object outside Angular's zone.
A concrete example
Imagine a parent holds let config = { theme: { color: 'blue' } } and passes it to a child. In Vue, parent.config.theme.color = 'red' triggers the child's watcher or template update immediately. In Svelte with let config = $state({ theme: { color: 'blue' } }), the same mutation is caught by the Proxy and the child re-renders. In Angular, if the parent mutates config.theme.color inside a click handler, Zone.js schedules change detection, traverses to the child, and re-evaluates the color expression in the template, but ngOnChanges receives no changes because the config object reference is the same.
Interview question
In Angular with default change detection, a parent mutates a nested property of an object passed to a child via @Input. What is the actual behavior?
- a.The child view does not update because Angular only checks reference equality by default.
- b.The child view updates and ngOnChanges fires because Zone.js recursively patches nested setters.
- c.The child view updates, but ngOnChanges does not fire because the input reference is unchanged.Correct
- d.The child view remains stale until the parent replaces the entire input object.
Why? this is the answer
Angular's default change detection triggers a full component tree check after events, so the child template re-evaluates and the view updates, but ngOnChanges is not invoked because the input object reference is still the same. Distractor A confuses default change detection with OnPush, which would indeed skip the update when the reference is unchanged.
Just read this? Test yourself on what you have been reading.
Read the original → svelte.dev
- #vue
- #angular
- #svelte
- #change-detection
- #reactivity
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on vue — each one lists the topics its interview covers.
See open roles