<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sahil Nasariwala</title>
    <description>The latest articles on DEV Community by Sahil Nasariwala (@sahilnasariwala).</description>
    <link>https://dev.to/sahilnasariwala</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4105529%2F9fb4b6da-ecd9-49ef-b2ad-a4ef21e62f5c.png</url>
      <title>DEV Community: Sahil Nasariwala</title>
      <link>https://dev.to/sahilnasariwala</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahilnasariwala"/>
    <language>en</language>
    <item>
      <title>I Built an Event Loop Visualizer Because the Best One Is From 2014</title>
      <dc:creator>Sahil Nasariwala</dc:creator>
      <pubDate>Wed, 02 Sep 2026 06:22:04 +0000</pubDate>
      <link>https://dev.to/sahilnasariwala/i-built-an-event-loop-visualizer-because-the-best-one-is-from-2014-1k95</link>
      <guid>https://dev.to/sahilnasariwala/i-built-an-event-loop-visualizer-because-the-best-one-is-from-2014-1k95</guid>
      <description>&lt;p&gt;Every JavaScript developer has seen this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promise&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// start → end → promise → timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of us know the answer.&lt;/p&gt;

&lt;p&gt;We know that microtasks run before the next task. We know &lt;code&gt;setTimeout(..., 0)&lt;/code&gt; doesn't actually mean "run this immediately." We know promises and the event loop are frequent interview topics.&lt;/p&gt;

&lt;p&gt;But then someone gives you a slightly uglier example and asks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Okay, what happens next?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And suddenly you're drawing boxes on a whiteboard.&lt;/p&gt;

&lt;p&gt;That's what made me build &lt;strong&gt;&lt;a href="https://event-loop-visualized.vercel.app/" rel="noopener noreferrer"&gt;The Event Loop, Visualized&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's an interactive course where you can actually watch the call stack, task queue, microtask queue, and Web APIs change step by step. You can slow it down, move backward, scrub through the timeline, and eventually paste in your own JavaScript and watch it get visualized.&lt;/p&gt;

&lt;h2&gt;
  
  
  But don't we already have event loop visualizers?
&lt;/h2&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;That's actually where this project started.&lt;/p&gt;

&lt;p&gt;Before writing any code, I spent some time looking at what already existed.&lt;/p&gt;

&lt;p&gt;The first one everyone knows is &lt;strong&gt;Loupe&lt;/strong&gt;, from 2014. It's still great, and Philip Roberts' "What the heck is the event loop anyway?" talk is one of the resources that made the event loop click for an entire generation of developers.&lt;/p&gt;

&lt;p&gt;But JavaScript has changed quite a bit since then.&lt;/p&gt;

&lt;p&gt;Promises weren't part of the picture in the same way. &lt;code&gt;async/await&lt;/code&gt; didn't exist. Microtasks weren't something most developers were thinking about.&lt;/p&gt;

&lt;p&gt;There are newer tools too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSV9000&lt;/strong&gt; does a good job of showing microtasks and letting you step through execution, but it assumes you already understand what you're looking at.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSFlow&lt;/strong&gt; supports promises and &lt;code&gt;async/await&lt;/code&gt;, but feels more like a playground than a course.&lt;/p&gt;

&lt;p&gt;And then there's Lydia Hallie's &lt;strong&gt;JavaScript Visualized&lt;/strong&gt; series, which is probably the best example of how much people enjoy learning JavaScript through animation. But they're still essentially videos/GIFs—you can't stop at a specific moment and ask, "Wait, why did this move here?"&lt;/p&gt;

&lt;p&gt;I kept noticing the same thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tools were either good at teaching or good at experimenting. Not both.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I decided to try combining the two.&lt;/p&gt;

&lt;p&gt;Not another diagram.&lt;/p&gt;

&lt;p&gt;Not another article explaining the event loop.&lt;/p&gt;

&lt;p&gt;Something you could actually play with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first thing I wanted to get right: different explanations, same animation
&lt;/h2&gt;

&lt;p&gt;One thing I didn't want to do was create a "beginner version" and an "advanced version" as completely separate experiences.&lt;/p&gt;

&lt;p&gt;Instead, every scene has three levels of explanation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Explain simply
&lt;/h3&gt;

&lt;p&gt;Think chef, kitchen, and VIP line.&lt;/p&gt;

&lt;p&gt;It's deliberately visual and avoids throwing terms like "microtask checkpoint" at someone who has never heard them before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer
&lt;/h3&gt;

