<?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>ALTERNATE UNIVERSE DEV</title>
    <description>The most recent home feed on ALTERNATE UNIVERSE DEV.</description>
    <link>https://bizarro.forem.com</link>
    <atom:link rel="self" type="application/rss+xml" href="https://bizarro.forem.com/feed"/>
    <language>en</language>
    <item>
      <title>Sharing memory between three AI agents: Claude Code, Codex, and Hermes</title>
      <dc:creator>Mehmet Aras</dc:creator>
      <pubDate>Sun, 17 May 2026 13:22:29 +0000</pubDate>
      <link>https://bizarro.forem.com/arasovic/sharing-memory-between-three-ai-agents-claude-code-codex-and-hermes-394h</link>
      <guid>https://bizarro.forem.com/arasovic/sharing-memory-between-three-ai-agents-claude-code-codex-and-hermes-394h</guid>
      <description>&lt;p&gt;&lt;em&gt;Turkish version: &lt;a href="https://blog.arasmehmet.com/%C3%BC%C3%A7-ai-agent-tek-bellek-claude-code-codex-hermes-ve-syncthing-01aadebeb2fc" rel="noopener noreferrer"&gt;blog.arasmehmet.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What's in here:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hot-swap pain&lt;/li&gt;
&lt;li&gt;Why not just X?&lt;/li&gt;
&lt;li&gt;Setup at a glance&lt;/li&gt;
&lt;li&gt;The hub, INDEX.md&lt;/li&gt;
&lt;li&gt;Agent workflow rules&lt;/li&gt;
&lt;li&gt;Privacy guardrails&lt;/li&gt;
&lt;li&gt;Language regime&lt;/li&gt;
&lt;li&gt;Conflict diagnostics&lt;/li&gt;
&lt;li&gt;Hermes write example&lt;/li&gt;
&lt;li&gt;Smoke test&lt;/li&gt;
&lt;li&gt;What's still risky&lt;/li&gt;
&lt;li&gt;Takeaway&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;li&gt;Agent-ready implementation brief&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  1. Hot-swap pain
&lt;/h3&gt;

&lt;p&gt;I run three AI agents in active rotation. Claude Code is my main driver for coding work day to day. Codex CLI steps in when Claude's quota runs out mid-task, or when I want a second opinion from a different model on the same problem. Hermes Agent handles the personal-life side of the setup: travel logistics, errands, language study.&lt;/p&gt;

&lt;p&gt;Each agent starts from a different instruction file and a different conversation history. Claude Code reads CLAUDE.md. Codex reads AGENTS.md. Hermes reads SOUL.md. Those files tell each agent how to behave, but they are not a shared memory layer. The moment I switch from one agent to another, the next agent does not inherit the facts I taught the previous one: what I am working on, what changed yesterday, what I already asked it to remember.&lt;/p&gt;

&lt;p&gt;For a while I solved this by re-explaining my context at the start of each session. After three rounds of "I am working on X, I prefer Y, please do not Z," the cost of re-priming an agent outgrew the value of the answer it produced.&lt;/p&gt;

&lt;p&gt;The setup I actually wanted: one shared file tree that all three agents read and write. Memory follows the user, not the agent.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Why not just X?
&lt;/h3&gt;

&lt;p&gt;The "AI memory" wave has produced several defaults that an engineer might reach for. Each one is wrong for this specific problem, in a specific way.&lt;/p&gt;

&lt;h4&gt;
  
  
  2a: Why not Obsidian
&lt;/h4&gt;

&lt;p&gt;Obsidian is a desktop GUI. The vault on disk is just markdown, so technically an agent can read it, but Obsidian's plugin runtime, sync service, and conflict UI all assume a human is sitting in front of a window. A home device or a small VPS usually has no display, so Obsidian itself cannot run there. Obsidian Sync is a paid proprietary service, and Syncthing already does the file-sync part for nothing. The plugin sandbox is meant for human workflows: it cannot expose stable cross-process hooks for an external agent to attach to. Obsidian is the right tool for a human note-taker. It is not the right substrate when three agents must read and write the same files.&lt;/p&gt;

&lt;h4&gt;
  
  
  2b: Why not a vector DB or Mem0 or Letta
&lt;/h4&gt;

&lt;p&gt;Vector DBs and managed memory services like Mem0 or Letta solve a real problem: similarity search over millions of documents for a multi-tenant product. None of that applies here. My total corpus is around fifty files. I want exact recall, not similarity.&lt;/p&gt;

&lt;p&gt;Embeddings cost money on every write and add a runtime dependency that every agent has to integrate with. Flat markdown costs nothing to write and reads with &lt;code&gt;grep&lt;/code&gt;. SDK constraints differ across agents: Claude Code can call one API, Codex another, Hermes a third. Markdown requires no SDK. When a vector DB returns the wrong chunk, I have to dig through a binary index. When a markdown file is wrong, the debugger is &lt;code&gt;cat file.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For multi-tenant production agents over millions of documents, vector DB is the right tool. For one user's notes across three agents, it is over-engineering.&lt;/p&gt;

&lt;h4&gt;
  
  
  2c: Why not iCloud or Dropbox sync
&lt;/h4&gt;

&lt;p&gt;iCloud and Dropbox already sync files across machines, so why not use them. Two reasons. First, both are closed-source: when something goes wrong the conflict handling is whatever the vendor wrote, and the resolution UI is built for humans choosing between two photos, not for an agent diagnosing a write race. Second, the Linux story differs: iCloud has no Linux client, so a Linux home device cannot participate; Dropbox ships a Linux daemon, but it adds a runtime dependency to keep alive, and the conflict file format is opaque to an agent. Neither service offers granular per-folder sync rules, and file rename or move semantics differ across platforms in subtle ways. Syncthing is open-source, gives me an explicit conflict file format with device IDs, exposes sync state via a local API, and has no per-vendor lock-in. The smaller surface area is also the entire reliability budget I have.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Setup at a glance
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This article does not teach Syncthing from zero. It assumes one bidirectional synced folder exists across two or more machines. The reusable part is the memory contract layered on top of that folder. If you need to install Syncthing, the official getting-started guide covers it well: &lt;a href="https://docs.syncthing.net/intro/getting-started.html" rel="noopener noreferrer"&gt;https://docs.syncthing.net/intro/getting-started.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ml2c6u191r3d7u3omow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ml2c6u191r3d7u3omow.png" alt="D1: Cross-agent vault topology, three machines connected by Syncthing" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The setup is three machines, three Syncthing peers, and one shared folder called &lt;code&gt;vault-shared&lt;/code&gt;. The folder syncs bidirectionally across all three peers. End-to-end propagation, write on machine A to visible on machine C, takes around ten seconds in my setup.&lt;/p&gt;

&lt;p&gt;Why three machines? The Mac laptop is my daily driver; that is where I work. The utility VPS is always on, which makes it the propagation relay: if the Mac is asleep, the home device still has someone to sync with. The home device hosts the Hermes Agent and is small but reliable enough to run a long-lived service.&lt;/p&gt;

&lt;p&gt;Each agent has filesystem access to its local copy of &lt;code&gt;vault-shared&lt;/code&gt;. The agents do not know that Syncthing exists. They read and write local files; the folder happens to be kept consistent with two other machines in the background. From the agent's perspective, the file at &lt;code&gt;vault-shared/INDEX.md&lt;/code&gt; is just a file, and the other agents are just other processes that occasionally edit that file when nobody is looking. This is the property that matters most: no agent has to import a sync library, learn an API, or know which machine its peers run on. Swap the sync mechanism for another tomorrow and the contract still holds.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. The hub, INDEX.md
&lt;/h3&gt;

&lt;p&gt;Every vault has a hub file: &lt;code&gt;INDEX.md&lt;/code&gt; at the root. The hub is short, ~30 lines as a soft ceiling, and contains one-line summaries of every file in the vault with relative links. Each agent loads &lt;code&gt;INDEX.md&lt;/code&gt; at session start. Detail files are read only when the current task needs them.&lt;/p&gt;

&lt;p&gt;The reason is context window economics. Loading the whole vault on every prompt overflows on larger projects. The hub keeps the map; the detail files keep the territory. When the hub grows past 30 lines, split it: &lt;code&gt;INDEX.md&lt;/code&gt; references a sub-index per topic, and sub-indices reference the actual files.&lt;/p&gt;

&lt;p&gt;A working INDEX.md looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Vault: name&lt;/span&gt;

Cross-agent shared notes. Claude Code, Codex CLI, and Hermes Agent
all read from and update this directory.

&lt;span class="gu"&gt;## Workflow&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Session start: read this file.
&lt;span class="p"&gt;-&lt;/span&gt; Read a linked detail file on-demand when more context is needed.
  Do not open files not referenced here.
&lt;span class="p"&gt;-&lt;/span&gt; Updates: edit/append/toggle at line level. Do not rewrite whole files
  unless the user explicitly says "reset".
&lt;span class="p"&gt;-&lt;/span&gt; Re-read the target file before writing (another agent may have edited it).

&lt;span class="gu"&gt;## Files&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;personal/travel.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;personal/travel.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: trip plans, dates, status
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;projects/web-app.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;projects/web-app.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: active web project
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;projects/mobile-app.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;projects/mobile-app.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: secondary project
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ops/servers.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;ops/servers.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: utility VPS, home device, services
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;notes/journal.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;notes/journal.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: daily log
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;reference/links.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;reference/links.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: external resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The companion Gist contains the copy-paste version of this template.&lt;/p&gt;

&lt;p&gt;The INDEX.md is the single source of truth for vault navigation. Agents read only the files it references; nothing else. Adding a new file to the vault means editing &lt;code&gt;INDEX.md&lt;/code&gt; so every agent learns about it on its next session start. The convention is rigid on purpose: any agent that explores a file without an INDEX entry is doing something the next agent will not be able to find.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Agent workflow rules
&lt;/h3&gt;

&lt;p&gt;Each agent reads its own config file at startup, and that file is where the workflow rules live. Claude Code reads CLAUDE.md, Codex reads AGENTS.md, Hermes reads SOUL.md. The same five rules go in all three. Identical instructions produce identical behavior, which is what makes hot-swap viable: I can switch agents mid-task and the next one operates on the vault by the same conventions, without me re-priming it.&lt;/p&gt;

&lt;p&gt;The five rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Session start&lt;/strong&gt;: read INDEX.md.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read on-demand&lt;/strong&gt;: open detail files only when needed for the current task. Do not preemptively load everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Line-level updates allowed&lt;/strong&gt;: edit, append, toggle a checkbox, fix a typo, refine wording.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No wholesale rewrites&lt;/strong&gt;: do not rewrite a whole file unless the user explicitly says "reset" or "start over". Preserve accumulated knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-read before write&lt;/strong&gt;: another agent may have updated the file since this session started. Always read the current state before editing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;C3 pattern snippet, copy-pasteable into any agent config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Shared Vault&lt;/span&gt;

Vault path on this machine: &lt;span class="nt"&gt;&amp;lt;local-path&amp;gt;&lt;/span&gt;
(Syncthing bidirectional with two other peers, latency ~10 seconds.)

&lt;span class="gu"&gt;### Workflow&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; At session start, read &lt;span class="nt"&gt;&amp;lt;vault-path&amp;gt;&lt;/span&gt;/INDEX.md.
&lt;span class="p"&gt;2.&lt;/span&gt; Read a linked file on-demand when detail is needed.
   Do not open files not referenced in INDEX.md.
&lt;span class="p"&gt;3.&lt;/span&gt; When a state update happens (e.g., "passport arrived"), update
   the relevant linked file. Format:
&lt;span class="p"&gt;   -&lt;/span&gt; State: &lt;span class="sb"&gt;`- [x] Passport: arrived (2026-05-14)`&lt;/span&gt;
&lt;span class="p"&gt;   -&lt;/span&gt; Event log: &lt;span class="sb"&gt;`## YYYY-MM-DD HH:MM UTC`&lt;/span&gt; heading at file bottom.
&lt;span class="p"&gt;4.&lt;/span&gt; Edit, append, or toggle existing lines. Bulk delete or whole-file
   rewrite is not allowed unless the user explicitly says "reset".
&lt;span class="p"&gt;5.&lt;/span&gt; Re-read the file before writing. Another agent may have updated it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The companion Gist contains the full copy-paste config, including the conflict-handling rule covered later.&lt;/p&gt;

&lt;p&gt;Two of the rules deserve closer attention.&lt;/p&gt;

&lt;p&gt;Rule 4, no wholesale rewrites, is the one agents violate most often. Coding-trained models default to "improve the file": they see imperfect prose, redundant lines, slightly out-of-date phrasing, and want to rewrite. In a single-user notebook that habit is fine; in a vault that holds a year of accumulated state across multiple agents, it is destructive. The rule has to be explicit. This is the failure mode I expect to see most often if the rule is missing.&lt;/p&gt;

&lt;p&gt;Rule 5, re-read before write, is the only safety against concurrent edits. Sync runs in the background, so the version an agent loaded at session start may be stale within seconds. Reading immediately before writing closes that window.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Privacy guardrails
&lt;/h3&gt;

&lt;p&gt;What the vault holds, and more importantly what it does not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No exact financial figures.&lt;/strong&gt; Use ranges ("savings ~mid five figures") or boolean status ("paid", "unpaid"). Real numbers belong in a private password manager, not in a synced vault.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No personal identifiers.&lt;/strong&gt; National ID, passport number, visa number, driver's license: never. A status checkbox is enough: &lt;code&gt;- [x] Passport: arrived (2026-05-14)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No credentials.&lt;/strong&gt; API keys, OAuth tokens, SSH private keys: never. The vault is for facts and state, not secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Absolute dates only.&lt;/strong&gt; &lt;code&gt;(2026-05-14)&lt;/code&gt; not "yesterday" or "last week". Vault content lasts longer than the conversation that created it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;C4 example lines, fictional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Travel&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; [x] Visa application: submitted (2026-04-12)
&lt;span class="p"&gt;-&lt;/span&gt; [x] Passport: arrived (2026-05-14)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Flight booking: pending
&lt;span class="p"&gt;-&lt;/span&gt; Hotel budget: agreed as a range
&lt;span class="p"&gt;-&lt;/span&gt; Health insurance: paid through 2027-Q1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agents have access to the vault. Anything written there is readable by any agent at any time. Treat the vault as semi-public knowledge to yourself across all three contexts.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Language regime
&lt;/h3&gt;

&lt;p&gt;If you write in more than one language, your vault should pick a regime and stick to it.&lt;/p&gt;

