<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="index, follow"><meta name="theme-color" content="#0a0a0a"><meta name="generator" content="Astro v5.16.6"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="canonical" href="https://andreabaccega.com/"><!-- RSS Feed Autodiscovery --><link rel="alternate" type="application/rss+xml" title="Andrea Baccega's Blog (English)" href="/rss.xml"><link rel="alternate" type="application/rss+xml" title="Blog di Andrea Baccega (Italiano)" href="/it/rss.xml"><!-- Hreflang tags for SEO --><!-- Primary Meta Tags --><title>Andrea Baccega</title><meta name="title" content="Andrea Baccega"><meta name="description" content="Andrea Baccega - Backend Developer specializing in TypeScript and Node.js. Based in Venice, Italy."><meta name="author" content="Andrea Baccega"><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:url" content="https://andreabaccega.com/"><meta property="og:title" content="Andrea Baccega"><meta property="og:description" content="Andrea Baccega - Backend Developer specializing in TypeScript and Node.js. Based in Venice, Italy."><meta property="og:image" content="https://andreabaccega.com/avatar.jpg"><meta property="og:site_name" content="Andrea Baccega"><meta property="og:locale" content="en_US"><!-- Twitter --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://andreabaccega.com/"><meta name="twitter:title" content="Andrea Baccega"><meta name="twitter:description" content="Andrea Baccega - Backend Developer specializing in TypeScript and Node.js. Based in Venice, Italy."><meta name="twitter:image" content="https://andreabaccega.com/avatar.jpg"><!-- Fonts --><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet"><!-- JSON-LD Person Schema --><script type="application/ld+json">{"@context":"https://schema.org","@type":"Person","name":"Andrea Baccega","url":"https://andreabaccega.com","jobTitle":"Backend Developer","worksFor":{"@type":"Organization","name":"D-EDGE"},"sameAs":["https://github.com/vekexasia","https://linkedin.com/in/andreabaccega"]}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"Andrea Baccega","url":"https://andreabaccega.com","description":"Andrea Baccega - Backend Developer specializing in TypeScript and Node.js. Based in Venice, Italy.","author":{"@type":"Person","name":"Andrea Baccega"}}</script><link rel="stylesheet" href="/_astro/index.BfrEa88Z.css">
<link rel="stylesheet" href="/_astro/_slug_.BMeBlF-T.css"></head> <body> <div class="chrome" data-astro-cid-3ef6ksr2> <div class="chrome-inner" data-astro-cid-3ef6ksr2> <div class="dots" aria-hidden="true" data-astro-cid-3ef6ksr2> <span class="dot r" data-astro-cid-3ef6ksr2></span> <span class="dot y" data-astro-cid-3ef6ksr2></span> <span class="dot g" data-astro-cid-3ef6ksr2></span> </div> <div class="pwd" data-astro-cid-3ef6ksr2> <b data-astro-cid-3ef6ksr2>~/andrea</b><span class="pwd-meta" data-astro-cid-3ef6ksr2> — bash — 80×24</span> </div> <div class="spacer" data-astro-cid-3ef6ksr2></div> <a class="cmd-link active" href="/" data-astro-cid-3ef6ksr2> <span class="fn" data-astro-cid-3ef6ksr2>home</span><span class="paren" data-astro-cid-3ef6ksr2>()</span> </a> <a class="cmd-link " href="/blog" data-astro-cid-3ef6ksr2> <span class="fn" data-astro-cid-3ef6ksr2>blog</span><span class="paren" data-astro-cid-3ef6ksr2>()</span> </a> <a class="cmd-link" href="https://github.com/vekexasia" target="_blank" rel="noopener noreferrer" data-astro-cid-3ef6ksr2> <span class="fn" data-astro-cid-3ef6ksr2>github</span><span class="paren" data-astro-cid-3ef6ksr2>()</span> </a> <button class="cmdk-btn" id="cmdk-btn" type="button" title="Command palette (⌘K)" data-astro-cid-3ef6ksr2> <span class="cmdk-key" data-astro-cid-3ef6ksr2>⌘K</span> <span class="cmdk-label" data-astro-cid-3ef6ksr2>command</span> </button> <button class="icon-btn" id="theme-btn" type="button" title="Toggle theme" aria-label="Toggle theme" data-astro-cid-3ef6ksr2> <span data-theme-icon data-astro-cid-3ef6ksr2>☼</span> </button> </div> </div> <script type="module">const n=document.documentElement,d=localStorage.getItem("theme");(d==="light"||d==="dark")&&n.setAttribute("data-theme",d);const o=()=>{const t=n.getAttribute("data-theme")||"dark";document.querySelectorAll("[data-theme-icon]").forEach(e=>{e.textContent=t==="dark"?"☼":"☾"})};o();document.getElementById("theme-btn")?.addEventListener("click",()=>{const e=(n.getAttribute("data-theme")||"dark")==="dark"?"light":"dark";n.setAttribute("data-theme",e),localStorage.setItem("theme",e),o()});document.getElementById("cmdk-btn")?.addEventListener("click",()=>{window.dispatchEvent(new CustomEvent("open-cmdk"))});window.addEventListener("keydown",t=>{(t.metaKey||t.ctrlKey)&&t.key.toLowerCase()==="k"&&(t.preventDefault(),window.dispatchEvent(new CustomEvent("open-cmdk")))});</script>  <main>  <section class="hero" data-astro-cid-bbe6dxrz> <div class="hero-inner" data-astro-cid-bbe6dxrz> <div class="eyebrow hero-eyebrow" data-astro-cid-bbe6dxrz>~/andrea — whoami</div> <div class="hero-grid" data-astro-cid-bbe6dxrz> <div class="hero-left" data-astro-cid-bbe6dxrz> <div class="hero-cmd" data-astro-cid-bbe6dxrz> <span class="prompt" data-astro-cid-bbe6dxrz></span>cat <span class="str" data-astro-cid-bbe6dxrz>about.md</span> </div> <h1 class="hero-title" data-astro-cid-bbe6dxrz> <span data-typing="Andrea Baccega" data-speed="45" data-on-done="t1" data-astro-cid-bbe6dxrz>Andrea Baccega</span><span class="cursor" data-cursor="t1" data-astro-cid-bbe6dxrz></span> </h1> <p class="hero-tagline" data-astro-cid-bbe6dxrz> <span data-typing="Building software that matters." data-speed="20" data-delay="800" data-after="t1" data-on-done="t2" data-astro-cid-bbe6dxrz>Building software that matters.</span><span class="cursor cursor-hidden" data-cursor="t2" data-astro-cid-bbe6dxrz></span> </p> <div class="hero-tags" data-reveal-after="t2" data-astro-cid-bbe6dxrz> <span class="tag" data-astro-cid-bbe6dxrz>senior backend</span> <span class="tag" data-astro-cid-bbe6dxrz>typescript · node.js</span> <span class="tag" data-astro-cid-bbe6dxrz>ai enthusiast</span> <span class="tag" data-astro-cid-bbe6dxrz>📍 venice, italy</span> </div> <div class="hero-ctas" data-reveal-after="t2" data-astro-cid-bbe6dxrz> <a class="btn primary" href="/blog" data-astro-cid-bbe6dxrz> <span class="hero-cta-arrow" data-astro-cid-bbe6dxrz>▸</span> read.blog()
</a> <a class="btn" href="https://github.com/vekexasia" target="_blank" rel="noopener noreferrer" data-astro-cid-bbe6dxrz> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-astro-cid-bbe6dxrz><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z" data-astro-cid-bbe6dxrz></path></svg>
github.com/vekexasia
</a> <a class="btn" href="https://linkedin.com/in/andreabaccega" target="_blank" rel="noopener noreferrer" data-astro-cid-bbe6dxrz>linkedin</a> <a class="btn email-link" href="#" data-a="YW5kcmVh" data-b="YmFjY2VnYS5pbw==" data-astro-cid-bbe6dxrz>~/contact</a> </div> </div> <div class="hero-avatar" data-astro-cid-bbe6dxrz> <div class="hero-avatar-frame" aria-hidden="true" data-astro-cid-bbe6dxrz></div> <img src="/avatar.jpg" alt="Andrea Baccega" class="hero-avatar-img" data-astro-cid-bbe6dxrz> <div class="hero-avatar-caption" data-astro-cid-bbe6dxrz>./avatar.jpg · 144×144</div> </div> </div> </div> <div class="container" data-astro-cid-bbe6dxrz> <div class="stats-panel" data-astro-cid-bbe6dxrz> <div class="stat" data-divider="true" data-astro-cid-bbe6dxrz> <div class="stat-num" data-astro-cid-bbe6dxrz>20+</div> <div class="stat-lbl" data-astro-cid-bbe6dxrz>years coding</div> </div><div class="stat" data-divider="true" data-astro-cid-bbe6dxrz> <div class="stat-num" data-astro-cid-bbe6dxrz>40+</div> <div class="stat-lbl" data-astro-cid-bbe6dxrz>android apps shipped</div> </div><div class="stat" data-divider="true" data-astro-cid-bbe6dxrz> <div class="stat-num" data-astro-cid-bbe6dxrz>1.7k</div> <div class="stat-lbl" data-astro-cid-bbe6dxrz>github stars</div> </div><div class="stat" data-divider="false" data-astro-cid-bbe6dxrz> <div class="stat-num" data-astro-cid-bbe6dxrz>600k</div> <div class="stat-lbl" data-astro-cid-bbe6dxrz>community members run</div> </div> </div> </div> </section> <script type="module">document.querySelectorAll(".email-link").forEach(t=>{t.addEventListener("click",async e=>{e.preventDefault();const r=atob(t.dataset.a||""),c=atob(t.dataset.b||""),a=`${r}@${c}`,o=t.innerHTML;try{await navigator.clipboard.writeText(a),t.textContent="copied!",setTimeout(()=>{t.innerHTML=o},2e3)}catch{window.location.href=`mailto:${a}`}})});function i(t){document.querySelectorAll(`[data-cursor="${t}"]`).forEach(e=>{e.classList.add("cursor-hidden")}),document.querySelectorAll(`[data-reveal-after="${t}"]`).forEach(e=>{e.classList.add("revealed")}),document.querySelectorAll(`[data-after="${t}"]`).forEach(e=>{n(e)})}function n(t){if(t.dataset.started==="1")return;t.dataset.started="1";const e=t.dataset.typing||"",r=Number(t.dataset.speed||28),c=Number(t.dataset.delay||0),a=t.dataset.onDone;a&&document.querySelectorAll(`[data-cursor="${a}"]`).forEach(o=>{o.classList.remove("cursor-hidden")}),t.textContent="",setTimeout(()=>{let o=0;const s=()=>{o++,t.textContent=e.slice(0,o),o<e.length?setTimeout(s,r+Math.random()*30):a&&i(a)};setTimeout(s,r)},c)}document.querySelectorAll("[data-typing]").forEach(t=>{t.dataset.after||n(t)});</script>  <section class="cmd-tip-section" data-astro-cid-j7pv25f6> <div class="container" data-astro-cid-j7pv25f6> <div class="cmd-tip" data-astro-cid-j7pv25f6> <span class="cmd-tip-label" data-astro-cid-j7pv25f6>$ tip</span> <span data-astro-cid-j7pv25f6><kbd data-astro-cid-j7pv25f6>⌘</kbd><kbd data-astro-cid-j7pv25f6>K</kbd> opens command palette</span> <span class="cmd-tip-sep" data-astro-cid-j7pv25f6>·</span> <span data-astro-cid-j7pv25f6><kbd data-astro-cid-j7pv25f6>?</kbd> help</span> <span class="cmd-tip-sep" data-astro-cid-j7pv25f6>·</span> <span class="cmd-tip-examples" data-astro-cid-j7pv25f6> <code class="cmd-tip-example" data-example="ls blog/" data-astro-cid-j7pv25f6>ls blog/</code><code class="cmd-tip-example" data-example="cat latest.md" data-astro-cid-j7pv25f6>cat latest.md</code><code class="cmd-tip-example" data-example="theme light" data-astro-cid-j7pv25f6>theme light</code><code class="cmd-tip-example" data-example="whoami" data-astro-cid-j7pv25f6>whoami</code> </span> </div> </div> </section> <section class="about" data-astro-cid-v2cbyr3p> <div class="container" data-astro-cid-v2cbyr3p> <div class="eyebrow about-eyebrow" data-astro-cid-v2cbyr3p>about — readme.md</div> <div class="about-grid" data-astro-cid-v2cbyr3p> <div class="about-prose" data-astro-cid-v2cbyr3p> <p data-astro-cid-v2cbyr3p>
I'm a senior backend developer at
<a href="https://www.d-edge.com" target="_blank" rel="noopener noreferrer" data-astro-cid-v2cbyr3p>D-EDGE</a>
and an entrepreneur. I specialize in <strong data-astro-cid-v2cbyr3p>TypeScript</strong> and <strong data-astro-cid-v2cbyr3p>Node.js</strong>,
          building efficient, scalable solutions with a rational approach to problem-solving.
