<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sidharth</title>
    <description>The latest articles on DEV Community by Sidharth (@sidharth_28c750a8437aa781).</description>
    <link>https://dev.to/sidharth_28c750a8437aa781</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4154885%2F12970f1d-679d-4e9b-b4e4-451986204ad0.jpg</url>
      <title>DEV Community: Sidharth</title>
      <link>https://dev.to/sidharth_28c750a8437aa781</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sidharth_28c750a8437aa781"/>
    <language>en</language>
    <item>
      <title>adventure.ai: A Local-AI Field Guide That Gets You Off Your Phone</title>
      <dc:creator>Sidharth</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:11:21 +0000</pubDate>
      <link>https://dev.to/sidharth_28c750a8437aa781/adventureai-a-local-ai-field-guide-that-gets-you-off-your-phone-6ik</link>
      <guid>https://dev.to/sidharth_28c750a8437aa781/adventureai-a-local-ai-field-guide-that-gets-you-off-your-phone-6ik</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Here is the paradox I couldn't stop thinking about: every app that promises to get you outside asks you to look at a screen to do it.&lt;/p&gt;

&lt;p&gt;Trail finders, plant identifiers and step trackers all succeed when you open them, so they are quietly designed to keep you looking. You leave the house to touch grass and spend the walk with your face in a glowing rectangle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;adventure.ai&lt;/strong&gt; flips that goal. The only metric I cared about was how quickly it could get you to put your phone away. It is a local-AI field guide that finds green spaces near you, writes a short mission for the one you pick, and then &lt;em&gt;reads it to you&lt;/em&gt;, so your phone can go into your pocket before you take your first step.&lt;/p&gt;

&lt;p&gt;The whole thing takes about 30 seconds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start anywhere.&lt;/strong&gt; Tap &lt;strong&gt;📍 Find Around Me&lt;/strong&gt; to use live GPS, or type any city and hit &lt;strong&gt;🔍 Explore City&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover.&lt;/strong&gt; The backend queries OpenStreetMap's Overpass API within a 5 km radius for parks, gardens, nature reserves, viewpoints, picnic sites, water, woods and peaks. They appear as clickable pins on an interactive Leaflet map over Esri World Topo tiles. Filter pills (&lt;code&gt;All&lt;/code&gt;, &lt;code&gt;Gardens &amp;amp; Parks&lt;/code&gt;, &lt;code&gt;Viewpoints&lt;/code&gt;, &lt;code&gt;Water &amp;amp; Trails&lt;/code&gt;) cut the noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tap a spot, get a Field Guide.&lt;/strong&gt; A local &lt;strong&gt;Gemma 2 (2B)&lt;/strong&gt; model running in Ollama writes a &lt;em&gt;Touch Grass Field Guide&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vibe:&lt;/strong&gt; one sentence on why to go today&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Activity:&lt;/strong&gt; the one thing worth doing there&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 Nature Spotters:&lt;/strong&gt; local plants, trees or birds to look for&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 Screen-Free Quests:&lt;/strong&gt; physical mini-challenges, each with a checkbox, designed to be done with the phone in your pocket&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go eyes-free.&lt;/strong&gt; Press &lt;strong&gt;🔊 Listen to Audio Briefing&lt;/strong&gt; and a warm three-sentence script covers the walk and the quests. Lock your phone, pocket it, and go.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is for anyone with a spare hour and a vague sense they should be outside: students between lectures, parents looking for somewhere new on a Sunday, travellers in an unfamiliar city. Because it is built on OpenStreetMap rather than a commercial POI database, it works for any place the community has mapped, not only the cities big apps care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/cz6mx_LrYaw" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The video walks through the full flow: searching a city (Agartala), watching the 5 km Overpass discovery drop pins on the Leaflet + Esri World Topo map, filtering by category, opening a spot to generate a Gemma 2 Touch Grass Field Guide, and ticking off the screen-free quests.&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sidharth-chauhan" rel="noopener noreferrer"&gt;
        sidharth-chauhan
      &lt;/a&gt; / &lt;a href="https://github.com/sidharth-chauhan/adventure.ai" rel="noopener noreferrer"&gt;
        adventure.ai
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌿 adventure.ai&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Find a patch of green nearby, then leave your phone in your pocket.&lt;/strong&gt;&lt;br&gt;
Built for the &lt;strong&gt;Hacktoberfest 2026 Open-Source AI Challenge: Week 1 (Touch Grass)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;adventure.ai&lt;/strong&gt; is a privacy-first, offline-capable local nature scout and micro-adventure generator. Instead of keeping you glued to a screen, it discovers real parks, botanical gardens, viewpoints, and waterside trails within 5 km of your location (or any city worldwide) and uses local open-weight AI (&lt;strong&gt;Google Gemma 2 2B&lt;/strong&gt; via &lt;strong&gt;Ollama&lt;/strong&gt;) to generate a &lt;strong&gt;Screen-Free Field Guide&lt;/strong&gt; with physical outdoor quests and an eyes-free audio briefing.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Key Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📍 Zero-Key Geospatial Discovery:&lt;/strong&gt; Uses browser geolocation (&lt;code&gt;Find Around Me&lt;/code&gt;) or global city geocoding via &lt;strong&gt;OpenStreetMap Nominatim&lt;/strong&gt; + &lt;strong&gt;Overpass API&lt;/strong&gt; to find real nearby parks, gardens, viewpoints, and water trails within a 3–5 km radius—with deterministic offline fallback spots if rate-limited.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🗺️ Interactive Topographic Map:&lt;/strong&gt; Embedded &lt;strong&gt;Leaflet.js&lt;/strong&gt; + &lt;strong&gt;Esri World&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sidharth-chauhan/adventure.ai" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Everything is open source: &lt;a href="https://github.com/sidharth-chauhan/adventure.ai" rel="noopener noreferrer"&gt;github.com/sidharth-chauhan/adventure.ai&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────┐       ┌───────────────────────────────┐
│ frontend/app/(tabs)/index.tsx│       │ backend/src/index.ts          │
│ Expo Router Web (React Native)│◄────►│ Express + TypeScript :5000    │
│ ┌──────────────────────────┐ │ REST  │                               │
│ │ sandboxed Leaflet iframe │ │       │  /api/discover ──► Nominatim  │
│ │ (postMessage bridge)     │ │       │                 └► Overpass   │
│ └──────────────────────────┘ │       │  /api/mission  ──► MongoDB    │
│ localStorage guide cache     │       │                 └► Ollama     │
│ Web Speech API fallback      │       │  /api/tts      ──► ElevenLabs │
└──────────────────────────────┘       └───────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The map is an iframe, on purpose
&lt;/h3&gt;