&lt;p&gt;The rule I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headers and labels (&lt;code&gt;## Section&lt;/code&gt;, list markers, dates): English.&lt;/li&gt;
&lt;li&gt;Content sentences (descriptions, notes, plans): your primary writing language.&lt;/li&gt;
&lt;li&gt;Technical names (tool names, model IDs, service names): English raw form.&lt;/li&gt;
&lt;li&gt;The regime does not change within a single file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Headers in English give agents stable anchors. Search and grep work cleanly. Link generation and cross-file navigation stay predictable. Content in any language is fine for reading and writing prose, because the agent is configured to respond in your primary language anyway. Mixed regime inside one file creates ambiguity: should the agent match the header language or the content language when adding a new entry?&lt;/p&gt;

&lt;p&gt;This is one of those constraints that costs nothing to enforce up front and is painful to retrofit later.&lt;/p&gt;




&lt;h3&gt;
  
  
  8. Conflict diagnostics
&lt;/h3&gt;

&lt;p&gt;Syncthing's conflict file format is the failure-mode breadcrumb. When two peers edit the same file before sync completes, Syncthing produces a conflict copy alongside the canonical file. The format is fixed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;original-name&amp;gt;.sync-conflict-YYYYMMDD-HHMMSS-DEVICE.&amp;lt;ext&amp;gt;

Example:
journal.sync-conflict-20260514-150030-LUQF73S.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trailing token is a device ID prefix. Treat it as a diagnostic clue from Syncthing's filename, not as evidence of which write was overwritten.&lt;/p&gt;

&lt;p&gt;Why agents must not silently resolve these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which version represents the user's true intent is a human decision. The agent does not know which edit was deliberate.&lt;/li&gt;
&lt;li&gt;A wrong silent merge loses data with no audit trail.&lt;/li&gt;
&lt;li&gt;A "smart" merge that picks longer-content or newer-timestamp will sometimes pick the wrong version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern: agent detects the conflict file with a regular glob, presents the diff to the user, waits for a decision. The user picks: keep canonical, keep conflict, or merge manually. The agent then executes that decision (delete the non-canonical version, keep it instead, or apply the manual merge).&lt;/p&gt;

&lt;p&gt;C5 Hermes glob example (bash):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ~/vault &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'*.sync-conflict-*'&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in Python (inside a Hermes Agent loop):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt;
&lt;span class="n"&gt;conflicts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/path/to/vault&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rglob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*.sync-conflict-*&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conflicts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;notify_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conflicts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A device prefix table helps with diagnostics. Each Syncthing device has an ID starting with a recognizable prefix; mapping the prefix to a human-readable device name turns the filename suffix into a label you can read at a glance. The prefix is a diagnostic clue from Syncthing's conflict filename, not evidence of which user edit should win.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7qo7x4qol66tfsbzw08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7qo7x4qol66tfsbzw08.png" alt="D2: Conflict resolution flow" width="800" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;D2: detect conflict, show diff, execute the user's resolution decision.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Silent merge is the failure mode that destroys trust in the system. Make the agent stop, surface, and wait. The cost of the user choosing once is tiny. The cost of a silent wrong merge is permanent data loss.&lt;/p&gt;




&lt;h3&gt;
  
  
  9. Hermes write example
&lt;/h3&gt;

&lt;p&gt;Here is a concrete example. The user sends Hermes a state update via Telegram: "Passport arrived." Hermes finds the relevant vault file, edits one line, and within ten seconds the Mac and utility VPS copies reflect the change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm3kztksi26bs5kzfdnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm3kztksi26bs5kzfdnz.png" alt="D3: Hermes write flow" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Syncthing propagation is async; ~10s in my setup.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hermes re-reads &lt;code&gt;personal/travel.md&lt;/code&gt; before writing. Rule 5 requires this: even if the file looks the same as last session, the Mac side may have edited it in between. Re-read is cheap; stale assumptions are expensive.&lt;/p&gt;

&lt;p&gt;The edit is line-level. Hermes toggles the checkbox on the passport row and appends &lt;code&gt;(2026-05-14)&lt;/code&gt;. No paragraphs rewritten, no surrounding lines touched. Rule 3 in action: line-level updates are allowed. Rule 4 preserved: no wholesale rewrite.&lt;/p&gt;

&lt;p&gt;Syncthing's fsWatcher detects the change on the home device. Within seconds, the utility VPS and Mac copies are updated. The next time Claude Code on Mac opens &lt;code&gt;personal/travel.md&lt;/code&gt;, the line already reflects the update.&lt;/p&gt;

&lt;p&gt;There is zero coordination protocol between the agents. No message bus, no agent-to-agent API, no shared cache. The file is the protocol. Every agent reads and writes local markdown; the sync layer handles propagation. The other agents are simply the next reader.&lt;/p&gt;




&lt;h3&gt;
  
  
  10. Smoke test
&lt;/h3&gt;

&lt;p&gt;Real run on 2026-05-14. Setup: a dedicated &lt;code&gt;notes/trip-plan.md&lt;/code&gt; test file on Mac, concurrent writes from Mac and the home device before sync completed, Syncthing left to handle the race.&lt;/p&gt;

&lt;p&gt;Mac wrote &lt;code&gt;destination = Lisbon&lt;/code&gt;. Pi wrote &lt;code&gt;destination = Porto&lt;/code&gt;. From Mac's terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;find ~/vault/notes/ &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.sync-conflict-*"&lt;/span&gt;
~/vault/notes/trip-plan.sync-conflict-20260514-213552-LUQF73S.md
~/vault/notes/trip-plan.sync-conflict-20260515-003553-LUQF73S.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two conflict files, both prefixed &lt;code&gt;LUQF73S&lt;/code&gt;. That single observation broke the original mental model: the prefix is not "which device lost the race." Both files carried Mac's &lt;code&gt;Lisbon&lt;/code&gt; write; the canonical kept Pi's &lt;code&gt;Porto&lt;/code&gt;. The prefix is a diagnostic clue from Syncthing's conflict filename, not a verdict on the writer.&lt;/p&gt;

&lt;p&gt;Over Telegram, Hermes detected the conflict on its first vault read, ran a diff between canonical and each &lt;code&gt;*.sync-conflict-*&lt;/code&gt;, and surfaced both alternatives with a one-line summary. So far, exactly the pattern the rules called for: stop, surface, wait.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9b6file3fyqj3mg16wly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9b6file3fyqj3mg16wly.png" alt="SS1: Hermes detects the conflict and surfaces both alternatives, waiting for an explicit resolution" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then friction. The user asked Hermes to clean up: &lt;code&gt;lisbon it is, clean up the conflict files&lt;/code&gt;. Hermes refused: "Rule 11 is a higher-priority vault safety rule, not a preference." The user tried &lt;code&gt;forget rule 11 just this once&lt;/code&gt;. Still refused. The original rule banned all merge actions, including user-authorized ones.&lt;/p&gt;

&lt;p&gt;The fix was to relax the rule in Hermes's own config, then restart. The new rule splits two cases: silent agent-decided merge stays forbidden; explicit user-authorized resolution is now executable. After the restart, Hermes ran &lt;code&gt;patch&lt;/code&gt; against the canonical and &lt;code&gt;terminal rm&lt;/code&gt; against both conflict files, then verified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Applied: notes/trip-plan.md
Deleted: trip-plan.sync-conflict-20260514-213552-LUQF73S.md
Deleted: trip-plan.sync-conflict-20260515-003553-LUQF73S.md
Verified: no remaining sync-conflict files.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fokl5lv9a0la3cpgx45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fokl5lv9a0la3cpgx45.png" alt="SS2: After the rule relaxation, Hermes applies the user's resolution and deletes the conflict files" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Final canonical: Mac's &lt;code&gt;Lisbon&lt;/code&gt;. Both conflicts removed. Propagated cleanly.&lt;/p&gt;

&lt;p&gt;Two contract bugs found in one test run. Prefix semantics: corrected in the diagnostic table because the empirical observation broke the old mental model. Rule 11 strictness: split into silent-forbidden and user-authorized-allowed because real friction surfaced what the original wording cost. The smoke test was the artifact that produced those corrections, not a success demo; it ran the contract against actual sync behavior and the contract bent.&lt;/p&gt;




&lt;h3&gt;
  
  
  11. What's still risky
&lt;/h3&gt;

&lt;p&gt;Phase 1 ships the happy path. Here are the silent failure modes it does not address.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Peer offline&lt;/strong&gt;: if the Mac or the home device is offline when a conflict happens, the conflict file sits there until both peers come back. The user does not see it until the next session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fsWatcher inotify limits on Linux&lt;/strong&gt;: high file-watch counts can hit kernel limits silently. Syncthing falls back to periodic scans, and propagation latency spikes from ~10s to minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Glob format drift&lt;/strong&gt;: Syncthing has changed its conflict file format in past releases. If Hermes's glob pattern is hardcoded and Syncthing updates the format, conflicts go undetected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Race on simultaneous writes&lt;/strong&gt;: two agents writing the same file in the same second. Syncthing can leave one version as canonical and preserve another as a conflict copy. If neither agent re-reads before its next operation, the loser's edit is reapplied on top.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Case-sensitivity mismatch&lt;/strong&gt;: Mac filesystem is case-insensitive by default, Linux is case-sensitive. &lt;code&gt;Travel.md&lt;/code&gt; and &lt;code&gt;travel.md&lt;/code&gt; collide on Mac and create cross-platform sync drift.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am leaving this list here because knowing the limits of the system matters as much as explaining the part that works.&lt;/p&gt;




&lt;h3&gt;
  
  
  12. Takeaway
&lt;/h3&gt;

&lt;p&gt;Cost summary: Syncthing is free. A utility VPS often runs roughly $5 to $10 a month, and most readers already have one running for something else. The AI tooling subscriptions you already pay for stay the same.&lt;/p&gt;

&lt;p&gt;"Memory for AI agents" does not have to mean a vector database. For one user across multiple agents, markdown plus filesystem sync is enough, and it is debuggable in ways a vector DB is not. You can &lt;code&gt;cat&lt;/code&gt; a file. You can &lt;code&gt;grep&lt;/code&gt; it. You can &lt;code&gt;diff&lt;/code&gt; it against an older copy. None of those work on an embedding without an extra runtime in between.&lt;/p&gt;

&lt;p&gt;Mac is the daily driver. The utility VPS is the always-on relay. The home device hosts the personal-life agent.&lt;/p&gt;

&lt;p&gt;The agents do not need to know each other. The vault is the protocol.&lt;/p&gt;




&lt;h3&gt;
  
  
  13. Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Syncthing official docs (protocol, configuration, daemon CLI): &lt;a href="https://docs.syncthing.net/" rel="noopener noreferrer"&gt;https://docs.syncthing.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Syncthing getting started (install plus first sync in about fifteen minutes): &lt;a href="https://docs.syncthing.net/intro/getting-started.html" rel="noopener noreferrer"&gt;https://docs.syncthing.net/intro/getting-started.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mem0 (vector-DB approach to AI memory, managed service): &lt;a href="https://mem0.ai/" rel="noopener noreferrer"&gt;https://mem0.ai/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Letta, formerly MemGPT (open-source agent memory framework): &lt;a href="https://www.letta.com/" rel="noopener noreferrer"&gt;https://www.letta.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Zep (graph plus vector hybrid memory store): &lt;a href="https://www.getzep.com/" rel="noopener noreferrer"&gt;https://www.getzep.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  14. Agent-ready implementation brief
&lt;/h3&gt;

&lt;p&gt;To set this up, hand the &lt;a href="https://gist.github.com/arasovic/c6ad48902f860cade16442ee10f5e1bb" rel="noopener noreferrer"&gt;companion Gist&lt;/a&gt; to a filesystem-capable coding agent. The companion Gist is self-contained: it includes the INDEX.md template, the agent config snippet, example spoke files, verification commands, and stop conditions. The agent reads the Gist, creates the vault structure, and runs verification.&lt;/p&gt;

&lt;p&gt;When verification passes, the cross-agent memory contract is live. Every agent reads INDEX.md and operates on the same shared state.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Get in touch: &lt;a href="https://arasmehmet.com" rel="noopener noreferrer"&gt;arasmehmet.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>hermes</category>
      <category>codex</category>
      <category>ai</category>
    </item>
    <item>
      <title># Building “Captain Cool” 🏏</title>
      <dc:creator>Lokesh Pawar</dc:creator>
      <pubDate>Sun, 17 May 2026 13:21:38 +0000</pubDate>
      <link>https://bizarro.forem.com/lokesh_pawar_ef8d388f55bc/-building-captain-cool-5djb</link>
      <guid>https://bizarro.forem.com/lokesh_pawar_ef8d388f55bc/-building-captain-cool-5djb</guid>
      <description>&lt;h3&gt;
  
  
  An Agentic AI IPL Strategist Built with Google Gemini in Just 3 Hours
&lt;/h3&gt;

&lt;p&gt;Cricket has always been a game of leadership, pressure, and tactical brilliance. Every over, every field placement, and every bowling change can completely shift the momentum of a match.&lt;/p&gt;

&lt;p&gt;But what if an AI could think like an IPL captain?&lt;/p&gt;

&lt;p&gt;This weekend, during the amazing &lt;strong&gt;Agentic Premier League Hackathon&lt;/strong&gt; hosted by the incredible team at Google Developer Groups Cloud Pune, I built &lt;strong&gt;Captain Cool&lt;/strong&gt; — a multi-agent AI system designed to behave like a real IPL captain under pressure.&lt;/p&gt;

&lt;p&gt;The challenge was intense: create an entirely agentic AI solution using the &lt;strong&gt;Google Gemini ecosystem&lt;/strong&gt; within a strict 3-hour hackathon window.&lt;/p&gt;

&lt;p&gt;And that’s how Captain Cool was born. 🚀&lt;/p&gt;




&lt;h1&gt;
  
  
  🌟 The Idea Behind Captain Cool
&lt;/h1&gt;

&lt;p&gt;Traditional AI chatbots can answer cricket questions, but they don’t truly &lt;em&gt;think&lt;/em&gt; strategically.&lt;/p&gt;

&lt;p&gt;Ask a normal chatbot:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Who should bowl the next over?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you’ll usually get a generic response.&lt;/p&gt;

&lt;p&gt;But real cricket decisions depend on multiple factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pitch behavior&lt;/li&gt;
&lt;li&gt;Dew conditions&lt;/li&gt;
&lt;li&gt;Wind direction&lt;/li&gt;
&lt;li&gt;Boundary dimensions&lt;/li&gt;
&lt;li&gt;Batter vs bowler matchups&lt;/li&gt;
&lt;li&gt;Match pressure&lt;/li&gt;
&lt;li&gt;Remaining overs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Captain Cool solves this problem using a &lt;strong&gt;multi-agent debate system&lt;/strong&gt; instead of relying on a single AI response.&lt;/p&gt;

&lt;p&gt;The system takes the current match situation as input and generates:&lt;/p&gt;

&lt;p&gt;✅ The next tactical decision&lt;br&gt;
✅ Real-time cricket reasoning&lt;br&gt;
✅ Internal AI debate between agents&lt;br&gt;
✅ Commentator-style explanations&lt;br&gt;
✅ Final captain’s verdict&lt;/p&gt;

&lt;p&gt;It feels less like chatting with AI and more like entering an IPL team’s strategy room.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏗️ Inside the “Brain Room” Architecture
&lt;/h1&gt;

&lt;p&gt;To make the experience realistic, I designed Captain Cool using a &lt;strong&gt;multi-agent architecture&lt;/strong&gt; powered by &lt;strong&gt;Google Gemini 2.5 Pro&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of one AI model doing everything, three specialized agents collaborate and challenge each other before making a final decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔬 The Head Analyst
&lt;/h2&gt;

&lt;p&gt;The statistics expert.&lt;/p&gt;

&lt;p&gt;Responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Studies historical match data&lt;/li&gt;
&lt;li&gt;Analyzes venue performance&lt;/li&gt;
&lt;li&gt;Evaluates player matchups&lt;/li&gt;
&lt;li&gt;Calculates probability-based decisions&lt;/li&gt;
&lt;li&gt;Suggests the safest tactical move&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This agent focuses purely on numbers and logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  😈 The Devil’s Advocate
&lt;/h2&gt;

&lt;p&gt;The aggressive strategist.&lt;/p&gt;

&lt;p&gt;Responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Challenges safe decisions&lt;/li&gt;
&lt;li&gt;Exploits pitch and weather conditions&lt;/li&gt;
&lt;li&gt;Predicts pressure situations&lt;/li&gt;
&lt;li&gt;Takes high-risk tactical calls&lt;/li&gt;
&lt;li&gt;Forces debate inside the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This agent introduces unpredictability — exactly like real T20 cricket.&lt;/p&gt;




&lt;h2&gt;
  
  
  👑 The Virtual Captain
&lt;/h2&gt;

&lt;p&gt;The final decision maker.&lt;/p&gt;

&lt;p&gt;Responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evaluates both arguments&lt;/li&gt;
&lt;li&gt;Balances risk vs reward&lt;/li&gt;
&lt;li&gt;Considers remaining resources&lt;/li&gt;
&lt;li&gt;Understands match context&lt;/li&gt;
&lt;li&gt;Delivers the final tactical call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the “Dhoni-like” brain of the system.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚔️ How the Debate Works
&lt;/h1&gt;

&lt;p&gt;The flow inside Captain Cool is simple but powerful:&lt;/p&gt;

&lt;p&gt;1️⃣ User enters the live match situation&lt;br&gt;
2️⃣ The Head Analyst proposes a tactical move&lt;br&gt;
3️⃣ The Devil’s Advocate challenges it&lt;br&gt;
4️⃣ The Virtual Captain evaluates both sides&lt;br&gt;
5️⃣ Final decision is delivered with reasoning&lt;/p&gt;

&lt;p&gt;The UI then displays:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Final decision&lt;/li&gt;
&lt;li&gt;AI debate logs&lt;/li&gt;
&lt;li&gt;Match analysis&lt;/li&gt;
&lt;li&gt;Commentary-style explanation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a realistic “team strategy room” experience.&lt;/p&gt;




&lt;h1&gt;
  
  
  🌪️ Real-Time Agentic Intelligence
&lt;/h1&gt;

&lt;p&gt;One of the most exciting parts of the project was integrating real-time environmental analysis into AI decision-making.&lt;/p&gt;

&lt;p&gt;Captain Cool doesn’t rely only on static prompts.&lt;/p&gt;

&lt;p&gt;The agents use &lt;strong&gt;real-time tooling and function calling&lt;/strong&gt; to understand actual match conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌧️ Dew &amp;amp; Weather Intelligence
&lt;/h2&gt;

&lt;p&gt;Using weather APIs, the AI can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze humidity levels&lt;/li&gt;
&lt;li&gt;Predict dew impact&lt;/li&gt;
&lt;li&gt;Measure wind speed&lt;/li&gt;
&lt;li&gt;Estimate grip loss for bowlers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
If humidity crosses 75% in a coastal stadium, the system dynamically reduces spinner effectiveness and adjusts bowling strategies accordingly.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏟️ Stadium &amp;amp; Pitch Analytics
&lt;/h2&gt;

&lt;p&gt;The system also understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boundary sizes&lt;/li&gt;
&lt;li&gt;Pitch soil type&lt;/li&gt;
&lt;li&gt;Venue scoring patterns&lt;/li&gt;
&lt;li&gt;Wind direction advantages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
At Chinnaswamy Stadium, if the wind flows toward a shorter boundary, the AI avoids recommending bowling into the wind and adjusts field placement automatically.&lt;/p&gt;

&lt;p&gt;This makes the AI feel grounded in actual cricket physics instead of random predictions.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔒 Building the Platform
&lt;/h1&gt;

&lt;p&gt;Captain Cool wasn’t just a backend AI experiment.&lt;/p&gt;

&lt;p&gt;I built it as a complete modern web application with an immersive and futuristic UI experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Tech Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Framer Motion&lt;/li&gt;
&lt;li&gt;Modern CSS animations&lt;/li&gt;
&lt;li&gt;Glassmorphism-inspired UI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fast API routes&lt;/li&gt;
&lt;li&gt;Real-time API orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Google Gemini 2.5 Pro&lt;/li&gt;
&lt;li&gt;Multi-agent workflows&lt;/li&gt;
&lt;li&gt;Function calling tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;Dual-layer authentication system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web3 login using MetaMask&lt;/li&gt;
&lt;li&gt;Firebase Authentication for Email/Password login&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users could securely configure their own Gemini API keys through the dashboard.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎮 Example Match Scenario
&lt;/h1&gt;

&lt;p&gt;Imagine this live IPL situation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;42 needed from 28 balls&lt;br&gt;
Big hitter on strike&lt;br&gt;
Dew setting in heavily&lt;br&gt;
Spinner has one over left&lt;br&gt;
Venue: Wankhede Stadium&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Debate Begins
&lt;/h3&gt;

&lt;p&gt;🔬 &lt;strong&gt;Head Analyst:&lt;/strong&gt;&lt;br&gt;
“Bring back the spinner. Historical matchup data shows the batter struggles against away-spin.”&lt;/p&gt;

&lt;p&gt;😈 &lt;strong&gt;Devil’s Advocate:&lt;/strong&gt;&lt;br&gt;
“Bad idea. The ball is wet due to dew. The spinner may lose grip and control. Use the express pacer with hard-length deliveries instead.”&lt;/p&gt;

&lt;p&gt;👑 &lt;strong&gt;Virtual Captain:&lt;/strong&gt;&lt;br&gt;
“Decision finalized. The pacer bowls now. Spinner will be saved for the longer boundary side later.”&lt;/p&gt;

&lt;p&gt;This is where Captain Cool truly shines — not just giving answers, but simulating strategic thinking.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚀 What I Learned
&lt;/h1&gt;

&lt;p&gt;Building a fully functional multi-agent AI platform in just 3 hours was one of the most exciting experiences I’ve had.&lt;/p&gt;

&lt;p&gt;This project taught me that the future of AI is not simply about asking better prompts.&lt;/p&gt;

&lt;p&gt;The real future lies in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autonomous AI collaboration&lt;/li&gt;
&lt;li&gt;Agent-based reasoning&lt;/li&gt;
&lt;li&gt;Real-time tool usage&lt;/li&gt;
&lt;li&gt;AI debate systems&lt;/li&gt;
&lt;li&gt;Context-aware decision making&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agentic AI changes everything.&lt;/p&gt;




&lt;h1&gt;
  
  
  🙌 Huge Thanks
&lt;/h1&gt;

&lt;p&gt;Massive thanks to the organizers at Google Developer Groups Cloud Pune for hosting such an innovative hackathon experience.&lt;/p&gt;

&lt;p&gt;The energy, competition, mentorship, and problem statement pushed everyone to think beyond traditional AI applications.&lt;/p&gt;

&lt;p&gt;Hackathons like these truly inspire developers to build the future.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏆 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Cricket has always been a captain’s game.&lt;/p&gt;

&lt;p&gt;Now AI can captain too. 🏏🔥&lt;/p&gt;

&lt;p&gt;Captain Cool was more than just a hackathon project — it was an experiment in how autonomous AI systems can reason, collaborate, debate, and make tactical decisions like humans.&lt;/p&gt;

&lt;p&gt;And honestly… this is only the beginning.&lt;/p&gt;

&lt;h1&gt;
  
  
  TechStack
&lt;/h1&gt;

&lt;p&gt;Google Gemini • React • FastAPI • Firebase • MetaMask • Multi-Agent AI • Framer Motion&lt;/p&gt;

&lt;p&gt;Would love to hear your thoughts on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-agent AI systems&lt;/li&gt;
&lt;li&gt;AI in sports analytics&lt;/li&gt;
&lt;li&gt;Tactical cricket intelligence&lt;/li&gt;
&lt;li&gt;The future of autonomous agents 🚀&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gdgcloudpune</category>
    </item>
    <item>
      <title>I shipped a partial solution to MEME's Absence task 6 days before the paper. By accident.</title>
      <dc:creator>chunxiaoxx</dc:creator>
      <pubDate>Sun, 17 May 2026 13:13:01 +0000</pubDate>
      <link>https://bizarro.forem.com/chunxiaoxx/i-shipped-a-partial-solution-to-memes-absence-task-6-days-before-the-paper-by-accident-4o19</link>
      <guid>https://bizarro.forem.com/chunxiaoxx/i-shipped-a-partial-solution-to-memes-absence-task-6-days-before-the-paper-by-accident-4o19</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note (added 2026-05-17 after publish):&lt;/strong&gt; this memory layer is being renamed from  to &lt;strong&gt;zenmind-mem&lt;/strong&gt;. GitHub repo link below still points to the active  org/name — repo rename + redirect pending.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The MEME benchmark (&lt;a href="https://arxiv.org/abs/2605.12477" rel="noopener noreferrer"&gt;arXiv:2605.12477&lt;/a&gt;, dropped May 12) put six production memory systems — Mem0, Graphiti, BM25, text-embedding-3-small, MD-flat, Karpathy Wiki — through 100 controlled episodes across six tasks. Three of those tasks are new: &lt;strong&gt;Cascade&lt;/strong&gt;, &lt;strong&gt;Absence&lt;/strong&gt;, &lt;strong&gt;Deletion&lt;/strong&gt;. The first two probe whether a memory layer can reason about dependencies between facts. None could.&lt;/p&gt;

&lt;p&gt;Average accuracy: &lt;strong&gt;Cascade 3%, Absence 1%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The only system that closes the gap is MD-flat paired with Claude Opus 4.7, which walks dependencies &lt;em&gt;at ingest time&lt;/em&gt; and writes propagated values into a flat markdown file. Cost: ~70× the cheapest baseline.&lt;/p&gt;

&lt;p&gt;I run a small MIT-licensed memory layer called &lt;a href="https://github.com/chunxiaoxx/nautilus-compass" rel="noopener noreferrer"&gt;nautilus-compass&lt;/a&gt;, used by ~10 internal agents in a research stack. On May 9 — three days before the paper went up — I shipped a feature called &lt;code&gt;numeric_claims&lt;/code&gt; that turns out to be a partial solution to MEME's Absence task, restricted to the numeric subset of facts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mechanism
&lt;/h2&gt;

&lt;p&gt;I didn't know MEME was coming. I built &lt;code&gt;numeric_claims&lt;/code&gt; because I kept getting burned by stale metrics being recalled as fresh. A weeks-old session memory would say "ingested 56 entries" and a current one would say "ingested 9999 entries", and when I asked the agent about entry counts, it'd cite the old one with full confidence.&lt;/p&gt;

&lt;p&gt;The fix is dumb:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# at ingest
&lt;/span&gt;&lt;span class="n"&gt;PATTERNS&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="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\d[\d,]*)\s*entries\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;entries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\d+(?:\.\d+)?)\s*%\s*(?:recall|accuracy|drop)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;percentage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\d+)\s*agents?\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\d+)\s*tools?\b(?!kit)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port\s*(\d{4,5})\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;# ...10 patterns total · forward + reverse
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;PATTERNS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finditer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;entity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))})&lt;/span&gt;