&lt;p&gt;Now we talk about the actual things developers work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call stack&lt;/li&gt;
&lt;li&gt;Web APIs&lt;/li&gt;
&lt;li&gt;Task queue&lt;/li&gt;
&lt;li&gt;Microtask queue&lt;/li&gt;
&lt;li&gt;Promises&lt;/li&gt;
&lt;li&gt;Timers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Under the hood
&lt;/h3&gt;

&lt;p&gt;This is where the browser's actual behavior comes in: task sources, microtask checkpoints, rendering opportunities, and the HTML specification.&lt;/p&gt;

&lt;p&gt;The interesting part is that &lt;strong&gt;the animation doesn't change&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Only the explanation changes.&lt;/p&gt;

&lt;p&gt;That means a beginner and an experienced JavaScript developer can watch the exact same animation and just choose how deep they want to go.&lt;/p&gt;

&lt;p&gt;It also turned out to be a useful constraint while building the content. I couldn't accidentally create three slightly different versions of the same lesson.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture decision I liked the most
&lt;/h2&gt;

&lt;p&gt;This is probably the most interesting part of the project from an engineering perspective.&lt;/p&gt;

&lt;p&gt;My first thought was to instrument the browser.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalSetTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// record what happened&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;originalSetTimeout&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intercept timers.&lt;/p&gt;

&lt;p&gt;Watch promise callbacks.&lt;/p&gt;

&lt;p&gt;Track the call stack.&lt;/p&gt;

&lt;p&gt;Emit events as the browser actually executes them.&lt;/p&gt;

&lt;p&gt;It sounds reasonable.&lt;/p&gt;

&lt;p&gt;It's also a pain if you want an interactive visualizer.&lt;/p&gt;

&lt;p&gt;Because now you're trying to control the actual event loop.&lt;/p&gt;

&lt;p&gt;You can't simply say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pause the browser right here."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Actually, go back three steps."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's replay this at 0.5× speed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The browser isn't designed around those controls.&lt;/p&gt;

&lt;p&gt;So I stopped trying to record the real event loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I decided to record what the event loop should do instead.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A scene is just a script
&lt;/h2&gt;

&lt;p&gt;Instead of treating a scene as executable JavaScript, I represent it as a sequence of small actions.&lt;/p&gt;

&lt;p&gt;Something roughly like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1
→ highlight line 1
→ push "console.log" onto stack
→ print "start"

Step 2
→ register setTimeout
→ move callback to Web APIs

Step 3
→ create promise callback
→ add it to microtask queue

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visualizer doesn't care how the scene was created.&lt;/p&gt;

&lt;p&gt;It just receives the steps and renders them.&lt;/p&gt;

&lt;p&gt;The runtime state at any point can then be calculated from those steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;computeState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;stepIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;RuntimeState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;emptyState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;stepIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And suddenly a lot of features became almost trivial.&lt;/p&gt;

&lt;p&gt;Want to go backward?&lt;/p&gt;

&lt;p&gt;Recalculate the state at the previous step.&lt;/p&gt;

&lt;p&gt;Want to jump to step 7?&lt;/p&gt;

&lt;p&gt;Calculate step 7.&lt;/p&gt;

&lt;p&gt;Want to scrub from step 2 to step 9?&lt;/p&gt;

&lt;p&gt;Calculate step 9 and animate the difference.&lt;/p&gt;

&lt;p&gt;No undo stack.&lt;/p&gt;

&lt;p&gt;No complicated event-sourcing system.&lt;/p&gt;

&lt;p&gt;No snapshots.&lt;/p&gt;

&lt;p&gt;Most scenes only have around ten or so steps, so recalculating the state is basically free.&lt;/p&gt;

&lt;p&gt;That one architectural decision gave me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Play&lt;/li&gt;
&lt;li&gt;Pause&lt;/li&gt;
&lt;li&gt;Step forward&lt;/li&gt;
&lt;li&gt;Step backward&lt;/li&gt;
&lt;li&gt;Scrubbing&lt;/li&gt;
&lt;li&gt;Speed control&lt;/li&gt;
&lt;li&gt;Deep links to specific steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Then came the harder question: what about my own code?
&lt;/h2&gt;

&lt;p&gt;Hand-written scenes work really well for lessons.&lt;/p&gt;

&lt;p&gt;But eventually the obvious question appears:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Cool. But can I paste my code into it?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That was the whole point.&lt;/p&gt;

&lt;p&gt;So the playground uses &lt;strong&gt;Acorn&lt;/strong&gt; to parse the JavaScript into an AST and then compiles the supported code into the exact same step format used by the hand-written lessons.&lt;/p&gt;