&lt;p&gt;The UI is React Native Expo Router running on web. Leaflet is a DOM library, so I render it inside an &lt;code&gt;&amp;lt;iframe srcDoc&amp;gt;&lt;/code&gt; with &lt;code&gt;sandbox="allow-scripts"&lt;/code&gt; and talk to it over &lt;code&gt;postMessage&lt;/code&gt;. The page sends &lt;code&gt;{ type: "data", center, spots, selectedId }&lt;/code&gt;. The map answers with &lt;code&gt;{ type: "ready" }&lt;/code&gt; once Leaflet has loaded and &lt;code&gt;{ type: "spot", id }&lt;/code&gt; when a pin is clicked. The parent checks &lt;code&gt;e.source&lt;/code&gt; against the iframe's &lt;code&gt;contentWindow&lt;/code&gt; before trusting any message.&lt;/p&gt;

&lt;p&gt;The result is that changing a filter or selecting a spot redraws the pins without reloading the map. The map also only re-fits its bounds when the set of spots changes, not when you select one, so the view doesn't jump around while you read a guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery: Nominatim, Overpass, and a demo that never dies
&lt;/h3&gt;

&lt;p&gt;A city name goes to &lt;strong&gt;Nominatim&lt;/strong&gt; to get coordinates. Then one &lt;strong&gt;Overpass&lt;/strong&gt; query pulls every &lt;em&gt;named&lt;/em&gt; feature in the radius:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nwr["leisure"~"^(park|garden|nature_reserve)$"]["name"](around:5000,lat,lon);
nwr["tourism"~"^(viewpoint|picnic_site|attraction)$"]["name"](around:5000,lat,lon);
nwr["natural"~"^(water|wood|peak)$"]["name"](around:5000,lat,lon);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results are deduplicated, categorised, distance-sorted with a haversine function, and capped at 40.&lt;/p&gt;

&lt;p&gt;Overpass is a free community service and it sometimes rate-limits or stalls. So if the call times out, fails, or returns fewer than six spots, the backend fills in plausible parks, viewpoints and trails around the coordinates. The generator uses a tiny seeded PRNG (&lt;code&gt;mulberry32&lt;/code&gt;) keyed on the coordinates, so the same place always produces the same fallback spots instead of reshuffling on every refresh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma 2 2B in JSON mode
&lt;/h3&gt;