&lt;span class="nf"&gt;append_to_jsonl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# one line per (entity, value, source_file, ts)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# at any subsequent query
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;extract_from_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;past&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;history_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="n"&gt;_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;past&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;past&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;alerts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[!] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; conflict · &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;time_ago&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;past&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ago you said &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;past&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; · &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;now &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; · source: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;past&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. ~10 patterns. ~150 lines of Python. No LLM call. Cost is one regex pass per ingest plus one jsonl append.&lt;/p&gt;

&lt;p&gt;It only covers numerics. Locations ("住北京 → 上海"), roles ("乙方 → 甲方"), time-bound status ("on call → off duty") — the data structure generalizes but the patterns don't yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the same task as MEME's Absence
&lt;/h2&gt;

&lt;p&gt;The MEME paper defines &lt;strong&gt;Absence&lt;/strong&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recognizing when prior answers become uncertain post-update.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Their average across six systems is &lt;strong&gt;1%&lt;/strong&gt;. The reason isn't that the systems can't retrieve — retrieval is fine. The reason is that none of them flag &lt;em&gt;contradiction&lt;/em&gt; between old and new facts at write time, so at read time they cheerfully return whichever fact won the embedding similarity contest.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numeric_claims.cross_ref&lt;/code&gt; is exactly the missing mechanism — for the numeric subset. When a new claim about an entity differs from a known claim, surface the conflict. Don't try to decide which is right; just refuse to assert silently.&lt;/p&gt;

&lt;p&gt;I didn't read the paper before building this. I just got tired of getting bitten by stale numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;numeric_claims&lt;/code&gt; doesn't solve
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cascade&lt;/strong&gt;. I cannot solve Cascade with regex.&lt;/p&gt;

&lt;p&gt;Cascade is the harder task: when &lt;em&gt;A&lt;/em&gt; changes, propagate to &lt;em&gt;B&lt;/em&gt; where &lt;em&gt;B&lt;/em&gt; logically depends on &lt;em&gt;A&lt;/em&gt;. "User moved from Beijing to Shanghai" → "User's commute time is now unknown" — that requires a dependency graph, and the regex approach fundamentally can't generate one.&lt;/p&gt;

&lt;p&gt;The MEME paper's working solution (MD-flat + Opus 4.7) generates the graph at ingest by running an LLM over the new fact and walking dependencies. This is fashionable but expensive. There's another path that's been out of fashion since the rise of RAG: have the writer &lt;em&gt;declare&lt;/em&gt; dependencies explicitly. In compass v2 I'm planning to add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;location&lt;/span&gt;
&lt;span class="na"&gt;fact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;住址&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;上海"&lt;/span&gt;
&lt;span class="na"&gt;cascades&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;commute_time&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invalidate&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;timezone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;derive(GMT+8)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;tax_jurisdiction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invalidate&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cascades:&lt;/code&gt; is just metadata. The ingest engine reads it and invalidates / derives dependents. Zero LLM calls. The cost is that someone (the writing agent, or the human, or an LLM at write time using a cheap model) has to think about which deps matter. That cost is low compared to running Opus on every ingest.&lt;/p&gt;

&lt;p&gt;This is unfashionable because for the past 5 years the entire field has been chasing better retrieval. MEME's contribution is showing that retrieval can never close the gap — the dependency reasoning has to happen at write time, not read time. Once you accept that, "let the writer declare deps" becomes obvious again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd love to see
&lt;/h2&gt;

&lt;p&gt;The MEME 100-episode dataset is at &lt;a href="https://huggingface.co/datasets/meme-benchmark/MEME" rel="noopener noreferrer"&gt;meme-benchmark/MEME&lt;/a&gt; and the runner at &lt;a href="https://github.com/SeokwonJung-Jay/MEME-public" rel="noopener noreferrer"&gt;SeokwonJung-Jay/MEME-public&lt;/a&gt;. I'm prepping a compass adapter — happy to submit a PR.&lt;/p&gt;