</p> <p data-astro-cid-v2cbyr3p>
My journey started at 15 with C, moved to PHP at 17, and in 2008 I co-founded
          Androidiani.com with
<a href="https://sebastianomontino.com" target="_blank" rel="noopener noreferrer" data-astro-cid-v2cbyr3p>Sebastiano Montino</a>
— Italy's leading Android community with <strong data-astro-cid-v2cbyr3p>600k+ registered users</strong>,
          which we ran until its closure in December 2025.
</p> <p data-astro-cid-v2cbyr3p>
Beyond software, I'm passionate about bridging the digital and physical worlds.
          I spend my free time 3D printing, designing PCBs, and building hardware projects
          that bring code to life.
</p> </div> <aside class="about-aside" data-astro-cid-v2cbyr3p> <div class="eyebrow" data-astro-cid-v2cbyr3p>currently()</div> <div class="currently" data-astro-cid-v2cbyr3p> <div data-astro-cid-v2cbyr3p><span class="cmt" data-astro-cid-v2cbyr3p>// work</span></div> <div data-astro-cid-v2cbyr3p>building <span class="str" data-astro-cid-v2cbyr3p>"ai tools"</span></div> <div class="currently-spacer" data-astro-cid-v2cbyr3p><span class="cmt" data-astro-cid-v2cbyr3p>// hardware</span></div> <div data-astro-cid-v2cbyr3p>iterating <span class="str" data-astro-cid-v2cbyr3p>"eNSPanel v3"</span></div> <div class="currently-spacer" data-astro-cid-v2cbyr3p><span class="cmt" data-astro-cid-v2cbyr3p>// reading</span></div> <div data-astro-cid-v2cbyr3p><span class="str" data-astro-cid-v2cbyr3p>"designing data-intensive applications"</span></div> <div class="currently-spacer" data-astro-cid-v2cbyr3p><span class="cmt" data-astro-cid-v2cbyr3p>// typing on</span></div> <div data-astro-cid-v2cbyr3p>temper · miryoku · zmk</div> </div> </aside> </div> </div> </section>  <section class="projects" data-astro-cid-2wkm2a2e> <div class="container" data-astro-cid-2wkm2a2e> <div class="projects-head" data-astro-cid-2wkm2a2e> <div data-astro-cid-2wkm2a2e> <div class="eyebrow" data-astro-cid-2wkm2a2e>open source — gh.repos()</div> <h2 class="projects-title" data-astro-cid-2wkm2a2e>Things I've built</h2> </div> <a class="projects-viewall" href="https://github.com/vekexasia" target="_blank" rel="noopener noreferrer" data-astro-cid-2wkm2a2e>view all on github →</a> </div> <div class="projects-grid" data-astro-cid-2wkm2a2e> <a href="https://github.com/vekexasia/android-edittext-validator" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>android-edittext-validator</span> </div> <p class="project-description" data-astro-cid-mspuyifq>Android form edit text is an extension of EditText that brings data validation facilities to the edittext.</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #b07219" data-astro-cid-mspuyifq></span> Java </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>1,400</span> </div> </a> <a href="https://github.com/vekexasia/comfoair-esp32" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>comfoair-esp32</span> </div> <p class="project-description" data-astro-cid-mspuyifq>Zehnder Comfoair integration for ESP32 devices</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #f34b7d" data-astro-cid-mspuyifq></span> C++ </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>140</span> </div> </a> <a href="https://github.com/vekexasia/mysqldumpsplit" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>mysqldumpsplit</span> </div> <p class="project-description" data-astro-cid-mspuyifq>MySQL dump file splitter optimized for speed and memory efficiency</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #f1e05a" data-astro-cid-mspuyifq></span> JavaScript </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>55</span> </div> </a> <a href="https://github.com/vekexasia/nodes2-ts" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>nodes2-ts</span> </div> <p class="project-description" data-astro-cid-mspuyifq>A TypeScript porting of the great S2 Geometry library from Google</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #3178c6" data-astro-cid-mspuyifq></span> TypeScript </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>46</span> </div> </a> <a href="https://github.com/vekexasia/lpc_voltage_glitch_test" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>lpc_voltage_glitch_test</span> </div> <p class="project-description" data-astro-cid-mspuyifq>Voltage-glitching experiments on the LPC1768 Cortex-M3, a hardware fault-injection test bed.</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #555555" data-astro-cid-mspuyifq></span> C </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>5</span> </div> </a> <a href="https://github.com/vekexasia/bigint-swissknife" class="project-card cardlink" target="_blank" rel="noopener noreferrer" data-astro-cid-mspuyifq> <div class="project-head" data-astro-cid-mspuyifq> <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="project-icon" data-astro-cid-mspuyifq><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.69 1.72.75.75 0 0 1-1.06 1.06A2.5 2.5 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8z" data-astro-cid-mspuyifq></path></svg> <span class="project-name" data-astro-cid-mspuyifq>bigint-swissknife</span> </div> <p class="project-description" data-astro-cid-mspuyifq>Node.JS bigint swissknife with math utils, buffer conversion, and more</p> <div class="project-meta" data-astro-cid-mspuyifq> <span class="language" data-astro-cid-mspuyifq> <span class="language-dot" style="background-color: #3178c6" data-astro-cid-mspuyifq></span> TypeScript </span> <span class="stars" data-astro-cid-mspuyifq><span class="star" data-astro-cid-mspuyifq>★</span>3</span> </div> </a>  </div> </div> </section>  <section class="recent-posts" data-astro-cid-j7pv25f6> <div class="container" data-astro-cid-j7pv25f6> <div class="recent-head" data-astro-cid-j7pv25f6> <div data-astro-cid-j7pv25f6> <div class="eyebrow" data-astro-cid-j7pv25f6>writing — ls -la blog/</div> <h2 class="recent-title" data-astro-cid-j7pv25f6>Recent posts</h2> </div> <a class="recent-viewall" href="/blog" data-astro-cid-j7pv25f6>view all →</a> </div> <div class="recent-grid" data-astro-cid-j7pv25f6> <a href="/blog/opus-vs-askelectronics" class="blog-card cardlink" data-astro-cid-f45vxlzk> <div class="blog-thumbnail" data-astro-cid-f45vxlzk> <img src="/blog/enspanel-thermal-poster.jpg" alt="Opus vs r/AskElectronics: 1-0 for the humans" loading="lazy" data-astro-cid-f45vxlzk> <div class="blog-date-badge" data-astro-cid-f45vxlzk>May 4 · 2026</div> </div> <div class="blog-content" data-astro-cid-f45vxlzk> <h3 class="blog-title" data-astro-cid-f45vxlzk>Opus vs r/AskElectronics: 1-0 for the humans</h3> <p class="blog-description" data-astro-cid-f45vxlzk>I spent a day taking orders from a frontier LLM to debug a thermal problem on my eNSPanel PCB. Then a stranger on Reddit fixed it with one question.</p> </div> </a> <a href="/blog/text-is-the-new-binary" class="blog-card cardlink" data-astro-cid-f45vxlzk> <div class="blog-thumbnail" data-astro-cid-f45vxlzk> <img src="/blog/text-is-the-new-binary-hero.jpg" alt="Text is the New Binary" loading="lazy" data-astro-cid-f45vxlzk> <div class="blog-date-badge" data-astro-cid-f45vxlzk>Apr 27 · 2026</div> </div> <div class="blog-content" data-astro-cid-f45vxlzk> <h3 class="blog-title" data-astro-cid-f45vxlzk>Text is the New Binary</h3> <p class="blog-description" data-astro-cid-f45vxlzk>Software increasingly ships as prose meant to be interpreted by someone else&#39;s LLM. From Karpathy&#39;s wiki gist to gh skill install, even installation is now a paragraph. The same critique that pushes Karpathy beyond RAG hints at where the dust will eventually settle.</p> </div> </a> <a href="/blog/why-i-switched-to-a-split-keyboard" class="blog-card cardlink" data-astro-cid-f45vxlzk> <div class="blog-thumbnail" data-astro-cid-f45vxlzk> <img src="/blog/split-kb-cover.jpg" alt="Why I Switched to a Split Keyboard (and Why You Should Too)" loading="lazy" data-astro-cid-f45vxlzk> <div class="blog-date-badge" data-astro-cid-f45vxlzk>Jan 29 · 2026</div> </div> <div class="blog-content" data-astro-cid-f45vxlzk> <h3 class="blog-title" data-astro-cid-f45vxlzk>Why I Switched to a Split Keyboard (and Why You Should Too)</h3> <p class="blog-description" data-astro-cid-f45vxlzk>From QWERTY&#39;s historical accident to the Temper split keyboard — my journey into ergonomic typing, the surprising history of keyboard layouts, and a practical guide to making the switch.</p> </div> </a>  </div> <div class="ls-list" data-astro-cid-j7pv25f6> <div class="ls-list-header" data-astro-cid-j7pv25f6> <span data-astro-cid-j7pv25f6><span class="prompt" data-astro-cid-j7pv25f6></span>ls -la blog/ <span class="ls-list-flags" data-astro-cid-j7pv25f6>--sort=time -r | tail -n +4 | head -8</span></span> <span class="ls-list-spacer" data-astro-cid-j7pv25f6></span> <span data-astro-cid-j7pv25f6>17 entries total</span> </div> <div class="ls-list-body" data-astro-cid-j7pv25f6> <a href="/blog/ai-solved-my-toddler-sleep-issues" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>8min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Jan 10 '26</span> <span class="ls-name" data-astro-cid-j7pv25f6>ai-solved-my-toddler-sleep-issues.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#claude-code #sleep-deprivation</span> </a><a href="/blog/enspanel-custom-nspanel-pcb" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>3min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Jan 4 '26</span> <span class="ls-name" data-astro-cid-j7pv25f6>enspanel-custom-nspanel-pcb.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#hardware #esp32</span> </a><a href="/blog/android-navigationview-footer" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>1min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Aug 28 '15</span> <span class="ls-name" data-astro-cid-j7pv25f6>android-navigationview-footer.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#android #java</span> </a><a href="/blog/android-fragment-overlap" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>1min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Aug 16 '15</span> <span class="ls-name" data-astro-cid-j7pv25f6>android-fragment-overlap.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#android #java</span> </a><a href="/blog/android-device-detection" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>1min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Aug 24 '12</span> <span class="ls-name" data-astro-cid-j7pv25f6>android-device-detection.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#android #java</span> </a><a href="/blog/android-edittext-validation" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>1min</span> <span class="ls-date" data-astro-cid-j7pv25f6>May 26 '12</span> <span class="ls-name" data-astro-cid-j7pv25f6>android-edittext-validation.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#android #java</span> </a><a href="/blog/flatterizor-php-library" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>1min</span> <span class="ls-date" data-astro-cid-j7pv25f6>May 9 '12</span> <span class="ls-name" data-astro-cid-j7pv25f6>flatterizor-php-library.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#php #database</span> </a><a href="/blog/server-backup-rsnapshot" class="ls-row" data-astro-cid-j7pv25f6> <span class="ls-perm" data-astro-cid-j7pv25f6>-rw-r--r--</span> <span class="ls-min" data-astro-cid-j7pv25f6>2min</span> <span class="ls-date" data-astro-cid-j7pv25f6>Apr 23 '12</span> <span class="ls-name" data-astro-cid-j7pv25f6>server-backup-rsnapshot.md</span> <span class="ls-tags" data-astro-cid-j7pv25f6>#devops #linux</span> </a> <a href="/blog" class="ls-cd" data-astro-cid-j7pv25f6> <span class="prompt" data-astro-cid-j7pv25f6></span>cd blog &amp;&amp; ls
<span class="ls-cd-result" data-astro-cid-j7pv25f6> → 6 more entries in archive</span> </a> </div> </div> </div> </section> </main> <footer class="footer" data-astro-cid-sz7xmlte> <div class="footer-inner" data-astro-cid-sz7xmlte> <span class="footer-echo" data-astro-cid-sz7xmlte> <span class="prompt" data-astro-cid-sz7xmlte></span>echo <span class="str" data-astro-cid-sz7xmlte>"thanks for visiting"</span> </span> <span class="footer-spacer" data-astro-cid-sz7xmlte></span> <span class="footer-copy" data-astro-cid-sz7xmlte>© 2026 Andrea Baccega</span> <span class="footer-sep" data-astro-cid-sz7xmlte>·</span> <a class="footer-link" href="https://github.com/vekexasia" target="_blank" rel="noopener noreferrer" data-astro-cid-sz7xmlte>github</a> <a class="footer-link" href="https://linkedin.com/in/andreabaccega" target="_blank" rel="noopener noreferrer" data-astro-cid-sz7xmlte>linkedin</a> <a class="footer-link" href="/rss.xml" data-astro-cid-sz7xmlte>rss</a> </div> </footer>  <div class="cmdk" id="cmdk" hidden> <div class="cmdk-overlay" data-cmdk-close></div> <div class="cmdk-panel" role="dialog" aria-modal="true" aria-label="Command palette"> <div class="cmdk-input-row"> <span class="cmdk-prompt">~/andrea $</span> <input type="text" class="cmdk-input" id="cmdk-input" placeholder="type a command or post…" autocomplete="off" spellcheck="false"> <span class="cmdk-esc">ESC</span> </div> <div class="cmdk-results" id="cmdk-results"></div> <div class="cmdk-footer"> <span><span class="cmdk-key">↑↓</span> nav</span> <span><span class="cmdk-key">↵</span> run</span> <span><span class="cmdk-key">esc</span> close</span> <span class="cmdk-count" id="cmdk-count"></span> </div> </div> </div> <script>(function(){const postCommands = [{"id":"post-opus-vs-askelectronics","label":"cat opus-vs-askelectronics.md","desc":"Opus vs r/AskElectronics: 1-0 for the humans","kind":"post","href":"/blog/opus-vs-askelectronics"},{"id":"post-text-is-the-new-binary","label":"cat text-is-the-new-binary.md","desc":"Text is the New Binary","kind":"post","href":"/blog/text-is-the-new-binary"},{"id":"post-why-i-switched-to-a-split-keyboard","label":"cat why-i-switched-to-a-split-keyboard.md","desc":"Why I Switched to a Split Keyboard (and Why You Should Too)","kind":"post","href":"/blog/why-i-switched-to-a-split-keyboard"},{"id":"post-ai-solved-my-toddler-sleep-issues","label":"cat ai-solved-my-toddler-sleep-issues.md","desc":"AI (almost) solved my toddler sleep issues","kind":"post","href":"/blog/ai-solved-my-toddler-sleep-issues"},{"id":"post-enspanel-custom-nspanel-pcb","label":"cat enspanel-custom-nspanel-pcb.md","desc":"eNSPanel: Building a Better Smart Home Touch Panel","kind":"post","href":"/blog/enspanel-custom-nspanel-pcb"},{"id":"post-android-navigationview-footer","label":"cat android-navigationview-footer.md","desc":"Adding a Footer to NavigationView in Android","kind":"post","href":"/blog/android-navigationview-footer"},{"id":"post-android-fragment-overlap","label":"cat android-fragment-overlap.md","desc":"Fixing Fragment Overlap in Android's Back Stack","kind":"post","href":"/blog/android-fragment-overlap"},{"id":"post-android-device-detection","label":"cat android-device-detection.md","desc":"Detecting Phones, Tablets, and Google TV in Android","kind":"post","href":"/blog/android-device-detection"},{"id":"post-android-edittext-validation","label":"cat android-edittext-validation.md","desc":"Android Form Validation with FormEditText","kind":"post","href":"/blog/android-edittext-validation"},{"id":"post-flatterizor-php-library","label":"cat flatterizor-php-library.md","desc":"Introducing Flatterizor: Storing Complex Objects in Databases","kind":"post","href":"/blog/flatterizor-php-library"},{"id":"post-server-backup-rsnapshot","label":"cat server-backup-rsnapshot.md","desc":"How to Backup Your Web Server with rsnapshot, rsync, and SSH","kind":"post","href":"/blog/server-backup-rsnapshot"},{"id":"post-android-first-launch-code","label":"cat android-first-launch-code.md","desc":"Execute Code Only on First App Launch in Android","kind":"post","href":"/blog/android-first-launch-code"},{"id":"post-password-reset-pattern","label":"cat password-reset-pattern.md","desc":"Password Reset: A Modern Design Pattern","kind":"post","href":"/blog/password-reset-pattern"},{"id":"post-xss-prevention-php","label":"cat xss-prevention-php.md","desc":"Preventing XSS While Allowing Some HTML Tags in PHP","kind":"post","href":"/blog/xss-prevention-php"},{"id":"post-android-edittext-onchange","label":"cat android-edittext-onchange.md","desc":"Handling onChange Events on EditText in Android","kind":"post","href":"/blog/android-edittext-onchange"},{"id":"post-android-ssl-certificates","label":"cat android-ssl-certificates.md","desc":"Android Root Certificate Authorities List","kind":"post","href":"/blog/android-ssl-certificates"},{"id":"post-android-google-calendar-events","label":"cat android-google-calendar-events.md","desc":"Adding Events to Google Calendar on Android","kind":"post","href":"/blog/android-google-calendar-events"}];

  (function () {
    const root = document.getElementById('cmdk');
    if (!root) return;
    const input = document.getElementById('cmdk-input');
    const results = document.getElementById('cmdk-results');
    const count = document.getElementById('cmdk-count');

    const baseCmds = [
      { id: 'home', label: 'cd ~', desc: 'go home', kind: 'nav', run: () => (window.location.href = '/') },
      { id: 'blog', label: 'ls blog/', desc: 'view all posts', kind: 'nav', run: () => (window.location.href = '/blog') },
      { id: 'it-blog', label: 'cd it/blog', desc: 'leggi in italiano', kind: 'nav', run: () => (window.location.href = '/it/blog') },
      {
        id: 'theme-d',
        label: 'theme dark',
        desc: 'switch to dark mode',
        kind: 'cmd',
        run: () => {
          document.documentElement.setAttribute('data-theme', 'dark');
          localStorage.setItem('theme', 'dark');
          document.querySelectorAll('[data-theme-icon]').forEach((el) => (el.textContent = '☼'));
        },
      },
      {
        id: 'theme-l',
        label: 'theme light',
        desc: 'switch to light mode',
        kind: 'cmd',
        run: () => {
          document.documentElement.setAttribute('data-theme', 'light');
          localStorage.setItem('theme', 'light');
          document.querySelectorAll('[data-theme-icon]').forEach((el) => (el.textContent = '☾'));
        },
      },
      { id: 'gh', label: 'open github', desc: 'github.com/vekexasia', kind: 'ext', run: () => window.open('https://github.com/vekexasia', '_blank') },
      { id: 'li', label: 'open linkedin', desc: 'linkedin.com/in/andreabaccega', kind: 'ext', run: () => window.open('https://linkedin.com/in/andreabaccega', '_blank') },
      { id: 'rss', label: 'subscribe rss', desc: 'feed.xml', kind: 'ext', run: () => (window.location.href = '/rss.xml') },
      { id: 'whoami', label: 'whoami', desc: 'about Andrea', kind: 'cmd', run: () => (window.location.href = '/') },
    ];

    const postCmds = (postCommands || []).map((p) => ({
      ...p,
      run: () => (window.location.href = p.href),
    }));

    // Share commands: only available when on a single blog post page.
    const onBlogPost = /^\/(it\/)?blog\/[^/]+\/?$/.test(window.location.pathname);
    const postUrl = window.location.href;
    const rawTitle = document.title.replace(/\s*\|\s*Andrea Baccega\s*$/, '');
    const enc = encodeURIComponent;

    const shareCmds = onBlogPost
      ? [
          {
            id: 'share-x',
            label: 'share x',
            desc: 'post on X (tags @andrea_baccega)',
            kind: 'share',
            run: () =>
              window.open(
                `https://twitter.com/intent/tweet?text=${enc(rawTitle)}&url=${enc(postUrl)}&via=andrea_baccega`,
                '_blank'
              ),
          },
          {
            id: 'share-li',
            label: 'share linkedin',
            desc: 'share on LinkedIn',
            kind: 'share',
            run: () =>
              window.open(
                `https://www.linkedin.com/sharing/share-offsite/?url=${enc(postUrl)}`,
                '_blank'
              ),
          },
          {
            id: 'share-hn',
            label: 'share hn',
            desc: 'submit to Hacker News',
            kind: 'share',
            run: () =>
              window.open(
                `https://news.ycombinator.com/submitlink?u=${enc(postUrl)}&t=${enc(rawTitle)}`,
                '_blank'
              ),
          },
          {
            id: 'share-copy',
            label: 'cp link',
            desc: 'copy post URL to clipboard',
            kind: 'share',
            run: async () => {
              try {
                await navigator.clipboard.writeText(postUrl);
              } catch {
                /* noop */
              }
            },
          },
        ]
      : [];

    const all = [...baseCmds, ...shareCmds, ...postCmds];

    let filtered = all;
    let highlighted = 0;
    let isOpen = false;

    const kindColor = { nav: 'var(--color-accent)', cmd: 'var(--color-accent-2)', ext: 'var(--color-accent-3)', share: 'var(--color-accent-4)', post: 'var(--color-text-dim)' };

    function render() {
      if (filtered.length === 0) {
        results.innerHTML = `<div class="cmdk-empty">command not found: <span class="cmdk-empty-q">${escapeHtml(input.value)}</span></div>`;
        count.textContent = '0 commands';
        return;
      }
      results.innerHTML = filtered
        .map(
          (c, i) => `
        <div class="cmdk-row${i === highlighted ? ' is-active' : ''}" data-i="${i}">
          <span class="cmdk-kind" style="color:${kindColor[c.kind] || 'var(--color-text-mute)'}">${c.kind}</span>
          <span class="cmdk-label">${escapeHtml(c.label)}</span>
          <span class="cmdk-desc">${escapeHtml(c.desc)}</span>
        </div>`
        )
        .join('');
      count.textContent = `${filtered.length} command${filtered.length === 1 ? '' : 's'}`;
    }

    function escapeHtml(s) {
      return String(s).replace(/[&<>"']/g, (m) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[m]));
    }

    function search(q) {
      const needle = q.trim().toLowerCase();
      filtered = needle ? all.filter((c) => (c.label + ' ' + c.desc).toLowerCase().includes(needle)) : all;
      highlighted = 0;
      render();
    }

    function open(prefill) {
      isOpen = true;
      root.removeAttribute('hidden');
      requestAnimationFrame(() => {
        input.value = prefill || '';
        search(input.value);
        input.focus();
        input.select();
      });
    }

    function close() {
      isOpen = false;
      root.setAttribute('hidden', '');
    }

    function exec(i) {
      const c = filtered[i];
      if (!c) return;
      close();
      c.run();
    }

    input.addEventListener('input', () => search(input.value));
    input.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        highlighted = Math.min(filtered.length - 1, highlighted + 1);
        render();
        scrollHighlightIntoView();
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        highlighted = Math.max(0, highlighted - 1);
        render();
        scrollHighlightIntoView();
      } else if (e.key === 'Enter') {
        e.preventDefault();
        exec(highlighted);
      } else if (e.key === 'Escape') {
        e.preventDefault();
        close();
      }
    });

    function scrollHighlightIntoView() {
      const el = results.querySelector('.cmdk-row.is-active');
      if (el) el.scrollIntoView({ block: 'nearest' });
    }

    results.addEventListener('mousemove', (e) => {
      const row = e.target.closest('.cmdk-row');
      if (!row) return;
      const i = Number(row.dataset.i);
      if (i !== highlighted) {
        highlighted = i;
        render();
      }
    });
    results.addEventListener('click', (e) => {
      const row = e.target.closest('.cmdk-row');
      if (!row) return;
      exec(Number(row.dataset.i));
    });

    document.querySelectorAll('[data-cmdk-close]').forEach((el) => el.addEventListener('click', close));

    window.addEventListener('keydown', (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        isOpen ? close() : open();
      } else if (
        e.key === '?' &&
        !isOpen &&
        document.activeElement?.tagName !== 'INPUT' &&
        document.activeElement?.tagName !== 'TEXTAREA'
      ) {
        e.preventDefault();
        open();
      }
    });

    window.addEventListener('open-cmdk', (e) => {
      open(e?.detail?.prefill);
    });

    render();
  })();
})();</script>  </body></html>  <script type="module">document.querySelectorAll(".cmd-tip-example").forEach(e=>{e.addEventListener("click",()=>{window.dispatchEvent(new CustomEvent("open-cmdk",{detail:{prefill:e.dataset.example}}))})});</script>