# Coming from vanilla JavaScript If you've been doing `document.querySelector` + `addEventListener` + manual DOM updates, Zoijs will feel familiar — it just removes the tedious "keep the DOM in sync" part. ## The shift | Vanilla | Zoijs | |---|---| | `el.textContent = value` everywhere | bind once: `${() => value.get()}` | | Manually re-set the DOM after every change | state changes update the DOM for you | | `addEventListener` by hand | `onclick=${fn}` in the template | | Track which DOM nodes need updating | Zoijs tracks it (fine-grained) | ## Before (vanilla) ```js let count = 0; const h1 = document.querySelector("h1"); const btn = document.querySelector("button"); btn.addEventListener("click", () => { count++; h1.textContent = count; // remember to update every place that shows count }); ``` ## After (Zoijs) ```js function Counter() { const count = createState(0); return html`