&lt;p&gt;When you tap a spot, the backend asks a local Ollama instance for the guide:&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;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;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemma2:2b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;// spot, category, city, current month, exact JSON schema&lt;/span&gt;
  &lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;format&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="c1"&gt;// constrain output to valid JSON&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&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;A 2B model is small enough to run on a laptop CPU, but small models drift. Even with &lt;code&gt;format: "json"&lt;/code&gt;, a key can be missing or an array can come back with two items. So every response goes through a normaliser that coerces types and pads arrays to exactly three entries from a hand-written template guide. If Ollama is down entirely, the user gets that template guide, clearly labelled as a starter guide, and it is never cached, so a real AI guide can replace it later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dual offline caching
&lt;/h3&gt;

&lt;p&gt;Guides are cached twice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server side (MongoDB):&lt;/strong&gt; keyed on spot, category, city and rounded coordinates, written with an upsert. If Mongo isn't reachable, the server falls back to an in-memory &lt;code&gt;Map&lt;/code&gt; so nothing breaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client side (&lt;code&gt;localStorage&lt;/code&gt;):&lt;/strong&gt; a guide you've opened once loads instantly and works with no backend at all. This is what the &lt;strong&gt;💾 Offline Cached&lt;/strong&gt; badge on the mission card refers to.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Voice: ElevenLabs first, browser second
&lt;/h3&gt;

&lt;p&gt;The three-sentence &lt;code&gt;voiceScript&lt;/code&gt; goes to &lt;code&gt;/api/tts&lt;/code&gt;. With an &lt;code&gt;ELEVENLABS_API_KEY&lt;/code&gt;, the server calls &lt;code&gt;eleven_multilingual_v2&lt;/code&gt; and returns base64 MP3 that the page plays through &lt;code&gt;Audio&lt;/code&gt;. With no key, or if the call fails, it returns &lt;code&gt;{ fallback: true }&lt;/code&gt; and the page reads the script with the Web Speech API (&lt;code&gt;speechSynthesis&lt;/code&gt;) instead. The briefing always plays; only the voice quality changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running it
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docker compose up -d&lt;/code&gt; starts MongoDB and Ollama and pulls &lt;code&gt;gemma2:2b&lt;/code&gt; into a persistent volume. Then run the Express server and &lt;code&gt;expo start --web&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;I could have built this with a cloud LLM in an afternoon. Here are three reasons it would have been a worse product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Offline resilience.&lt;/strong&gt; The places this app is for, such as forest trails, hill paths and park edges, are exactly where signal gets thin. The guide is generated by Gemma on hardware I control, and once a guide is cached it loads with no network and can be read aloud by the browser's built-in voice. To be precise, discovery and map tiles still need a connection, so the intended pattern is to plan at the trailhead and walk offline. Even so, "the guide still works when the bars drop" is a property a closed API can't give you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Location privacy.&lt;/strong&gt; Where you walk is sensitive data. In this design your coordinates are never sent to an LLM vendor. The prompt that includes them goes to a model running on your own machine. Spatial queries go to OpenStreetMap's open infrastructure, not to a commercial ad-tech stack. The only thing that can leave for a third party is the finished audio script, and only if you opt into ElevenLabs by setting a key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No token meter, no engagement trap.&lt;/strong&gt; Local inference has no per-token cost, so there is no pressure to monetise attention. An app whose job is to get you to leave the screen cannot sit on a business model that rewards screen time. Running open weights, I can set the objective to "get you outside faster" without a cloud bill working against it.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; Gemma 2 2B is the creative engine of the whole product. It is the smallest model that still writes a vivid, structured, location-aware field guide, and it runs locally with &lt;code&gt;format: "json"&lt;/code&gt;. I treat its weaknesses as design constraints: a strict schema, a normaliser that pads and coerces the output, and a labelled template fallback. That is what makes a 2B model reliable enough to build a product on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use of ElevenLabs.&lt;/strong&gt; Voice is the interface, not a bolt-on. The eyes-free briefing is what lets you actually lock the phone and walk. I use &lt;code&gt;eleven_multilingual_v2&lt;/code&gt; for a warm, natural narration of each guide, and the Web Speech API fallback means the feature degrades gracefully instead of failing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use of MongoDB Atlas.&lt;/strong&gt; Atlas holds the shared guide cache. A guide is generated once by Gemma and stored with an upsert keyed on spot and location, so every later request, from any device or backend instance, gets it instantly instead of waiting on a 2B model. The server keeps an in-memory fallback so the demo never depends on one connection.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>book.ai: A spoiler-free, fully local AI reading companion built for a friend</title>
      <dc:creator>Sidharth</dc:creator>
      <pubDate>Sun, 04 Oct 2026 19:34:18 +0000</pubDate>
      <link>https://dev.to/sidharth_28c750a8437aa781/bookai-a-spoiler-free-fully-local-ai-reading-companion-built-for-a-friend-356a</link>
      <guid>https://dev.to/sidharth_28c750a8437aa781/bookai-a-spoiler-free-fully-local-ai-reading-companion-built-for-a-friend-356a</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;book.ai&lt;/strong&gt;, a reading companion that runs entirely on your own computer and never spoils the book.&lt;/p&gt;