&lt;p&gt;The visualizer doesn't know—or care—whether a scene came from a lesson or from the playground.&lt;/p&gt;

&lt;p&gt;It's just a sequence of steps.&lt;/p&gt;

&lt;p&gt;For now, the playground supports a deliberately limited subset:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;console.log&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Promise chains&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;queueMicrotask&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;async/await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Function calls&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's also an 80-step limit.&lt;/p&gt;

&lt;p&gt;I don't want someone pasting an accidental infinite loop into an educational animation and making the browser regret its life choices.&lt;/p&gt;

&lt;h3&gt;
  
  
  I also made a mistake here
&lt;/h3&gt;

&lt;p&gt;I didn't build the compiler first.&lt;/p&gt;

&lt;p&gt;I built the flagship scenes manually.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;promise-vs-setTimeout&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Microtask starvation&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async/await, unmasked&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After building enough of them, I started noticing the patterns.&lt;/p&gt;

&lt;p&gt;Only then did I build the compiler.&lt;/p&gt;

&lt;p&gt;That turned out to be a much better approach.&lt;/p&gt;

&lt;p&gt;If I'd started by designing the compiler, I would have designed an abstraction based on what I &lt;em&gt;thought&lt;/em&gt; a scene needed.&lt;/p&gt;

&lt;p&gt;After building the scenes, I knew what it actually needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some small things ended up making a big difference
&lt;/h2&gt;

&lt;p&gt;The event loop is the main feature, but a few other decisions made the project feel much more complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prediction mode
&lt;/h3&gt;

&lt;p&gt;Before showing the answer, the site asks you to predict the output.&lt;/p&gt;

&lt;p&gt;There's something useful about committing to an answer first.&lt;/p&gt;

&lt;p&gt;If you're wrong, you don't just see the correct output—you see exactly where your mental model diverged.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Break the loop"
&lt;/h3&gt;

&lt;p&gt;There's a small sandbox where you can intentionally block the main thread.&lt;/p&gt;

&lt;p&gt;You see an animation running normally.&lt;/p&gt;

&lt;p&gt;Then the blocking loop starts.&lt;/p&gt;

&lt;p&gt;And the animation freezes.&lt;/p&gt;

&lt;p&gt;It's much more memorable than reading:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Long-running JavaScript can block rendering."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You actually watch the UI stop responding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compare snippets
&lt;/h3&gt;

&lt;p&gt;You can run two to four snippets against each other and watch their behavior side by side.&lt;/p&gt;

&lt;p&gt;The benchmarks run inside a Web Worker so the comparison doesn't block the very event loop you're trying to understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Themes
&lt;/h3&gt;

&lt;p&gt;There are five themes inspired by tools like Monkeytype.&lt;/p&gt;

&lt;p&gt;The theme system uses CSS variables, and an inline pre-paint script prevents the page from flashing the wrong theme during startup.&lt;/p&gt;

&lt;p&gt;It's a tiny detail.&lt;/p&gt;

&lt;p&gt;But once you notice a flash like that, you can't unsee it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deep links
&lt;/h3&gt;

&lt;p&gt;You can link directly to a specific point in an animation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/play/promise-vs-settimeout?step=5&amp;amp;level=simply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So instead of telling someone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Go to the promise vs setTimeout example and move to step 5."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can just send them the exact moment.&lt;/p&gt;

&lt;p&gt;I also added keyboard controls and reduced-motion support along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd like to build next
&lt;/h2&gt;

&lt;p&gt;The obvious next step is &lt;strong&gt;Node.js's event loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Browser JavaScript and Node.js share the same language, but their event loop behavior has important differences.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Phases&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;process.nextTick&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;setImmediate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Timers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I want to put the browser and Node models next to each other and let people experiment with both.&lt;/p&gt;

&lt;p&gt;And because the visualizer is based on step scripts rather than browser instrumentation, the underlying architecture doesn't really care which event loop we're describing.&lt;/p&gt;

&lt;p&gt;That's probably my favorite thing about the project.&lt;/p&gt;

&lt;p&gt;What started as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I wish there was a better event loop visualizer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;turned into a small experiment in building interactive technical education.&lt;/p&gt;

&lt;p&gt;If you want to try it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://event-loop-visualized.vercel.app/" rel="noopener noreferrer"&gt;The Event Loop, Visualized&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And if you've ever written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as a fix and then quietly hoped nobody would ask you &lt;em&gt;why&lt;/em&gt; it worked...&lt;/p&gt;

&lt;p&gt;You might enjoy this project.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>learning</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
