1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="utf-8"/> 5 <title>nvie.com</title> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1"/> 7 <meta name="generator" content="iron"/> 8 <meta name="viewport" content="width=device-width,initial-scale=1"/> 9
9<script>(function(){var t=localStorage.getItem('theme');if(!t){t=matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light'}document.documentElement.setAttribute('data-theme',t)})();</script>
9 10 <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Crimson+Pro:400,700|Rubik:300|Inconsolata:400,700"/> 11 <link rel="stylesheet" type="text/css" href="/main.css"/> 12 <link href="/img/favicon.ico" rel="shortcut icon" type="image/x-icon"/> 13 <link rel="alternate" type="application/atom+xml" href="//feeds.feedburner.com/nvie"/> 14 <meta name="description" content="Thoughts and writings by Vincent Driessen."/> 15 <meta property="og:description" content="Thoughts and writings by Vincent Driessen."/> 16 <meta property="og:title" content="nvie.com"/> 17 <meta property="og:type" content="nvie:blog:home"/> 18 <meta property="og:image" content="https://nvie.com/og-img/og-default.png"/> 19 <meta property="og:site_name" content="nvie.com"/> 20 <meta property="og:locale" content="en_US"/> 21 22
23<script async src="https://plausible.io/js/pa-ozVw34azU4QvO9hTbW8a7.js"></script>
vendor: 1 bytes, line 23
23
24<script> 25 window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}}; 26 plausible.init() 27</script>
27 28 29 </head> 30 <body class="home"> 31 <div class="site-container"> 32 <div class="site-header"> 33 <nav> 34 <ul> 35 <li><a href="/">Home</a></li> 36 <li><a href="/posts/">Posts</a></li> 37 <li><a href="/projects/">Projects</a></li> 38 <li><a href="/about/">About</a></li> 39 <li><button id="sun-btn" type="button" aria-label="Toggle light mode" style="display:none;background:none;border:none;cursor:pointer;padding:0;color:var(--color-link-nav);vertical-align:middle"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></button><button id="moon-btn" type="button" aria-label="Toggle dark mode" style="display:none;background:none;border:none;cursor:pointer;padding:0;color:var(--color-link-nav);vertical-align:middle"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg></button></li> 40 </ul> 41 </nav> 42 43 <header> 44 <h1>nvie.com</h1> 45 46 <div class="tagline"> 47 Thoughts and writings by Vincent Driessen. 48 </div> 49 </header> 50 </div> 51 52 <article> 53 54 55 56 <div class="post-entry"> 57 <div class="post-detail"> 58 <h2> 59 <a href="https://liveblocks.io/blog/how-crdts-and-sync-engines-keep-realtime-lists-ordered-with-fractional-indexing?utm_source=nvie.com#regular-array-indexing" title="This blog post was published on liveblocks.io" target="_blank" rel="noopener">Fractional indexing techniques explained visually <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--color-text-secondary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg></a> 60 <span class="post-date">Apr 23, 2026</span> 61 </h2> 62 63 64 <div class="post-summary">An interactive guide to fractional indexing, and how itâs used in Liveblocks.</div> 65 66 </div> 67 </div> 68 69 70 71 <div class="post-entry"> 72 <div class="post-detail"> 73 <h2> 74 <a href="https://liveblocks.io/blog/introducing-zen-router-our-open-source-type-safe-router-compatible-with-cloudflare-workers?utm_source=nvie.com" title="This blog post was published on liveblocks.io" target="_blank" rel="noopener">Introducing Zen Router <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--color-text-secondary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg></a> 75 <span class="post-date">Feb 26, 2026</span> 76 </h2> 77 78 79 <div class="post-summary">An opinionated HTTP router with typed path params, built-in body validation, and a clean auth model.</div> 80 81 </div> 82 </div> 83 84 85 86 <div class="post-entry"> 87 <div class="post-detail"> 88 <h2> 89 <a href="https://liveblocks.io/blog/open-sourcing-the-liveblocks-sync-engine-and-dev-server?utm_source=nvie.com" title="This blog post was published on liveblocks.io" target="_blank" rel="noopener">Open sourcing the Liveblocks sync engine and dev server <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
89ox="0 0 24 24" fill="none" stroke="var(--color-text-secondary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg></a> 90 <span class="post-date">Feb 18, 2026</span> 91 </h2> 92 93 94 <div class="post-summary">We've open sourced most of our server stack. Now you can run and test your Liveblocks apps locally.</div> 95 96 </div> 97 </div> 98 99 100 101 <div class="post-entry"> 102 <div class="post-detail"> 103 <h2> 104 <a href="/posts/15-years-later/">15+ years later, Microsoft morged my diagram</a> 105 <span class="post-date">Feb 18, 2026</span> 106 </h2> 107 108 109 <div class="post-summary">How Microsoft continvoucly morged my Git branching diagram.</div> 110 111 </div> 112 </div> 113 114 115 116 <div class="post-entry"> 117 <div class="post-detail"> 118 <h2> 119 <a href="/posts/a-successful-git-branching-model/">A successful Git branching model</a> 120 <span class="post-date">Jan 5, 2010</span> 121 </h2> 122 123 124 <div class="post-summary">In this post I present a Git branching strategy for developing and releasing version-based software.</div> 125 126 </div> 127 </div> 128 129 130 131 <h2 class="readmore"> 132 <a href="/posts/">Read more posts »</a> 133 </h2> 134 135</article> 136 137</div> 138
138<script> 139 (function(){ 140 var sunBtn = document.getElementById('sun-btn'); 141 var moonBtn = document.getElementById('moon-btn'); 142 var mq = matchMedia('(prefers-color-scheme:dark)'); 143 144 function apply(){ 145 var stored = localStorage.getItem('theme'); 146 var theme = stored || (mq.matches ? 'dark' : 'light'); 147 document.documentElement.setAttribute('data-theme', theme); 148 // System mode: show opposite icon (offer to switch away) 149 // Forced mode: show matching icon (click goes back to system) 150 sunBtn.style.display = theme === 'dark' ? 'inline' : 'none'; 151 moonBtn.style.display = theme === 'dark' ? 'none' : 'inline'; 152 } 153 154 apply(); 155 156 mq.addEventListener('change', function(){ 157 if (!localStorage.getItem('theme')) apply(); 158 }); 159 160 // Sun: toggle between forced-light and system 161 sunBtn.addEventListener('click', function(){ 162 if (!mq.matches) { 163 localStorage.removeItem('theme'); 164 } else { 165 localStorage.setItem('theme', 'light'); 166 } 167 apply(); 168 }); 169 170 // Moon: toggle between forced-dark and system 171 moonBtn.addEventListener('click', function(){ 172 if (mq.matches) { 173 localStorage.removeItem('theme'); 174 } else { 175 localStorage.setItem('theme', 'dark'); 176 } 177 apply(); 178 }); 179 })(); 180 </script>
180 181 </body> 182</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.