&lt;p&gt;It's for a friend of mine who loves getting lost in fantasy and sci-fi like &lt;em&gt;The Hobbit&lt;/em&gt;. Whenever she hit a confusing bit of lore or a character she'd forgotten, searching online or asking a chatbot meant risking a spoiler for a later chapter. On top of that, she didn't love the idea of her reading habits sitting on someone else's servers.&lt;/p&gt;

&lt;p&gt;So book.ai does two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stays inside your chapter.&lt;/strong&gt; You pick where you are in the book, and the AI only discusses what has happened up to that point. Ask about the ending and it politely declines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeps everything local.&lt;/strong&gt; Your questions and reading history never leave your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also has a quiet, paper-toned reading UI, cached book overviews, and optional audio narration for when she'd rather listen than read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/sBKbTY0pKis" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;A 5-minute walkthrough of local inference, chapter-scoped answers, and voice narration.&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sidharth-chauhan" rel="noopener noreferrer"&gt;
        sidharth-chauhan
      &lt;/a&gt; / &lt;a href="https://github.com/sidharth-chauhan/book.ai" rel="noopener noreferrer"&gt;
        book.ai
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A self-hosted AI book companion to explore books and read chapters interactively. Auto-generates chapter breakdowns, author details, and structured content into clickable UI slides. Fully containerized with Docker, featuring React Native Web, Node.js, TypeScript, MongoDB caching, and local Ollama (Gemma) with zero external API keys needed.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/sidharth-chauhan/book.ai/frontend/assets/logo.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsidharth-chauhan%2Fbook.ai%2FHEAD%2Ffrontend%2Fassets%2Flogo.svg" alt="book.ai logo" width="140" height="140"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;book.ai&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Read deeper. Spoil nothing. Share nothing.&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A privacy-first, offline-capable AI reading companion that runs on your machine, not in someone else's cloud.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/sidharth-chauhan/book.ai/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9218332452902d9e542a100d0af126fd3174a116456614d2cf093546a13783db/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e7376673f7374796c653d666f722d7468652d6261646765" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sidharth-chauhan/book.ai/CONTRIBUTING.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/875fdcafb33a30d3badb178f9a5e7177dd3ebab8dbedeaa97028e748172e7375/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f7374796c653d666f722d7468652d6261646765" alt="PRs Welcome"&gt;&lt;/a&gt;
&lt;a href="https://hacktoberfest.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/63315c9b498e4fa6d3c509d7de28dc231019e540b6263c56e2b11ea9431559fd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362d626c756576696f6c65742e7376673f7374796c653d666f722d7468652d6261646765" alt="Hacktoberfest 2026"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/02b0496725dd0faada59a30761e60e4bc2401c2e9053067a88599bdb43da7efe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163745f4e61746976652d4578706f5f5765622d3631444146423f6c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b"&gt;&lt;img src="https://camo.githubusercontent.com/02b0496725dd0faada59a30761e60e4bc2401c2e9053067a88599bdb43da7efe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163745f4e61746976652d4578706f5f5765622d3631444146423f6c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b" alt="React Native"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/263ac0f4c45dc084ff7cbfbeb3986dd8c9acba41a993e06f1a6ea6495030669f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652e6a732d457870726573732d3333393933333f6c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/263ac0f4c45dc084ff7cbfbeb3986dd8c9acba41a993e06f1a6ea6495030669f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652e6a732d457870726573732d3333393933333f6c6f676f3d6e6f64652e6a73266c6f676f436f6c6f723d7768697465" alt="Node.js"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/2c6ae5406823e79ee3a6ec1835c371b139f19c65633756bbf5426d82ac9a2ea9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f6e676f44422d4c6f63616c2d3437413234383f6c6f676f3d6d6f6e676f6462266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/2c6ae5406823e79ee3a6ec1835c371b139f19c65633756bbf5426d82ac9a2ea9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f6e676f44422d4c6f63616c2d3437413234383f6c6f676f3d6d6f6e676f6462266c6f676f436f6c6f723d7768697465" alt="MongoDB"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/893bd2850ec5d0c47846d139083c5ebc6520a4b326380c22ef11d7c870bff873/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f6c6c616d612d47656d6d615f325f32422d3030303030303f6c6f676f3d6f6c6c616d61266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/893bd2850ec5d0c47846d139083c5ebc6520a4b326380c22ef11d7c870bff873/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f6c6c616d612d47656d6d615f325f32422d3030303030303f6c6f676f3d6f6c6c616d61266c6f676f436f6c6f723d7768697465" alt="Ollama"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/22be7b8b4dcd8179af2651a234ef7bcbcded006f266309236d938c6789dd0cec/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446f636b65722d52656164792d3234393645443f6c6f676f3d646f636b6572266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/22be7b8b4dcd8179af2651a234ef7bcbcded006f266309236d938c6789dd0cec/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446f636b65722d52656164792d3234393645443f6c6f676f3d646f636b6572266c6f676f436f6c6f723d7768697465" alt="Docker"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;a href="https://youtu.be/sBKbTY0pKis" rel="nofollow noopener noreferrer"&gt;
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsidharth-chauhan%2Fbook.ai%2FHEAD%2Ffrontend%2Fassets%2Fdemo-thumbnail.png" alt="Watch the book.ai demo walkthrough on YouTube" width="240"&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;a href="https://youtu.be/sBKbTY0pKis" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;▶ Watch the 5-min demo walkthrough&lt;/b&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;💌 Why book.ai Exists&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I just want to ask a question about the chapter I'm on, without the app telling me how the book ends."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Built for a friend who loves reading, &lt;code&gt;book.ai&lt;/code&gt; solves three problems with general-purpose chatbots:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Privacy:&lt;/strong&gt; your questions reveal what you think and feel. They stay on your machine.&lt;/li&gt;
&lt;li&gt;🙈 &lt;strong&gt;Spoilers:&lt;/strong&gt; ask about chapter three and get chapter three, not the ending.&lt;/li&gt;
&lt;li&gt;📴 &lt;strong&gt;Access:&lt;/strong&gt; no subscription, and no connection required.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Key Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;Local-first AI:&lt;/strong&gt; Google's &lt;code&gt;gemma2:2b&lt;/code&gt; runs through &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; on your hardware.&lt;/li&gt;
&lt;li&gt;📖 &lt;strong&gt;Book exploration:&lt;/strong&gt; enter a title for the author, summary, and chapter breakdown.&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Spoiler-free Read Mode:&lt;/strong&gt; chat about a chapter; the AI discusses only what happened up to it.&lt;/li&gt;
&lt;li&gt;🎧 &lt;strong&gt;Audio&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sidharth-chauhan/book.ai" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The repo has everything: the React Native web frontend, the Express backend, and a &lt;code&gt;docker-compose.yml&lt;/code&gt; that starts the database and model server in one command.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Google's open-weight &lt;strong&gt;Gemma 2 (2B)&lt;/strong&gt;, served locally through &lt;strong&gt;Ollama&lt;/strong&gt; in a Docker container. It's small enough to give usable answers on an ordinary laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Node.js and Express. It builds the prompts, enforces the chapter boundary in the instructions sent to the model, and talks to Ollama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; A local &lt;strong&gt;MongoDB&lt;/strong&gt; container caches book overviews so repeat visits load instantly. Docker volumes (&lt;code&gt;mongo_data&lt;/code&gt; and &lt;code&gt;ollama_data&lt;/code&gt;) keep the cache and model weights across restarts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; &lt;strong&gt;React Native with Expo Web&lt;/strong&gt;, styled to feel like a page rather than a dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio:&lt;/strong&gt; Optional narration through the &lt;strong&gt;ElevenLabs&lt;/strong&gt; API. This is the one feature that needs internet, since the text of a single answer is sent to be converted to speech. Skip it and the app works fully offline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;A closed API would have broken the main promise of this project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; What someone asks about a book says a lot about them. With open weights, that data never has to leave their laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No meter running.&lt;/strong&gt; Because the model runs locally, my friend can ask as many questions as she wants without paying per token or subscribing to anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works offline.&lt;/strong&gt; She reads on trains and flights, and a local model keeps working when the connection doesn't.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Gemma Challenge:&lt;/strong&gt; Gemma 2 running locally is the core of the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs:&lt;/strong&gt; Powers the optional voice narration.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