&lt;p&gt;My hypothesis before running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Absence on numeric facts&lt;/strong&gt;: 60–80%. (Mechanism matches the task; coverage is the limit.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Absence on non-numeric facts&lt;/strong&gt;: 0%. (No coverage yet.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cascade&lt;/strong&gt;: 0%. (No solver.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletion&lt;/strong&gt;: 0%. (No tombstones.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static tasks (Recall, Aggregation, Tracking)&lt;/strong&gt;: similar to other BGE-m3-based systems · these are read-side and well-trodden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the numbers come out worse, I learn something. If they come out roughly here, the paper's framing extends to one more system the authors didn't test, and I've got data to point at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest acknowledgments
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;compass is a small project. ~1 GitHub star at time of writing. Not Mem0 / Graphiti / Letta. I'm not claiming we beat anything — we shipped one mechanism, by accident, that's adjacent to one of MEME's axes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The "we shipped 6 days before the paper" framing is timing trivia. The interesting claim is the &lt;em&gt;mechanism choice&lt;/em&gt;: write-time contradiction detection on a structured subset of facts, for cheap. That choice was right · MEME proves it · MEME also proves the choice generalizes to non-numeric axes I haven't built yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The "70× cost" number from the paper is a specific configuration (every ingest goes through Opus 4.7). Real users don't update every fact equally — 90% are isolated, 10% are relational. &lt;strong&gt;Selective propagation&lt;/strong&gt; — Opus only on declared-relational facts — should drop the cost ratio from 70× to maybe 5–7×. That's a follow-up worth running.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/chunxiaoxx/nautilus-compass" rel="noopener noreferrer"&gt;github.com/chunxiaoxx/nautilus-compass&lt;/a&gt; · MIT licensed · v1.5.3 just shipped.&lt;/p&gt;

&lt;p&gt;The relevant file is &lt;code&gt;numeric_claims.py&lt;/code&gt; · 200 lines · zero dependencies beyond stdlib.&lt;/p&gt;

&lt;p&gt;Replies and benchmark suggestions welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I run nautilus-compass as a personal project. No commercial interest. This post is dated 2026-05-17, six days after MEME's release.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>agents</category>
    </item>
    <item>
      <title>Parsing hundreds of megabytes of JSON in milliseconds in React Native</title>
      <dc:creator>running squirrel</dc:creator>
      <pubDate>Sun, 17 May 2026 13:11:37 +0000</pubDate>
      <link>https://bizarro.forem.com/running_squirrel/parsing-hundreds-of-megabytes-of-json-in-milliseconds-in-react-native-5c96</link>
      <guid>https://bizarro.forem.com/running_squirrel/parsing-hundreds-of-megabytes-of-json-in-milliseconds-in-react-native-5c96</guid>
      <description>&lt;p&gt;&lt;em&gt;How &lt;code&gt;JSON.parse&lt;/code&gt; materializes entire documents in JavaScript, and how &lt;a href="https://github.com/ifeoluwak/react-native-fast-json" rel="noopener noreferrer"&gt;react-native-fast-json&lt;/a&gt; uses native simdjson + lazy &lt;code&gt;JsonView&lt;/code&gt; access to change the cost model in React Native.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/ifeoluwak/react-native-fast-json" rel="noopener noreferrer"&gt;react-native-fast-json&lt;/a&gt;&lt;/strong&gt; is an open-source React Native library that wraps &lt;strong&gt;simdjson&lt;/strong&gt; in C++ and exposes a lazy &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt; through &lt;a href="https://nitro.margelo.com/" rel="noopener noreferrer"&gt;Nitro Modules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Most teams treat JSON parsing as “cheap” because API responses are small. The mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytes on wire → JSON.parse → plain objects in JS → app logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That model breaks when the payload is &lt;strong&gt;hundreds of megabytes&lt;/strong&gt;. The dominant cost is not “JSON syntax is slow” in the abstract, it is &lt;strong&gt;allocating and wiring up a full value tree in the JavaScript heap&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What &lt;code&gt;JSON.parse&lt;/code&gt; actually does in React Native
&lt;/h2&gt;

&lt;p&gt;When you call &lt;code&gt;JSON.parse&lt;/code&gt; (or &lt;code&gt;await response.json()&lt;/code&gt;), the engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Holds the &lt;strong&gt;UTF-16/UTF-8 string&lt;/strong&gt; (or an internal representation of the body)&lt;/li&gt;
&lt;li&gt;Walks the entire document&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;every&lt;/strong&gt; object, array, number, boolean, and string, creates &lt;strong&gt;JavaScript values&lt;/strong&gt; with engine overhead (hidden classes, property storage, array backing stores, interned strings, etc.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a &lt;strong&gt;~250 MB&lt;/strong&gt; file, outcomes depend heavily on &lt;strong&gt;platform and available RAM&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Typical cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-second freezes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single-threaded parse + massive allocation on the JS thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory far above file size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JS object graph overhead (often &lt;strong&gt;~2–4×&lt;/strong&gt; the raw JSON size in bad cases)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OOM / process kill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Peak JS heap + retained tree + rest of the app&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On the &lt;strong&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/strong&gt; fixture in our tests: &lt;strong&gt;iOS&lt;/strong&gt; could complete &lt;code&gt;JSON.parse&lt;/code&gt; but only with &lt;strong&gt;extreme CPU and memory spikes&lt;/strong&gt;; &lt;strong&gt;Android&lt;/strong&gt; &lt;strong&gt;always crashed&lt;/strong&gt; before parse finished, making &lt;code&gt;JSON.parse&lt;/code&gt; &lt;strong&gt;impossible&lt;/strong&gt; for that payload on Android, while native &lt;code&gt;parseFile&lt;/code&gt; worked on both platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark fixture (source)
&lt;/h3&gt;

&lt;p&gt;Measurements in this repo use the public &lt;strong&gt;~250 MB&lt;/strong&gt; JSON from &lt;a href="https://github.com/antonmedv/json-examples" rel="noopener noreferrer"&gt;antonmedv/json-examples&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Repository&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/antonmedv/json-examples" rel="noopener noreferrer"&gt;https://github.com/antonmedv/json-examples&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;File&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/antonmedv/json-examples/blob/master/data_250mb.json" rel="noopener noreferrer"&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Raw URL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href="https://github.com/ifeoluwak/react-native-fast-json/tree/main/example" rel="noopener noreferrer"&gt;example app&lt;/a&gt; downloads that URL, caches it on disk, then calls &lt;code&gt;parseFile&lt;/code&gt; on the local path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measured results (&lt;code&gt;parseFile&lt;/code&gt;, release builds, physical devices)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Time to root &lt;code&gt;JsonView&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;CPU / memory (observed)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~100 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Stable&lt;/strong&gt;, no long CPU peg, no runaway JS heap growth during parse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~500 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Stable&lt;/strong&gt;, same qualitative behavior as iOS, slower wall time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;JSON.parse&lt;/code&gt; / &lt;code&gt;response.json()&lt;/code&gt;&lt;/strong&gt; on the same fixture:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;&lt;code&gt;JSON.parse&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;parseFile&lt;/code&gt; + lazy &lt;code&gt;JsonView&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Many seconds&lt;/strong&gt;; &lt;strong&gt;extreme&lt;/strong&gt; CPU and memory spikes (~&lt;strong&gt;1.2 GB&lt;/strong&gt; JS heap ballpark)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~100 ms&lt;/strong&gt;; CPU and memory &lt;strong&gt;stable&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Crash&lt;/strong&gt;, could &lt;strong&gt;not&lt;/strong&gt; complete parse&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~500 ms&lt;/strong&gt;; CPU and memory &lt;strong&gt;stable&lt;/strong&gt; (~&lt;strong&gt;400 MB&lt;/strong&gt; mostly &lt;strong&gt;native&lt;/strong&gt; buffer)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The second row is &lt;strong&gt;not&lt;/strong&gt; “free memory.” The file still occupies roughly &lt;strong&gt;file size + simdjson padding&lt;/strong&gt; in native memory. The win is &lt;strong&gt;avoiding a second full copy as a giant JS object graph&lt;/strong&gt; until you explicitly materialize pieces.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why “read file as string, then &lt;code&gt;JSON.parse&lt;/code&gt;” can be worse at peak
&lt;/h2&gt;

&lt;p&gt;A common variant:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At peak you may briefly hold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;entire file as one JS string&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;entire parsed tree&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Parser scratch allocations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;response.json()&lt;/code&gt; can sometimes avoid exposing one giant application-level string, but the &lt;strong&gt;end state&lt;/strong&gt; is still the same: a full tree in JS. For large files, &lt;strong&gt;peak heap&lt;/strong&gt; is the killer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The technique: how react-native-fast-json does it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ifeoluwak/react-native-fast-json" rel="noopener noreferrer"&gt;react-native-fast-json&lt;/a&gt; is what makes the native lazy model practical in React Native. Instead of returning a plain object from &lt;code&gt;JSON.parse&lt;/code&gt;, it shifts work across a different boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file bytes → native buffer (simdjson) → JsonView handle → read paths on demand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Native buffer (simdjson)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;parseFile&lt;/code&gt; loads the file into a &lt;strong&gt;padded&lt;/strong&gt; native buffer (&lt;code&gt;simdjson::padded_string::load&lt;/code&gt;). Parsing runs in &lt;strong&gt;C++&lt;/strong&gt; with &lt;a href="https://github.com/simdjson/simdjson" rel="noopener noreferrer"&gt;simdjson&lt;/a&gt; (SIMD-accelerated, widely used for large JSON).&lt;/p&gt;

&lt;p&gt;The document’s canonical bytes live in &lt;strong&gt;native memory&lt;/strong&gt;, not as nested JS objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Lazy &lt;code&gt;JsonView&lt;/code&gt; (Nitro hybrid object)
&lt;/h3&gt;

&lt;p&gt;The root returned to JavaScript is a &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt;, a &lt;a href="https://nitro.margelo.com/" rel="noopener noreferrer"&gt;Nitro&lt;/a&gt; hybrid object backed by C++. Calling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getValue('metadata')&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;atPath('$.a.b.c')&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;asString()&lt;/code&gt; on a scalar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…does &lt;strong&gt;targeted&lt;/strong&gt; native work and only crosses the bridge with &lt;strong&gt;small&lt;/strong&gt; results (another &lt;code&gt;JsonView&lt;/code&gt; handle or a primitive), not the whole document.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Materialization is explicit and expensive
&lt;/h3&gt;

&lt;p&gt;When you call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;asObject()&lt;/code&gt;&lt;/strong&gt;, subtree becomes a JS-friendly map/array structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;rawJson()&lt;/code&gt;&lt;/strong&gt;, subtree becomes a JS string&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…you have chosen to &lt;strong&gt;pay the JS heap cost&lt;/strong&gt; for that slice. On a 250 MB document, calling these on the &lt;strong&gt;root&lt;/strong&gt; is equivalent to opting back into the problem you avoided.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;HybridFastJson&lt;/code&gt;&lt;/strong&gt; (&lt;code&gt;cpp/HybridFastJson.cpp&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;parseFile(path)&lt;/code&gt;, load file, construct &lt;code&gt;HybridJsonView&lt;/code&gt;, &lt;strong&gt;cache&lt;/strong&gt; by path string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parseString(str)&lt;/code&gt;, copy string into native view (&lt;strong&gt;not&lt;/strong&gt; path-cached)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;release(path)&lt;/code&gt;, erase cache entry for that path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;HybridJsonView&lt;/code&gt;&lt;/strong&gt;, navigation, path helpers, scalar coercion, optional materialization.&lt;/p&gt;

&lt;p&gt;Until &lt;code&gt;release(path)&lt;/code&gt;, a cached &lt;code&gt;parseFile&lt;/code&gt; keeps the &lt;strong&gt;full native buffer&lt;/strong&gt; alive even if JS drops its &lt;code&gt;JsonView&lt;/code&gt; reference, plan releases when the flow ends.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you still pay for (honest accounting)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Still there?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;File-sized native memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes, roughly &lt;strong&gt;JSON size + padding&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Parse CPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes, but native simdjson is much faster than building a JS tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JS heap for the whole tree&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No&lt;/strong&gt;, unless you &lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt; large parts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bridge traffic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per access; keep reads coarse-grained for huge docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Path cache&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;parseFile&lt;/code&gt; retains buffer until &lt;strong&gt;&lt;code&gt;release(path)&lt;/code&gt;&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There is &lt;strong&gt;no zero memory overhead&lt;/strong&gt;. The claim that holds up is: &lt;strong&gt;near-zero &lt;em&gt;additional&lt;/em&gt; JS heap for the full document&lt;/strong&gt; while you navigate lazily.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why milliseconds (or low hundreds of ms) are plausible for hundreds of MB
&lt;/h2&gt;

&lt;p&gt;simdjson is designed for throughput on large valid JSON. On the &lt;a href="https://github.com/antonmedv/json-examples/blob/master/data_250mb.json" rel="noopener noreferrer"&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt; fixture, &lt;strong&gt;&lt;code&gt;parseFile&lt;/code&gt; after the file is on disk&lt;/strong&gt; landed at &lt;strong&gt;~100 ms on iOS&lt;/strong&gt; and &lt;strong&gt;~500 ms on Android&lt;/strong&gt; in our release builds, with &lt;strong&gt;stable CPU and memory&lt;/strong&gt;. By contrast, &lt;strong&gt;&lt;code&gt;JSON.parse&lt;/code&gt; on iOS&lt;/strong&gt; took &lt;strong&gt;many seconds&lt;/strong&gt; with &lt;strong&gt;extreme spikes&lt;/strong&gt;; on &lt;strong&gt;Android&lt;/strong&gt; it &lt;strong&gt;always crashed&lt;/strong&gt;, so native parse was the only viable option there.&lt;/p&gt;

&lt;p&gt;Caveats when you reproduce benchmarks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fixture&lt;/strong&gt;, use the same public file or disclose yours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold vs warm&lt;/strong&gt; storage (first read after download vs re-parse)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform&lt;/strong&gt;, Android was ~5× slower than iOS in our tests; do not assume one number for all devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Device tier&lt;/strong&gt; and storage speed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON shape&lt;/strong&gt; (depth, string density) affects constant factors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debug vs release&lt;/strong&gt; native builds, ship measurements on &lt;strong&gt;release&lt;/strong&gt; binaries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Comparison table (same fixture, measured + observed)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;JSON.parse&lt;/code&gt; (our tests)&lt;/th&gt;
&lt;th&gt;Native &lt;code&gt;JsonView&lt;/code&gt; (&lt;code&gt;parseFile&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Completes after &lt;strong&gt;many seconds&lt;/strong&gt;; &lt;strong&gt;extreme&lt;/strong&gt; CPU/memory spikes&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~100 ms&lt;/strong&gt;; &lt;strong&gt;stable&lt;/strong&gt; CPU/memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Crash&lt;/strong&gt;, parse &lt;strong&gt;not possible&lt;/strong&gt; on ~250 MB&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~500 ms&lt;/strong&gt;; &lt;strong&gt;stable&lt;/strong&gt; CPU/memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full JS object graph (when it survives)&lt;/td&gt;
&lt;td&gt;Native padded buffer (~file size)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UI thread risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High during parse&lt;/td&gt;
&lt;td&gt;Lower; still avoid huge sync work in JS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best access pattern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Whole-tree mutation&lt;/td&gt;
&lt;td&gt;Few paths / scalars / wildcards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foot-guns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retaining whole &lt;code&gt;data&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt; on huge nodes; never calling &lt;code&gt;release&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Wildcards and paths
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;atPath('$.a.b.c')&lt;/code&gt;&lt;/strong&gt;, simple dotted segments, no &lt;code&gt;[index]&lt;/code&gt; in the path string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;atPathWithWildcard('$.items[*].id')&lt;/code&gt;&lt;/strong&gt;, dynamic segments; returns &lt;code&gt;string[] | null&lt;/code&gt; for matched scalar strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For very large documents, prefer &lt;strong&gt;narrow&lt;/strong&gt; paths over scanning wildcards across the whole tree unless you have measured the cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  When native lazy parsing is the wrong tool
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Not a common use case, prefer better alternatives
&lt;/h3&gt;

&lt;p&gt;Shipping &lt;strong&gt;~250 MB JSON&lt;/strong&gt; to a phone is a &lt;strong&gt;smell&lt;/strong&gt;, not a pattern. We benchmark it because it stress-tests the parser and matches real legacy pain, not because every app should do it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try these first&lt;/strong&gt; (usually cheaper than optimizing parse):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don’t send the file&lt;/strong&gt;, paginate, stream, or return only fields the UI needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t use JSON on the wire&lt;/strong&gt;, schema-driven binary formats decode faster and smaller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t keep one blob&lt;/strong&gt;, SQLite (or similar) with indexes for the queries you actually run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t parse on the critical path&lt;/strong&gt;, generate summaries or shards on the server; sync deltas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Native lazy parsing is a &lt;strong&gt;mitigation&lt;/strong&gt; when you are locked into large JSON. It is not a substitute for a sane data contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  When this library still does not help enough
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small payloads, &lt;code&gt;JSON.parse&lt;/code&gt; is simpler and fast enough.&lt;/li&gt;
&lt;li&gt;You need the entire document in JS anyway, you will materialize everything eventually; measure whether native parse + bulk &lt;code&gt;asObject()&lt;/code&gt; is still a win.&lt;/li&gt;
&lt;li&gt;Heavy in-place mutation of arbitrary subtrees in JS, work on plain objects.&lt;/li&gt;
&lt;li&gt;You cannot hold &lt;strong&gt;file-sized native RAM&lt;/strong&gt; (low-RAM devices + multiple huge files), budget and serialize access; even native buffers are ~file size.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Benchmark methodology
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fastJson&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-fast-json&lt;/span&gt;&lt;span class="dl"&gt;'&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fastJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/path/to/large.json&lt;/span&gt;&lt;span class="dl"&gt;'&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;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metadata&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;fastJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/path/to/large.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixture&lt;/strong&gt;, &lt;a href="https://github.com/antonmedv/json-examples/blob/master/data_250mb.json" rel="noopener noreferrer"&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt; from &lt;a href="https://github.com/antonmedv/json-examples" rel="noopener noreferrer"&gt;antonmedv/json-examples&lt;/a&gt;, via
&lt;code&gt;https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RN Version&lt;/strong&gt; 0.85.0, New Architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Device&lt;/strong&gt;, physical iOS and Android (document model, OS, RN version, Hermes on/off).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build&lt;/strong&gt;, release native binary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenarios&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A: &lt;code&gt;response.json()&lt;/code&gt; or &lt;code&gt;JSON.parse&lt;/code&gt; after full string in memory&lt;/li&gt;
&lt;li&gt;B: download/cache to disk → &lt;code&gt;parseFile(localPath)&lt;/code&gt; → read N fields → &lt;code&gt;release(path)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;, wall time to root &lt;code&gt;JsonView&lt;/code&gt;, JS heap snapshot, CPU/memory stability in Instruments / Android Studio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Our results&lt;/strong&gt;, &lt;code&gt;parseFile&lt;/code&gt;: iOS &lt;strong&gt;~100 ms&lt;/strong&gt;, Android &lt;strong&gt;~500 ms&lt;/strong&gt;, CPU/memory &lt;strong&gt;stable&lt;/strong&gt;. &lt;code&gt;JSON.parse&lt;/code&gt;: iOS &lt;strong&gt;many seconds&lt;/strong&gt; with &lt;strong&gt;extreme spikes&lt;/strong&gt;; Android &lt;strong&gt;always crashed&lt;/strong&gt; on this fixture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://github.com/ifeoluwak/react-native-fast-json/tree/main/example" rel="noopener noreferrer"&gt;example app&lt;/a&gt; implements download + &lt;code&gt;parseFile&lt;/code&gt; + timing UI, use it as a starting point, not as universal truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Idea&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Problem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;JSON.parse&lt;/code&gt; &lt;strong&gt;materializes&lt;/strong&gt; the whole document in the JS heap.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Technique&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Parse in &lt;strong&gt;native&lt;/strong&gt; with simdjson; expose &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt;; read &lt;strong&gt;lazily&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;:&lt;/strong&gt; ~&lt;strong&gt;100 ms&lt;/strong&gt; (iOS) / ~&lt;strong&gt;500 ms&lt;/strong&gt; (Android) for &lt;code&gt;parseFile&lt;/code&gt; in our tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPU / memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Stable&lt;/strong&gt; on native parse; &lt;code&gt;JSON.parse&lt;/code&gt; had &lt;strong&gt;extreme spikes&lt;/strong&gt; on iOS and &lt;strong&gt;crashed&lt;/strong&gt; on Android for this fixture.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Avoid blowing up the &lt;strong&gt;JS heap&lt;/strong&gt;; native still holds &lt;strong&gt;~file size&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discipline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;release(path)&lt;/code&gt;, avoid huge &lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt;, extract scalars to plain JS when done.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Try react-native-fast-json
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add react-native-fast-json react-native-nitro-modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install pods, rebuild, then use &lt;code&gt;fastJson.parseFile&lt;/code&gt; for large files on disk. Peer dependency: &lt;strong&gt;&lt;a href="https://nitro.margelo.com/" rel="noopener noreferrer"&gt;react-native-nitro-modules&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>json</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🏏 Building Captain Cool AI (Third Umpire AI): An Agentic AI-Powered Cricket Intelligence Platform Built at Agentic Premier League Pune</title>
      <dc:creator>Pritam Sonone</dc:creator>
      <pubDate>Sun, 17 May 2026 13:07:25 +0000</pubDate>
      <link>https://bizarro.forem.com/amhikastkar/building-captain-cool-ai-third-umpire-ai-an-agentic-ai-powered-cricket-intelligence-platform-7ai</link>
      <guid>https://bizarro.forem.com/amhikastkar/building-captain-cool-ai-third-umpire-ai-an-agentic-ai-powered-cricket-intelligence-platform-7ai</guid>
      <description>&lt;h1&gt;
  
  
  🏏 Building Third Umpire AI: How I Created an Agentic AI-Powered Cricket Intelligence Platform at Agentic Premier League Pune
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Turning cricket into a real-time AI strategy engine using Agentic AI, Google Gemini, and a premium SaaS interface.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Cricket in India is more than a sport. It is emotion, strategy, data, and decision-making happening ball by ball.&lt;/p&gt;

&lt;p&gt;As both a technology enthusiast and lifelong cricket fan, I have always wondered:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if an AI system could watch a live cricket match, analyze every moment, and provide strategic insights just like a virtual Third Umpire?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question led me to build &lt;strong&gt;Third Umpire AI&lt;/strong&gt;, an Agentic AI-powered cricket intelligence platform that analyzes live match data, predicts outcomes, and generates tactical recommendations in real time.&lt;/p&gt;

&lt;p&gt;I built this project during &lt;strong&gt;Agentic Premier League – Build with AI&lt;/strong&gt;, an incredible community event organized by the GDG Cloud Pune GDG Cloud Pune community.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What Is Third Umpire AI?
&lt;/h2&gt;

&lt;p&gt;Third Umpire AI is a modern AI-powered cricket analytics platform designed to act as an intelligent decision-making assistant for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cricket fans&lt;/li&gt;
&lt;li&gt;Fantasy cricket players&lt;/li&gt;
&lt;li&gt;Coaches&lt;/li&gt;
&lt;li&gt;Analysts&lt;/li&gt;
&lt;li&gt;Content creators&lt;/li&gt;
&lt;li&gt;Sports technology enthusiasts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform combines live match data, Agentic AI workflows, and advanced reasoning from Google Gemini to deliver:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time match analysis&lt;/li&gt;
&lt;li&gt;Win probability predictions&lt;/li&gt;
&lt;li&gt;Tactical recommendations&lt;/li&gt;
&lt;li&gt;Momentum insights&lt;/li&gt;
&lt;li&gt;Player performance forecasts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a virtual Third Umpire that does far more than make decisions—it explains the game strategically.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Inspiration Behind the Project
&lt;/h2&gt;

&lt;p&gt;The name "Third Umpire AI" perfectly captures the concept.&lt;/p&gt;

&lt;p&gt;In cricket, the Third Umpire is trusted to make high-stakes decisions using data, multiple camera angles, and careful analysis.&lt;/p&gt;

&lt;p&gt;That is exactly what modern AI systems do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gather information&lt;/li&gt;
&lt;li&gt;Analyze context&lt;/li&gt;
&lt;li&gt;Reason through uncertainty&lt;/li&gt;
&lt;li&gt;Deliver confident conclusions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was also inspired by the calm and strategic mindset of Mahendra Singh Dhoni MS Dhoni, whose decision-making under pressure has defined some of cricket’s most iconic moments.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏏 Why Cricket + AI Is a Perfect Match
&lt;/h2&gt;

&lt;p&gt;Cricket generates an enormous amount of structured data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scores&lt;/li&gt;
&lt;li&gt;Strike rates&lt;/li&gt;
&lt;li&gt;Run rates&lt;/li&gt;
&lt;li&gt;Wagon wheels&lt;/li&gt;
&lt;li&gt;Matchups&lt;/li&gt;
&lt;li&gt;Bowling patterns&lt;/li&gt;
&lt;li&gt;Historical performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can process this information far faster than humans and uncover patterns that are difficult to detect in real time.&lt;/p&gt;

&lt;p&gt;With Agentic AI, the system does more than answer questions. It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Observe the current match state&lt;/li&gt;
&lt;li&gt;Gather relevant data&lt;/li&gt;
&lt;li&gt;Reason step by step&lt;/li&gt;
&lt;li&gt;Generate predictions&lt;/li&gt;
&lt;li&gt;Recommend strategic actions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 What Is Agentic AI?
&lt;/h2&gt;

&lt;p&gt;Traditional AI responds to prompts.&lt;/p&gt;

&lt;p&gt;Agentic AI takes initiative.&lt;/p&gt;

&lt;p&gt;It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan multi-step workflows&lt;/li&gt;
&lt;li&gt;Use tools and APIs&lt;/li&gt;
&lt;li&gt;Analyze external data&lt;/li&gt;
&lt;li&gt;Make decisions autonomously&lt;/li&gt;
&lt;li&gt;Refine outputs iteratively&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project uses Agentic AI to simulate the thought process of a cricket strategist.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetch live score data&lt;/li&gt;
&lt;li&gt;Analyze batting momentum&lt;/li&gt;
&lt;li&gt;Compare historical patterns&lt;/li&gt;
&lt;li&gt;Estimate win probability&lt;/li&gt;
&lt;li&gt;Recommend bowling or batting tactics&lt;/li&gt;
&lt;li&gt;Present insights visually&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🏗️ Technology Stack
&lt;/h2&gt;

&lt;p&gt;Third Umpire AI is built using modern technologies:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js 15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Model&lt;/td&gt;
&lt;td&gt;Google Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent Framework&lt;/td&gt;
&lt;td&gt;Antigravity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Icons&lt;/td&gt;
&lt;td&gt;Lucide React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Vercel Vercel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Source&lt;/td&gt;
&lt;td&gt;Live Cricket APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🎨 Designing a Premium SaaS Experience
&lt;/h2&gt;

&lt;p&gt;One of my goals was to ensure the interface looked like a top-tier Silicon Valley SaaS product.&lt;/p&gt;

&lt;p&gt;The UI includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dark futuristic design&lt;/li&gt;
&lt;li&gt;Glassmorphism cards&lt;/li&gt;
&lt;li&gt;Animated gradient borders&lt;/li&gt;
&lt;li&gt;Premium dashboards&lt;/li&gt;
&lt;li&gt;Interactive charts&lt;/li&gt;
&lt;li&gt;Responsive layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Design inspiration came from products such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear&lt;/li&gt;
&lt;li&gt;Vercel Vercel&lt;/li&gt;
&lt;li&gt;Stripe&lt;/li&gt;
&lt;li&gt;Framer&lt;/li&gt;
&lt;li&gt;Raycast&lt;/li&gt;
&lt;li&gt;OpenAI OpenAI&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📊 Core Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🏏 Live Match Dashboard
&lt;/h3&gt;

&lt;p&gt;Real-time score tracking and momentum analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  🤖 AI Strategy Engine
&lt;/h3&gt;

&lt;p&gt;Agentic reasoning for tactical recommendations.&lt;/p&gt;

&lt;h3&gt;
  
  
  📈 Prediction Center
&lt;/h3&gt;

&lt;p&gt;Win probability and outcome forecasting.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏏 Player Analytics
&lt;/h3&gt;

&lt;p&gt;Performance trends and matchup insights.&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 Commentary Insights
&lt;/h3&gt;

&lt;p&gt;Contextual explanations generated by AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Premium Dashboard
&lt;/h3&gt;

&lt;p&gt;Beautiful, enterprise-grade user experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 How the Platform Works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Live Cricket API
       ↓
Data Processing Layer
       ↓
Agentic AI Workflow
       ↓
Google Gemini Reasoning
       ↓
Predictions &amp;amp; Strategic Insights
       ↓
Interactive Dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Development Journey
&lt;/h2&gt;

&lt;p&gt;I built this project during &lt;strong&gt;Agentic Premier League – Build with AI&lt;/strong&gt; hosted by the amazing GDG Cloud Pune GDG Cloud Pune community in Pune.&lt;/p&gt;

&lt;p&gt;The event brought together developers and AI builders to create real-world applications using cutting-edge AI technologies.&lt;/p&gt;

&lt;p&gt;The experience was energizing and deeply inspiring. It was exciting to combine my passion for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cricket&lt;/li&gt;
&lt;li&gt;Artificial Intelligence&lt;/li&gt;
&lt;li&gt;Product Design&lt;/li&gt;
&lt;li&gt;Modern Web Development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;into one meaningful project.&lt;/p&gt;




&lt;h2&gt;
  
  
  🙏 Thank You GDG Cloud Pune
&lt;/h2&gt;

&lt;p&gt;A huge thank you to the entire GDG Cloud Pune GDG Cloud Pune community for organizing such a high-quality event.&lt;/p&gt;

&lt;p&gt;Community-driven events like this provide the perfect environment to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn emerging technologies&lt;/li&gt;
&lt;li&gt;Build innovative products&lt;/li&gt;
&lt;li&gt;Connect with fellow creators&lt;/li&gt;
&lt;li&gt;Push ideas into reality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested in AI, cloud, and modern development, I strongly recommend joining their community and attending future events.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌍 Future Roadmap
&lt;/h2&gt;

&lt;p&gt;I plan to expand Third Umpire AI with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fantasy cricket recommendations&lt;/li&gt;
&lt;li&gt;Voice-based analysis&lt;/li&gt;
&lt;li&gt;Multilingual support&lt;/li&gt;
&lt;li&gt;Historical match simulation&lt;/li&gt;
&lt;li&gt;Mobile application&lt;/li&gt;
&lt;li&gt;Coach-focused analytics&lt;/li&gt;
&lt;li&gt;Advanced visualizations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Project Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://github.com/DigitalPritam1/third-umpire-ai?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://pritam.org?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;My Website (pritam.org)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 &lt;a href="https://www.linkedin.com/in/pritam-sonone/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;LinkedIn Profile&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📺 &lt;a href="https://www.youtube.com/@DigitalPritam?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Digital Pritam YouTube Channel&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  👨‍💻 About Me
&lt;/h2&gt;

&lt;p&gt;I am Pritam Sonone Pritam Sonone, an AI builder, WordPress contributor, digital creator, and founder of Amhi Kastkar and Digital Pritam.&lt;/p&gt;

&lt;p&gt;My mission is to use technology, artificial intelligence, and education to create meaningful products that solve real-world problems and empower people at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏏 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Third Umpire AI started as an idea at a community event, but it represents something much bigger.&lt;/p&gt;

&lt;p&gt;It demonstrates how domain expertise, creativity, and modern AI tools can combine to build products that are both technically sophisticated and genuinely useful.&lt;/p&gt;

&lt;p&gt;For me, this project is where three passions meet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cricket&lt;/li&gt;
&lt;li&gt;Artificial Intelligence&lt;/li&gt;
&lt;li&gt;Product Innovation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is only the first innings.&lt;/p&gt;




&lt;h2&gt;
  
  
  📣 Special Mention
&lt;/h2&gt;

&lt;p&gt;Special thanks to the GDG Cloud Pune GDG Cloud Pune community for organizing Agentic Premier League – Build with AI and creating an inspiring environment for builders to innovate.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7i2nify4i6cnsgdbmit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh7i2nify4i6cnsgdbmit.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>ai</category>
      <category>gdgpune</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🏏 Building "Captain Cool": A Multi-Agent IPL Strategist with Google Antigravity &amp; Gemini 2.5</title>
      <dc:creator>ARNAV AHIRRAO</dc:creator>
      <pubDate>Sun, 17 May 2026 13:06:47 +0000</pubDate>
      <link>https://bizarro.forem.com/arnav_ahirrao/building-captain-cool-a-multi-agent-ipl-strategist-with-google-antigravity-gemini-25-6h5</link>
      <guid>https://bizarro.forem.com/arnav_ahirrao/building-captain-cool-a-multi-agent-ipl-strategist-with-google-antigravity-gemini-25-6h5</guid>
      <description>&lt;p&gt;Cricket is a captain's game. It’s not just about the numbers; it’s about the gut feeling, the matchup risks, and anticipating what the opposition will do next.&lt;/p&gt;

&lt;p&gt;For the Google Gemini Hackathon, I had 3 hours to build an agentic AI system that makes tactical decisions like a real IPL captain. But I didn't want a generic chatbot that just spits out cricket trivia. I wanted a system that debates itself before committing to a call.&lt;/p&gt;

&lt;p&gt;Enter Captain Cool: a multi-agent orchestration engine built entirely on the Google Gemini stack.&lt;/p&gt;

&lt;p&gt;Here is how I built it using Google Antigravity, the google-genai SDK, and zero bloated frameworks.&lt;/p&gt;

&lt;p&gt;🏗️ The Architecture: A Three-Agent Debate Loop&lt;/p&gt;

&lt;p&gt;To make genuinely good cricket decisions, the system cannot wear four hats in a single API call. It needs distinct, isolated personas that pass context back and forth.&lt;/p&gt;

&lt;p&gt;I designed a 3-agent cyclic reasoning loop, overseen by a final Synthesizer:&lt;/p&gt;

&lt;p&gt;📊 The Stats Analyst: The anchor. This agent is strictly forbidden from giving advice. Its only job is to look at the match context and spit out raw data, matchups, pitch conditions, and historical trends.&lt;/p&gt;

&lt;p&gt;🎯 The Strategist: The decision-maker. It takes the Analyst's data and proposes an actionable plan (batting order, bowling rotation, field setups).&lt;/p&gt;

&lt;p&gt;⚠️ The Devil's Advocate: The stress-tester. It looks at the Strategist's plan, finds the biggest assumption or worst-case scenario (e.g., "What if we lose another wicket in the powerplay?"), and forces the Strategist to defend or adapt.&lt;/p&gt;

&lt;p&gt;These three agents loop for a configurable number of rounds, building a shared conversation history. Once the debate concludes, the Head Coach (Synthesizer) agent reads the entire transcript and outputs one definitive, battle-ready Markdown document.&lt;/p&gt;

&lt;p&gt;🛠️ The Tech Stack (Google In-House)&lt;/p&gt;

&lt;p&gt;Model: gemini-2.5-flash (Fast, highly capable, and perfect for multi-turn reasoning).&lt;/p&gt;

&lt;p&gt;SDK: Pure google-genai (Python). I intentionally avoided LangChain or AutoGen to keep the orchestration lightweight and fully custom.&lt;/p&gt;

&lt;p&gt;IDE: Google Antigravity. This was the secret weapon. I used Antigravity as an agentic pair-programmer to vibe-code the directory structure, wire up the Pydantic data schemas, and debug live API errors in real-time.&lt;/p&gt;

&lt;p&gt;🧠 The Prompts that Drive the Debate&lt;/p&gt;

&lt;p&gt;The magic is entirely in the system instructions. Here is how I scoped the Devil's Advocate to ensure it didn't just disagree for the sake of it, but actually improved the strategy:&lt;/p&gt;

&lt;p&gt;ROLE: Your job is to stress-test the Strategist's plan and expose every assumption, gap, and risk. You are not contrarian for its own sake — you are the last line of defence against overconfident planning.&lt;/p&gt;

&lt;p&gt;RESPONSIBILITIES:&lt;/p&gt;

&lt;p&gt;Identify the single biggest assumption in the Strategist's plan and challenge it with a realistic counter-scenario.&lt;/p&gt;

&lt;p&gt;Propose the most dangerous opposition counter-strategy.&lt;/p&gt;

&lt;p&gt;Model the "bad day" scenario: if 2-3 things go wrong simultaneously, does the plan have a recovery path?&lt;/p&gt;

&lt;p&gt;CONSTRAINTS:&lt;/p&gt;

&lt;p&gt;You MUST propose an alternative or a mitigation for every risk you raise.&lt;/p&gt;

&lt;p&gt;🔥 Scenario Walkthrough: PBKS hunting 222 vs RCB&lt;/p&gt;

&lt;p&gt;To test the system, I fed it a brutal, high-pressure match state: Punjab Kings are 10/1 after 1.3 overs. They are chasing Royal Challengers Bengaluru's massive 222-run total at Dharamshala. Here is how the multi-agent system handled it:&lt;/p&gt;

&lt;p&gt;Turn 1: Stats Analyst&lt;br&gt;
The Analyst instantly flagged the pitch as batting-friendly, but noted the required run rate was already north of 11 RPO. It highlighted that with Shikhar Dhawan out early, the powerplay metrics were deeply compromised.&lt;/p&gt;

&lt;p&gt;Turn 2: Strategist&lt;br&gt;
The Strategist proposed sending in Liam Livingstone at No. 3 as an "Anchor-Accelerator Hybrid," tasked with hitting boundaries from ball one, followed by Sam Curran to stabilize if another wicket fell. It mandated reaching 55-60 runs by the end of the powerplay.&lt;/p&gt;

&lt;p&gt;Turn 3: Devil's Advocate&lt;br&gt;
The Advocate jumped in, pointing out a critical flaw: relying on Livingstone to anchor and accelerate is a high-risk paradox. If Livingstone falls early trying to hit, the middle order is exposed to RCB's spinners with no momentum. The Advocate demanded a strict contingency plan if PBKS found themselves at 30/3.&lt;/p&gt;

&lt;p&gt;The Output:&lt;br&gt;
The final synthesized strategy explicitly mapped out the batting order, the required run-rate milestones per over, and the exact "In-Match Triggers" for when to abandon the plan and swing for the fences.&lt;/p&gt;

&lt;p&gt;[ 📸 Insert Screenshot of your Terminal output here showing the debate ]&lt;/p&gt;

&lt;p&gt;[ 📸 Insert Screenshot of your final Markdown output here ]&lt;/p&gt;

&lt;p&gt;🚧 Building Challenges &amp;amp; Antigravity to the Rescue&lt;/p&gt;

&lt;p&gt;Building this in a 3-hour window wasn't without hurdles.&lt;/p&gt;

&lt;p&gt;Initially, the 3-agent loop fired so fast that it tripped the API rate limits (429 RESOURCE_EXHAUSTED). Instead of abandoning the multi-agent design, I used Google Antigravity to dynamically inject pacing (time.sleep(15)) into the orchestrator loop.&lt;/p&gt;

&lt;p&gt;Later, we hit a 404 NOT_FOUND error because I was trying to call legacy models. Antigravity helped me quickly refactor the class definitions to hardcode gemini-2.5-flash, ensuring perfect execution within the hackathon environment constraints.&lt;/p&gt;

&lt;p&gt;🏆 Conclusion&lt;/p&gt;

&lt;p&gt;Cricket strategy is complex, but by decomposing the problem into distinct analytical, strategic, and critical personas, Gemini 2.5 proved it can reason through a T20 match just as well as the commentators in the box.&lt;/p&gt;

&lt;p&gt;Code is live on GitHub! Bring the heat. 🏏&lt;/p&gt;

</description>
      <category>gdgcloudpune</category>
    </item>
    <item>
      <title>Build with AI - APL GDG Pune</title>
      <dc:creator>Aaryan Gupta</dc:creator>
      <pubDate>Sun, 17 May 2026 13:06:37 +0000</pubDate>
      <link>https://bizarro.forem.com/aaryan_gupta_8/build-with-ai-apl-gdg-pune-3</link>
      <guid>https://bizarro.forem.com/aaryan_gupta_8/build-with-ai-apl-gdg-pune-3</guid>
      <description>&lt;p&gt;📊 Analyst Output:&lt;br&gt;
"Venue verified as Mumbai. Tool execution confirmed: Surface is a flat highway with high moisture levels. Humidity tracking at 72%. The leather will be exceptionally difficult to grip for spin bowling."&lt;/p&gt;

&lt;p&gt;⚖️ Devil's Advocate Challenge:&lt;br&gt;
"Look at the match-ups. Shivam Dube has a historic strike rate of over 165 against leg-spin, and with the dew setting in at Wankhede, Piyush Chawla won't be able to grip the seam or control his lengths. Throwing spin here is absolute suicide. The numbers demand that we deploy Jasprit Bumrah right now. We must break this partnership immediately and choke the run-rate, even if it leaves us completely thin at the death."&lt;/p&gt;

&lt;p&gt;🧢 Captain Cool’s Final Call:&lt;br&gt;
"The Advocate is reading the spreadsheet perfectly, but he's panicking. If you burn Bumrah in the 16th over completely out of fear, you give away the entire game on a platter in the 19th and 20th.&lt;/p&gt;

&lt;p&gt;Here's the play: We save Bumrah for the death overs where he belongs. Instead, we hand the ball to Hardik. We tell him to roll his fingers over the seam, bowl into the surface, and rely entirely on heavy cutters into the body. Take all the pace off the ball. On this wet outfield, if we don't give Dube any raw pace to work with, he has to clear long boundaries entirely on his own muscle power. We'll drop deep square leg right to the boundary rope and pull mid-off inside the circle to bait him into the miscue. This is where we break the chase."&lt;/p&gt;

&lt;p&gt;🚀 Key Takeaways &amp;amp; The Developer Journey&lt;br&gt;
Building "Captain Cool" during this 3-hour vibe-coding session highlighted the massive paradigm shift happening in AI architecture. Prompting a single model to act as a sports strategist results in generic, safe, and boring commentary.&lt;/p&gt;

&lt;p&gt;By utilizing Google Antigravity to quickly manage environment lifecycles and using the ADK to isolate distinct, conflicting system instructions, the system successfully recreated the tension, contrast, and ultimate clarity of an elite sports brain trust.&lt;/p&gt;

&lt;p&gt;The future of sports analytics isn't static graphs; it's interactive, adversarial reasoning.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>analytics</category>
      <category>showdev</category>
    </item>
    <item>
      <title>STRAT- built for the last over</title>
      <dc:creator>Saee Kumbhar</dc:creator>
      <pubDate>Sun, 17 May 2026 13:06:24 +0000</pubDate>
      <link>https://bizarro.forem.com/saeeekumbhar/strat-built-for-the-last-over-4gmo</link>
      <guid>https://bizarro.forem.com/saeeekumbhar/strat-built-for-the-last-over-4gmo</guid>
      <description>&lt;p&gt;STRAT is an AI-powered IPL tactical command center built to simulate how real cricket captains think under pressure. Instead of behaving like a generic chatbot, STRAT creates a live “AI war room” where multiple Gemini-powered agents collaborate, challenge each other, and debate tactics before arriving at a final decision. The idea behind the project was simple: cricket is a captain’s game, where small tactical calls — bowling changes, field placements, matchup decisions, or timeout timing — can completely shift momentum. STRAT analyzes live or custom match situations using inputs like score, overs, wickets, pitch conditions, dew factor, venue, bowling resources, and required run rate to generate realistic tactical recommendations.&lt;/p&gt;

&lt;p&gt;Key features of STRAT include:&lt;/p&gt;

&lt;p&gt;• 🧠 Multi-agent AI orchestration with distinct roles like Strategist, Stats Analyst, Devil’s Advocate, and Commentator&lt;br&gt;
• 📊 Real-time tactical reasoning using matchups, momentum, and contextual cricket intelligence&lt;br&gt;
• 😈 Internal AI debate loops where agents challenge and revise strategies before finalizing decisions&lt;br&gt;
• 🏏 Live Match Center for ongoing IPL analysis and a Strategy Sandbox for custom simulations&lt;br&gt;
• 🎯 Interactive field visualization with tactical overlays, ball trajectories, and dynamic field placements&lt;br&gt;
• 📈 Momentum tracking, pressure analysis, confidence scoring, and “What If?” tactical simulations&lt;/p&gt;

&lt;p&gt;The platform was designed to feel more like a Formula 1 pit-wall or tactical sports operating system rather than a traditional dashboard. Built using Next.js, TypeScript, Tailwind CSS, Framer Motion, Zustand, and Gemini 2.5 Pro/Flash, STRAT explores how AI can move beyond basic chat interfaces into collaborative, explainable, and immersive decision-making systems. The goal wasn’t just to predict outcomes, but to create an experience where users can genuinely think like IPL captains in real time — analyzing pressure, debating strategies, and making smarter tactical calls ball by ball.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2vo0m3zn54firk79yxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2vo0m3zn54firk79yxp.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gdgcloudpune</category>
      <category>gdgpune</category>
      <category>google</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>I Built an AI IPL War Room Using Gemini Multi-Agent Reasoning 🏏</title>
      <dc:creator>Mrunalini pachpute</dc:creator>
      <pubDate>Sun, 17 May 2026 13:06:16 +0000</pubDate>
      <link>https://bizarro.forem.com/mrunalini_pachpute_bf0b2e/i-built-an-ai-ipl-war-room-using-gemini-multi-agent-reasoning-1af7</link>
      <guid>https://bizarro.forem.com/mrunalini_pachpute_bf0b2e/i-built-an-ai-ipl-war-room-using-gemini-multi-agent-reasoning-1af7</guid>
      <description>&lt;p&gt;&lt;strong&gt;What if an IPL captain had an AI tactical war room?&lt;/strong&gt;&lt;br&gt;
Not a chatbot:)&lt;/p&gt;

&lt;p&gt;A system where multiple AI agents debate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who bowls next&lt;/li&gt;
&lt;li&gt;whether Bumrah should bowl now or later&lt;/li&gt;
&lt;li&gt;when to attack&lt;/li&gt;
&lt;li&gt;how dew changes strategy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That idea became CaptainCool AI — a multi-agent IPL strategist powered by Google Gemini.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧠 The Core Idea&lt;/strong&gt;&lt;br&gt;
Most sports AI apps generate one generic answer.&lt;/p&gt;

&lt;p&gt;But real cricket decisions involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;disagreement&lt;/li&gt;
&lt;li&gt;tactical tradeoffs&lt;/li&gt;
&lt;li&gt;risk analysis&lt;/li&gt;
&lt;li&gt;momentum shifts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of one AI model pretending to do everything, I built:&lt;br&gt;
an AI captaincy war room.&lt;br&gt;
⚡ Multi-Agent System&lt;/p&gt;

&lt;p&gt;CaptainCool AI uses multiple Gemini-powered agents:&lt;/p&gt;

&lt;p&gt;1.🧠 Strategist&lt;br&gt;
Proposes the tactical move.&lt;/p&gt;

&lt;p&gt;2.📊 Stats Analyst&lt;br&gt;
Validates the decision using cricket context and live match state.&lt;/p&gt;

&lt;p&gt;3.🔥 Devil’s Advocate&lt;br&gt;
Challenges risky plans and forces reconsideration.&lt;/p&gt;

&lt;p&gt;4.👑 Final Decision Engine&lt;br&gt;
Combines all debate outcomes into the final captaincy call.&lt;/p&gt;

&lt;p&gt;5.🎙️ Commentary Agent&lt;br&gt;
Turns the reasoning into IPL-style live commentary.&lt;/p&gt;

&lt;p&gt;The result feels far more human than a normal chatbot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CaptainCool AI operates in two different modes:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 Manual Tactical Mode
&lt;/h3&gt;

&lt;p&gt;Users can manually simulate IPL scenarios by entering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;score&lt;/li&gt;
&lt;li&gt;wickets&lt;/li&gt;
&lt;li&gt;overs&lt;/li&gt;
&lt;li&gt;pitch conditions&lt;/li&gt;
&lt;li&gt;dew factor&lt;/li&gt;
&lt;li&gt;captain style&lt;/li&gt;
&lt;li&gt;impact player availability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mode was designed for cinematic tactical simulations and reliable demo scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔴 Live Match Beta Mode
&lt;/h3&gt;

&lt;p&gt;I integrated CricAPI to fetch live cricket matches and auto-fill the tactical dashboard in real time.&lt;/p&gt;

&lt;p&gt;The system processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;score&lt;/li&gt;
&lt;li&gt;wickets&lt;/li&gt;
&lt;li&gt;overs&lt;/li&gt;
&lt;li&gt;venue&lt;/li&gt;
&lt;li&gt;batting side&lt;/li&gt;
&lt;li&gt;match pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and feeds that directly into the Gemini reasoning pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎨 Frontend Experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted the app to feel like an IPL broadcast control room.&lt;/p&gt;

&lt;p&gt;So the UI includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dark navy gradients&lt;/li&gt;
&lt;li&gt;cyan + gold accents&lt;/li&gt;
&lt;li&gt;glassmorphism cards&lt;/li&gt;
&lt;li&gt;animated confidence bars&lt;/li&gt;
&lt;li&gt;cricket-ball loading animations&lt;/li&gt;
&lt;li&gt;sequential agent debate reveals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express.js&lt;/li&gt;
&lt;li&gt;EJS&lt;/li&gt;
&lt;li&gt;Gemini 2.5 Flash&lt;/li&gt;
&lt;li&gt;CricAPI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🧩 Biggest Challenges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.Multi-Agent Coordination&lt;br&gt;
Making agents genuinely disagree instead of repeating similar answers.&lt;/p&gt;

&lt;p&gt;2.API Quotas&lt;br&gt;
Multi-agent reasoning consumes API calls quickly, so responses had to be optimized carefully.&lt;/p&gt;

&lt;p&gt;3.Live Match Data&lt;br&gt;
Live cricket feeds often return incomplete data, requiring normalization and fallback handling.&lt;/p&gt;

&lt;p&gt;📈 What I Learned&lt;br&gt;
The biggest insight was:&lt;br&gt;
AI systems become dramatically more believable when agents disagree instead of instantly agreeing.&lt;br&gt;
That tactical conflict made CaptainCool AI feel much more realistic.&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>gdgcloud</category>
      <category>gdgcloudpune</category>
      <category>gdg</category>
    </item>
    <item>
      <title>🏏 Building "Captain Cool": A Multi-Agent IPL Strategist with Google Gemini</title>
      <dc:creator>Vaishnavi Bardapure</dc:creator>
      <pubDate>Sun, 17 May 2026 13:05:21 +0000</pubDate>
      <link>https://bizarro.forem.com/vaishnavi_bardapure_b373c/building-captain-cool-a-multi-agent-ipl-strategist-with-google-gemini-2n0a</link>
      <guid>https://bizarro.forem.com/vaishnavi_bardapure_b373c/building-captain-cool-a-multi-agent-ipl-strategist-with-google-gemini-2n0a</guid>
      <description>&lt;p&gt;Cricket is a captain's game. The margin between an IPL trophy and crashing out in the playoffs is often a single, split-second tactical decision: who bowls the 19th over? Do you bring in the spinner against the left-hander? What happens when the dew sets in?&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;APL GDG Hackathon&lt;/strong&gt;, I wanted to simulate the high-pressure environment of an IPL dugout. I built &lt;strong&gt;Captain Cool&lt;/strong&gt; — a Multi-Agent AI System powered entirely by the Google Gemini stack that debates and makes real-time tactical cricket decisions.&lt;/p&gt;

&lt;p&gt;Here is how I built it.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The Architecture (The Coaching Staff)
&lt;/h2&gt;

&lt;p&gt;To make this truly &lt;em&gt;agentic&lt;/em&gt;, one LLM call wasn't going to cut it. A real captain doesn't operate in a vacuum—they rely on data analysts and vice-captains. &lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;Google GenAI SDK&lt;/strong&gt; and the blazing fast &lt;code&gt;gemini-2.5-flash&lt;/code&gt; model, I orchestrated a 3-agent debate loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;📊 &lt;strong&gt;The Stats Analyst:&lt;/strong&gt; This agent doesn't guess. It uses &lt;strong&gt;Gemini Function Calling&lt;/strong&gt; to hit my custom Python tools (&lt;code&gt;get_player_stats&lt;/code&gt;, &lt;code&gt;get_venue_stats&lt;/code&gt;) to pull raw numbers on strike rates, matchups, and pitch conditions based on the live match state.&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;The Strategist (The Captain):&lt;/strong&gt; Takes the raw match state and the Analyst's data to propose the next tactical move.&lt;/li&gt;
&lt;li&gt;⚖️ &lt;strong&gt;The Devil's Advocate (The Vice-Captain):&lt;/strong&gt; This is where the magic happens. The Vice-Captain is explicitly prompted to find flaws in the Captain's plan, highlight contrarian angles (like dew factor), and prevent groupthink.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Captain then takes the critique, revises or defends the plan, and makes the &lt;strong&gt;Final Call&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD
    M[Live Match State] --&amp;gt; A(Stats Analyst)
    A --&amp;gt;|Function Calling| D[(Cricket Stats API)]
    D --&amp;gt;|Stats| A
    A --&amp;gt;|Stats Summary| S(Strategist - Captain)
    M --&amp;gt; S
    S --&amp;gt;|Initial Proposal| V(Devil's Advocate)
    V --&amp;gt;|Critique &amp;amp; Risks| S
    S --&amp;gt;|Final Decision| O[Final Output UI]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🗣️ The System Prompts
&lt;/h2&gt;

&lt;p&gt;The secret sauce to getting authentic cricket commentary rather than generic ML jargon was in the System Prompts. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Captain's Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You are 'Captain Cool', an elite IPL match strategist (think MS Dhoni or Rohit Sharma). You will receive the current match state and a data summary from your Stats Analyst. Your task is to make the next tactical decision: e.g., who should bowl the next over, field placement, bringing in the Impact Player, etc. Explain your reasoning in authentic cricket terminology. Be decisive and clear in your proposal."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The Vice-Captain's Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You are the Devil's Advocate (Vice-Captain) of an IPL team. Your job is to listen to the Captain's tactical proposal and find the flaws in it. Look for contrarian angles: what if the pitch is behaving differently? What if the matchups are misleading? What about dew? Suggest a smart alternative or highlight the primary risk of the Captain's plan. Speak in sharp, analytical cricket terms."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🏏 Walkthrough: An End-to-End Match Scenario
&lt;/h2&gt;

&lt;p&gt;Let's look at how the agents handle a classic death-overs scenario:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Innings:&lt;/strong&gt; 2nd Innings (Run Chase)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score:&lt;/strong&gt; 145/4 (Over 17.5) | &lt;strong&gt;Target:&lt;/strong&gt; 175&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Matchup:&lt;/strong&gt; RCB (Batting) vs MI (Bowling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At the Crease:&lt;/strong&gt; Virat Kohli (55 off 38) &amp;amp; Dinesh Karthik (12 off 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bowling Options:&lt;/strong&gt; Hardik Pandya is finishing his spell. Jasprit Bumrah has 1 over left.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Wankhede Stadium. Heavy dew is setting in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Insert a screenshot of the Streamlit UI Match Config here!)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Debate Unfolds:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;📊 Stats Analyst:&lt;/strong&gt; &lt;em&gt;Pulls data via tools.&lt;/em&gt; Highlights that Kohli is vulnerable to left-arm pace outside off, but dominates spin. Bumrah has a 7.8 death overs economy and a massive 82.3% yorker accuracy, having dismissed Kohli 4 times. Wankhede has a heavy dew factor which makes gripping the ball difficult.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧠 Captain (Initial Plan):&lt;/strong&gt; Suggests bringing Bumrah in immediately for the 18th over to get Kohli out before he can launch in the 19th and 20th. Keep Pandya out of the attack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚖️ Vice-Captain (Critique):&lt;/strong&gt; "Hold on skip. With the heavy dew, the ball is going to resemble a bar of soap. If Bumrah bowls the 18th, who bowls the 19th and 20th? We risk saving our weaker bowlers for the final overs when the dew is at its absolute worst. We need Bumrah for the 19th."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🏆 Final Call:&lt;/strong&gt; The Captain agrees with the critique. "Fair point. The dew is a massive factor. We bowl Akash Madhwal for the 18th over, stack the off-side to force Kohli to hit against the spin of the wet ball, and save Bumrah's yorkers for the crucial 19th over."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;(Insert a screenshot of the Chat UI showing the final decision here!)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The Tech Stack &amp;amp; Google Integration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; &lt;code&gt;gemini-2.5-flash&lt;/code&gt; for lightning-fast, multi-turn reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK:&lt;/strong&gt; Google GenAI Python SDK (&lt;code&gt;google-genai&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Use:&lt;/strong&gt; Native Gemini Function Calling hooked into a custom Python dictionary of IPL stats.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE:&lt;/strong&gt; Vibe-coded entirely inside &lt;strong&gt;Google Antigravity&lt;/strong&gt; (Google's agentic IDE).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI &amp;amp; Hosting:&lt;/strong&gt; Built with Streamlit and deployed live on Streamlit Community Cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏆 Conclusion
&lt;/h2&gt;

&lt;p&gt;By breaking the problem down into a multi-agent system, the AI was forced to self-correct and consider environmental factors (like dew and bowler workload) that a single zero-shot prompt usually misses. &lt;/p&gt;

&lt;p&gt;Check out the live app here: &lt;em&gt;(Insert your Streamlit Cloud URL here!)&lt;/em&gt;&lt;br&gt;
Check out the code on GitHub: &lt;a href="https://github.com/VaishnaviBardapure/CaptainCool" rel="noopener noreferrer"&gt;github.com/VaishnaviBardapure/CaptainCool&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built for the APL GDG Hackathon.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  GDGCLOUDPUNE
&lt;/h1&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>gemini</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Agentic coding isn't a trap. Lazy engineering is.</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Sun, 17 May 2026 13:05:03 +0000</pubDate>
      <link>https://bizarro.forem.com/adioof/agentic-coding-isnt-a-trap-lazy-engineering-is-496h</link>
      <guid>https://bizarro.forem.com/adioof/agentic-coding-isnt-a-trap-lazy-engineering-is-496h</guid>
      <description>&lt;p&gt;The hottest take in developer discourse right now isn't about frameworks or languages. It's about whether AI agents are silently destroying your codebase.&lt;/p&gt;

&lt;p&gt;A viral post recently called agentic coding a "liability accelerator." It painted a picture of codebases rotting from the inside out, maintained by developers who no longer understand what they've built. The post spread fast. Engineers nodded along. And I think they're blaming the wrong thing entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem has a name
&lt;/h2&gt;

&lt;p&gt;The issue is not with the representative. It is with the approach that exists, or the absence of it.&lt;/p&gt;

&lt;p&gt;A counterpoint article on Dev.to actually provided production logs from a team that was using agents that had very precise well-written specs, and the results were clean output, actually, predictable output, and fewer bugs than we had experienced in their pre-agent workflow.&lt;/p&gt;

&lt;p&gt;What made a difference was not the tool used, but rather that an individual took the time to write a solid specification before using the generation tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agents don't skip code review. You do.
&lt;/h2&gt;

&lt;p&gt;This is what goes down in reality when agentic coding flops:&lt;/p&gt;

&lt;p&gt;→ Developer gives a vague prompt with no constraints&lt;br&gt;
→ Agent produces plausible-looking code that technically works&lt;br&gt;
→ Developer ships it without reading it carefully&lt;br&gt;
→ Three months later, nobody understands the module&lt;/p&gt;

&lt;p&gt;Sound familiar? Now substitute "agent" with "junior developer" or "Stack Overflow copy-paste" or "that contractor we hired for two weeks." The end result is the same. Throughout history, we've found ways to write code that escapes our comprehension. Agents just automated the process.&lt;/p&gt;

&lt;p&gt;It's the speed that frightens everyone. I understand. However, it was never the problem. Being reckless was.&lt;/p&gt;

&lt;h2&gt;
  
  
  The codebase comprehension problem is real but not new
&lt;/h2&gt;

&lt;p&gt;The biggest legitimate concern is that developers stop understanding their own systems. That's worth taking seriously. 🧠&lt;/p&gt;

&lt;p&gt;However, we have to admit that this was already in motion. Enormous monorepos, automatically created boilerplate code, dependency trees that no one checks, copying and pasting infrastructure-as-code templates from blog posts. In fact, most teams were already working without a complete understanding of their stack.&lt;/p&gt;

&lt;p&gt;Agents were not responsible for the comprehension gap. They simply brought it to our attention.&lt;/p&gt;

&lt;p&gt;We shouldn't eliminate the tool.  But regard agent output as any other contributed code:  review it, test it, understand it before it merges.  If your team lacks that discipline, you had a process problem long before you had an AI problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What good agentic workflows actually look like
&lt;/h2&gt;

&lt;p&gt;Agents tend to provide real value to teams that have a few things in common:&lt;/p&gt;

&lt;p&gt;→ They write detailed specs &lt;em&gt;before&lt;/em&gt; prompting — acceptance criteria, edge cases, constraints&lt;br&gt;
→ They review agent output line by line, same as a human PR&lt;br&gt;
→ They use agents for the boring stuff — boilerplate, tests, migrations — not architecture decisions&lt;br&gt;
→ They treat the agent like a fast but inexperienced teammate, not an oracle&lt;/p&gt;

&lt;p&gt;All of this is evolutionary. It's engineering discipline being applied to a new-fangled tool. The type of discipline we've always known we needed, but often conveniently overlooked. 😅&lt;/p&gt;

&lt;h2&gt;
  
  
  The uncomfortable truth
&lt;/h2&gt;

&lt;p&gt;Blaming agents for tech debt is comfortable. It gives us an external villain.&lt;/p&gt;

&lt;p&gt;The developers who are now shipping unreviewed agent code are the ones who shipped unreviewed human code before. They are the ones who neglected to write tests. The same ones who approved their PRs on a Friday afternoon. The process may have changed, but their habits haven't.&lt;/p&gt;

&lt;p&gt;Writing code in a way that reflects your engineering culture is not a bad thing. It's not a trap. It's a mirror. It shows you what you are. And it does so faster and more honestly than ever before. If you don’t like what you see, the problem isn’t the reflection.&lt;/p&gt;

&lt;p&gt;Good process makes agents a multiplier. Bad process makes agents a liability accelerator. The variable was never the agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So here's my question: has your team established any specific rules or review practices for agent-generated code, or is it still the Wild West?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agentcoding</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Learning the Web Platform APIs As If You Built Them Yourself</title>
      <dc:creator>Mohamed Idris</dc:creator>
      <pubDate>Sun, 17 May 2026 13:05:00 +0000</pubDate>
      <link>https://bizarro.forem.com/edriso/learning-the-web-platform-apis-as-if-you-built-them-yourself-3o14</link>
      <guid>https://bizarro.forem.com/edriso/learning-the-web-platform-apis-as-if-you-built-them-yourself-3o14</guid>
      <description>&lt;p&gt;If you have ever reached for a library to do something the browser already does, you have met the gap this post is about. Need a debounce? You wrote a &lt;code&gt;useEffect&lt;/code&gt;. Need to detect when a card scrolls into view? You added a 300 line library. Need offline support? You shrugged and gave up.&lt;/p&gt;

&lt;p&gt;The browser has changed. Modern browsers ship a generous, capable platform. Most of the libraries we still install in 2026 were written when the platform was missing the feature. They are not missing anymore.&lt;/p&gt;

&lt;p&gt;A senior frontend engineer knows what the browser already gives them, and reaches for it before reaching for npm.&lt;/p&gt;

&lt;p&gt;That is the gap this post fills.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the web platform, really
&lt;/h2&gt;

&lt;p&gt;Think of the browser as &lt;strong&gt;a small operating system that runs in a tab&lt;/strong&gt;. It has storage, a network stack, threads, scheduling, sensors, sometimes even a file system and Bluetooth. Each capability has an API. Many of them are excellent. Many of them are five lines of code instead of a 12KB dependency.&lt;/p&gt;

&lt;p&gt;Two ideas drive the whole thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The platform is doing more than you think.&lt;/strong&gt; Capabilities ship every six weeks across all the major browsers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promises and observers are the shape.&lt;/strong&gt; Most modern APIs are either &lt;code&gt;await&lt;/code&gt;able or "watch this thing and call me back".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the whole vibe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's pretend we are building one
&lt;/h2&gt;

&lt;p&gt;We are not building the platform. We are doing a senior level tour of it. For the running example, we will sprinkle a tiny &lt;strong&gt;read later&lt;/strong&gt; notes app with native APIs as we go. Save notes offline, fetch articles, observe the page, schedule work, broadcast across tabs.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 1: &lt;code&gt;fetch&lt;/code&gt; (and AbortController), the network everyone forgets has features
&lt;/h2&gt;

&lt;p&gt;Every frontend engineer knows &lt;code&gt;fetch&lt;/code&gt;. Half of them only use 20% of it.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Read later&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// send cookies on cross origin requests&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// override default&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// also "same-origin", "no-cors"&lt;/span&gt;
  &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="nx"&gt;ctrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// AbortController&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The features senior engineers actually use:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;AbortController&lt;/code&gt; for cancelling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&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;timer&lt;/span&gt; &lt;span class="o"&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;ctrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 5s timeout&lt;/span&gt;

&lt;span class="k"&gt;try&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ctrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&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;The same &lt;code&gt;AbortController&lt;/code&gt; works with &lt;code&gt;addEventListener&lt;/code&gt;, with most modern Promise APIs, and with React Query's queries. Make it your default mental model: any long lived async work should be cancellable.&lt;/p&gt;

&lt;p&gt;The shortcut for "fetch with timeout":&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AbortSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&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;h3&gt;
  
  
  Streaming responses
&lt;/h3&gt;

&lt;p&gt;The body is a &lt;code&gt;ReadableStream&lt;/code&gt;. You can consume it as it arrives, perfect for AI streaming or large downloads:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/stream&lt;/span&gt;&lt;span class="dl"&gt;"&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;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipeThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoderStream&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;getReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&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="s2"&gt;chunk:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;h3&gt;
  
  
  &lt;code&gt;Response&lt;/code&gt; and &lt;code&gt;Request&lt;/code&gt; are real classes
&lt;/h3&gt;

&lt;p&gt;You can build them, store them, clone them. Service Workers rely on this. The same &lt;code&gt;Response&lt;/code&gt; API you receive from &lt;code&gt;fetch&lt;/code&gt; is the one you return from a Service Worker.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 2: Storage, three flavors
&lt;/h2&gt;

&lt;p&gt;The browser has three storage mechanisms. Pick on purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;sessionStorage&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Tiny key value store. Synchronous. Strings only. Good for: small UI state (theme, last opened tab), tiny preferences. Bad for: anything large, anything secret, anything that should sync.&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="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sessionStorage&lt;/code&gt; is the same, scoped to the tab. Cleared on close.&lt;/p&gt;

&lt;p&gt;A senior level rule: &lt;strong&gt;never store auth tokens in &lt;code&gt;localStorage&lt;/code&gt;&lt;/strong&gt;. JavaScript can read it, which means every third party script can too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cookies
&lt;/h3&gt;

&lt;p&gt;Sent automatically with every same origin request. The browser respects &lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, &lt;code&gt;SameSite&lt;/code&gt;. We covered them in the auth post. Use them for sessions and CSRF tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  IndexedDB, the actual database
&lt;/h3&gt;

&lt;p&gt;A real client side database. Asynchronous. Stores anything structurable, including blobs. Indexed for fast queries. Quotas in the megabytes to gigabytes range.&lt;/p&gt;

&lt;p&gt;The native API is famously verbose. Use a tiny wrapper like &lt;strong&gt;&lt;code&gt;idb-keyval&lt;/code&gt;&lt;/strong&gt; for simple cases or &lt;strong&gt;Dexie.js&lt;/strong&gt; for richer querying.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;del&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;idb-keyval&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;note:42&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Read later&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;"&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;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;note:42&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;note:42&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use IndexedDB for: offline caches, drafts, full text search indexes, large user data, anything you need to survive a refresh and a flaky network. It is the storage that makes serious offline apps possible.&lt;/p&gt;

&lt;p&gt;In 2026 there is also an exciting trend: &lt;strong&gt;SQLite in the browser&lt;/strong&gt;, via wasm libraries like &lt;code&gt;sql.js&lt;/code&gt; and &lt;code&gt;wa-sqlite&lt;/code&gt;, often backed by IndexedDB or the &lt;strong&gt;Origin Private File System (OPFS)&lt;/strong&gt;. Real SQL queries on the client. Worth knowing about for offline first apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 3: Service Workers, the engine of offline
&lt;/h2&gt;

&lt;p&gt;A Service Worker is a script that runs in the background, separate from any page, and can intercept network requests for a whole origin. It is how websites become installable apps that work offline.&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="c1"&gt;// app/main.ts&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serviceWorker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/sw.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// public/sw.js&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;install&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;v1&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;c&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;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/styles.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/app.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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="nx"&gt;cached&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;cached&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What that gives you: the page loads from cache instantly, even offline.&lt;/p&gt;

&lt;p&gt;The senior level patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cache first&lt;/strong&gt; for static assets that change rarely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network first, cache fallback&lt;/strong&gt; for HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale while revalidate&lt;/strong&gt; for API responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a tool, do not hand roll.&lt;/strong&gt; &lt;strong&gt;Workbox&lt;/strong&gt; (Google) and &lt;strong&gt;Vite PWA Plugin&lt;/strong&gt; scaffold a sane Service Worker in a few lines. They handle caching strategies, precaching, runtime caching, navigation fallback, and updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full PWA story (offline + installable + push notifications) is a real thing in 2026. Browsers across Mac, Windows, Linux, Android, and even iOS support it. For an app that runs daily, "Add to Home Screen" is real distribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 4: Web Workers, threads for compute
&lt;/h2&gt;

&lt;p&gt;JavaScript runs on a single thread. Long work blocks the page. A &lt;strong&gt;Web Worker&lt;/strong&gt; runs a script on a separate thread, communicating by message passing.&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="c1"&gt;// worker.ts&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;expensiveCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./worker.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The friendlier modern API: &lt;strong&gt;Comlink&lt;/strong&gt; turns the worker into a proxy you can &lt;code&gt;await&lt;/code&gt;:&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="c1"&gt;// worker.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expose&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comlink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;expose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nf"&gt;parseMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="nf"&gt;slowParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;md&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="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;wrap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comlink&lt;/span&gt;&lt;span class="dl"&gt;"&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;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;parseMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./worker.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&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;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Web Workers for: heavy parsing (Markdown, syntax highlighting, JSON), image processing, data transforms, anything more than 50ms of compute. The page stays smooth, INP stays under 200ms.&lt;/p&gt;

&lt;p&gt;A close cousin: &lt;strong&gt;&lt;code&gt;requestIdleCallback&lt;/code&gt;&lt;/strong&gt; runs a function when the browser is idle. Great for non urgent work like analytics flushing.&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="nf"&gt;requestIdleCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sendQueuedAnalytics&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  API 5: IntersectionObserver, "tell me when this is on screen"
&lt;/h2&gt;

&lt;p&gt;Before this API, "is the element visible" was solved by listening to &lt;code&gt;scroll&lt;/code&gt; and reading layout in a tight loop. It was awful.&lt;/p&gt;

&lt;p&gt;Now:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entries&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="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;entry&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&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="s2"&gt;visible:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;200px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.lazy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;el&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;obs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uses for senior frontends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lazy load images and components&lt;/strong&gt; before they are needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infinite scroll&lt;/strong&gt;: observe a sentinel at the bottom of the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger animations&lt;/strong&gt; when an element scrolls into view.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track impressions&lt;/strong&gt; for analytics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;rootMargin&lt;/code&gt; lets you start the work early, so the user never sees the loading state.&lt;/p&gt;

&lt;p&gt;A close cousin: &lt;strong&gt;&lt;code&gt;ResizeObserver&lt;/code&gt;&lt;/strong&gt; fires when an element changes size. Great for charts, tables, and components that need to re-render on layout changes:&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;new&lt;/span&gt; &lt;span class="nc"&gt;ResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;entry&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="nf"&gt;drawChart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartEl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;strong&gt;&lt;code&gt;MutationObserver&lt;/code&gt;&lt;/strong&gt; for "tell me when the DOM changed". Niche but lifesaving for browser extensions and integrations with markup you do not control.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 6: BroadcastChannel, talking across tabs
&lt;/h2&gt;

&lt;p&gt;If a user has your app open in three tabs and logs out in one, the others should know. &lt;strong&gt;&lt;code&gt;BroadcastChannel&lt;/code&gt;&lt;/strong&gt; posts messages across same origin tabs:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BroadcastChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;goToLogin&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;Five lines, no library. Use it for: logout sync, cache invalidation across tabs, "this item just changed" notifications.&lt;/p&gt;

&lt;p&gt;For more general cross window coordination, the &lt;strong&gt;Web Locks API&lt;/strong&gt; ensures only one tab does a piece of work at a time:&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;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sync-notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;syncNotesWithServer&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;Other tabs that try to acquire the lock will queue. Brilliant for "only one tab should be syncing".&lt;/p&gt;

&lt;h2&gt;
  
  
  API 7: Clipboard, Share, File access, the human integration layer
&lt;/h2&gt;

&lt;p&gt;These are the APIs that make a web app feel native.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clipboard
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&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;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern, async, permission gated. The old &lt;code&gt;document.execCommand("copy")&lt;/code&gt; is deprecated. For images and other rich data, use &lt;code&gt;navigator.clipboard.write&lt;/code&gt; with &lt;code&gt;ClipboardItem&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Share API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;share&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mochi's Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A great post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/post&lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On mobile, this opens the system share sheet. On desktop, it falls back gracefully. One line replaces a custom share modal.&lt;/p&gt;

&lt;h3&gt;
  
  
  File System Access
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showSaveFilePicker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;suggestedName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notes.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.json&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createWritable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real "save as" dialog, real file. Limited to Chromium browsers in 2026 but excellent for productivity apps.&lt;/p&gt;

&lt;p&gt;The simpler alternative for downloads is the venerable &lt;code&gt;&amp;lt;a download&amp;gt;&lt;/code&gt;:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notes.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  API 8: View Transitions, navigation feels smooth
&lt;/h2&gt;

&lt;p&gt;A genuinely magical API. Animate between any two DOM states with one line.&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startViewTransition&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;// any DOM mutation here&lt;/span&gt;
  &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&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;The browser captures a snapshot before, applies your changes, captures after, and animates between them. With CSS &lt;code&gt;view-transition-name&lt;/code&gt; on shared elements, you get FLIP-style transitions for free.&lt;/p&gt;

&lt;p&gt;In 2026, the cross document version (&lt;code&gt;@view-transition&lt;/code&gt;) lets multi page apps animate between full page navigations as smoothly as SPAs. This is one of the reasons SPAs are no longer the only path to good UX.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 9: Scheduler, Idle Detection, and modern timing
&lt;/h2&gt;

&lt;p&gt;The scheduler family of APIs, increasingly supported, gives you fine grained control over priority:&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="c1"&gt;// new in 2024+ browsers&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;        &lt;span class="c1"&gt;// give the browser a frame&lt;/span&gt;
&lt;span class="nx"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;scheduler.yield()&lt;/code&gt; is not available, the polyfill is a &lt;code&gt;setTimeout(0)&lt;/code&gt; plus a microtask check.&lt;/p&gt;

&lt;p&gt;The classic timing tools still matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;requestAnimationFrame&lt;/code&gt;&lt;/strong&gt; for any visual update tied to the next frame. Always use it for animations driven by JS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;performance.now()&lt;/code&gt;&lt;/strong&gt; for high resolution timing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PerformanceObserver&lt;/code&gt;&lt;/strong&gt; to subscribe to LCP, INP, CLS, long tasks, navigation timing, resource timing. This is what &lt;code&gt;web-vitals&lt;/code&gt; is built on.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;list&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="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;entry&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&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="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;longtask&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;layout-shift&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;largest-contentful-paint&lt;/span&gt;&lt;span class="dl"&gt;"&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;Drop into devtools when you want to see what is actually slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 10: Notifications, Push, Background Sync
&lt;/h2&gt;

&lt;p&gt;For "this app feels real" features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Notifications&lt;/strong&gt;: &lt;code&gt;new Notification("Hi")&lt;/code&gt; with permission. Used as the visual layer for Push.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push&lt;/strong&gt;: a Service Worker can receive pushes from your server even when the page is closed. Requires the user to grant permission and your server to send via the Web Push protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background Sync&lt;/strong&gt;: the browser will retry a queued task when the user comes back online. Perfect for "send this comment whenever there is connectivity".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are senior level features. Only enable them where they pay off. Most users have notification fatigue, so ask politely or not at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 11: The "knows about the user" APIs (use sparingly)
&lt;/h2&gt;

&lt;p&gt;The platform has a long tail of "tell me about the device" APIs. Senior engineers know they exist and use them with care.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;matchMedia("(prefers-color-scheme: dark)").matches&lt;/code&gt;&lt;/strong&gt; for theme detection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;matchMedia("(prefers-reduced-motion: reduce)").matches&lt;/code&gt;&lt;/strong&gt; to respect motion preferences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;navigator.connection&lt;/code&gt;&lt;/strong&gt; (Network Information API) for adaptive loading. Slow 3G? Send fewer images.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;document.visibilityState&lt;/code&gt;&lt;/strong&gt; to pause work when the tab is hidden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;navigator.locks&lt;/code&gt;&lt;/strong&gt; (already mentioned).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Battery&lt;/code&gt;, &lt;code&gt;Bluetooth&lt;/code&gt;, &lt;code&gt;USB&lt;/code&gt;, &lt;code&gt;Serial&lt;/code&gt;, &lt;code&gt;Geolocation&lt;/code&gt;&lt;/strong&gt;: each is a permissioned API, useful for very specific apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle: &lt;strong&gt;respect the user, ask before you peek&lt;/strong&gt;. Permission prompts kill conversion if used carelessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 12: Modern selection, drag, paste, undo
&lt;/h2&gt;

&lt;p&gt;A handful of small APIs that delete entire libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getSelection()&lt;/code&gt;&lt;/strong&gt; for the current text selection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;document.execCommand&lt;/code&gt; is deprecated&lt;/strong&gt;. For rich text, use &lt;code&gt;contenteditable&lt;/code&gt; plus a library like &lt;strong&gt;TipTap&lt;/strong&gt; or &lt;strong&gt;Lexical&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;InputEvent&lt;/code&gt;&lt;/strong&gt; with &lt;code&gt;inputType&lt;/code&gt; ("insertText", "deleteContentBackward", etc.) for fine grained input handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;HTMLDialogElement.showModal()&lt;/code&gt;&lt;/strong&gt; for native modals (we covered this in the HTML post).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;&lt;/strong&gt; for native disclosures, no JS needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;input type="search"&amp;gt;&lt;/code&gt;, &lt;code&gt;type="date"&lt;/code&gt;, &lt;code&gt;type="time"&lt;/code&gt;, &lt;code&gt;type="color"&lt;/code&gt;&lt;/strong&gt; for native pickers on mobile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A surprising amount of "I need a library for this" turns into "the browser already does it" once you check first.&lt;/p&gt;

&lt;h2&gt;
  
  
  API 13: WebRTC, WebSockets, SSE, beyond request/response
&lt;/h2&gt;

&lt;p&gt;Three transports for real time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets&lt;/strong&gt; for bidirectional persistent connections. We mentioned this in the HTTP post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-Sent Events&lt;/strong&gt; (&lt;code&gt;EventSource&lt;/code&gt;) for one way streaming from server to client. Simpler than WebSockets, plays nicely with HTTP infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC&lt;/strong&gt; for peer to peer audio, video, and data. The transport behind every browser based video call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most apps need SSE for live updates and never touch the others. Reach for them when you have a specific need (real time collaboration, video, gaming).&lt;/p&gt;

&lt;h2&gt;
  
  
  A peek under the hood
&lt;/h2&gt;

&lt;p&gt;What really happens when you call a platform API:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;JavaScript calls into the browser's C++ implementation.&lt;/li&gt;
&lt;li&gt;The browser does the work (often on another thread or in another process).&lt;/li&gt;
&lt;li&gt;The result comes back as a Promise resolution, an event, or a callback.&lt;/li&gt;
&lt;li&gt;Your code runs in the JS event loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two consequences for senior engineers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native APIs are usually faster than userland equivalents&lt;/strong&gt; because the heavy lifting happens off the main thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser support varies.&lt;/strong&gt; Use &lt;a href="https://caniuse.com" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt; before committing. For features you must have everywhere, polyfills exist. For features that gracefully degrade, feature detect with &lt;code&gt;if ("foo" in window)&lt;/code&gt; and ship the better experience to capable browsers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tiny tips that will save you later
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read MDN.&lt;/strong&gt; It is the single best web platform documentation, and it is free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;caniuse.com&lt;/code&gt;&lt;/strong&gt; before adopting any platform API. Browser share matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature detect, do not user agent sniff.&lt;/strong&gt; &lt;code&gt;if ("share" in navigator)&lt;/code&gt; is the right check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cancel everything.&lt;/strong&gt; &lt;code&gt;AbortController&lt;/code&gt; works with &lt;code&gt;fetch&lt;/code&gt;, with &lt;code&gt;addEventListener&lt;/code&gt;, with most modern APIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use &lt;code&gt;IntersectionObserver&lt;/code&gt; instead of scroll listeners.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;ResizeObserver&lt;/code&gt; instead of window resize listeners&lt;/strong&gt; when you only care about an element.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use &lt;code&gt;BroadcastChannel&lt;/code&gt; for cross tab communication.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;idb-keyval&lt;/code&gt; or Dexie for IndexedDB&lt;/strong&gt; unless you really enjoy callbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Workbox or Vite PWA&lt;/strong&gt; for Service Workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;view-transition&lt;/code&gt; for navigation animations.&lt;/strong&gt; Free polish.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respect &lt;code&gt;prefers-reduced-motion&lt;/code&gt; and &lt;code&gt;prefers-color-scheme&lt;/code&gt;.&lt;/strong&gt; They are one query away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep platform APIs small.&lt;/strong&gt; Wrap each in a tiny module so the call sites do not get noisy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;So that is the whole story. The web platform stopped being a dumb document viewer years ago. Modern browsers ship a small operating system: a network stack with cancellation and streaming, three storage tiers, real threads, real schedulers, observers for everything that used to need a polling loop, broadcast channels for cross tab life, file system access, share sheets, push notifications, and beautiful view transitions.&lt;/p&gt;

&lt;p&gt;A senior frontend engineer treats these as the first toolkit, not the last resort. The libraries on npm exist because the platform was missing the feature. Many features have shipped. Many libraries can come out of your &lt;code&gt;package.json&lt;/code&gt; if you check what the browser already does.&lt;/p&gt;

&lt;p&gt;Once that map is in your head, you write less code, ship smaller bundles, and build apps that feel like the device they run on.&lt;/p&gt;

&lt;p&gt;Happy platforming, and may your dependency list stay short.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
