<?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: Arjan kc</title>
    <description>The latest articles on DEV Community by Arjan kc (@arjankc).</description>
    <link>https://dev.to/arjankc</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%2F502163%2F30e50c82-5a9b-440a-b2f1-0aa880a05b25.jpeg</url>
      <title>DEV Community: Arjan kc</title>
      <link>https://dev.to/arjankc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arjankc"/>
    <language>en</language>
    <item>
      <title>QuestSloth: Local Gemma Turns Lecture Notes Into a Dungeon Quiz</title>
      <dc:creator>Arjan kc</dc:creator>
      <pubDate>Sun, 25 Oct 2026 07:15:58 +0000</pubDate>
      <link>https://dev.to/arjankc/questsloth-local-gemma-turns-lecture-notes-into-a-dungeon-quiz-166g</link>
      <guid>https://dev.to/arjankc/questsloth-local-gemma-turns-lecture-notes-into-a-dungeon-quiz-166g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;QuestSloth&lt;/strong&gt; automates a chore teachers dread — turning dry syllabus notes into quizzes — and makes studying feel like a tiny dungeon crawl.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Teacher Forge&lt;/strong&gt; — paste lecture notes. Open-weight &lt;strong&gt;Gemma 2 2B&lt;/strong&gt; runs locally in the browser via &lt;a href="https://webllm.mlc.ai/" rel="noopener noreferrer"&gt;WebLLM&lt;/a&gt; and emits a strict &lt;code&gt;quest.json&lt;/code&gt; (quest title, boss name, five MCQs, answers, explanations).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Student Dungeon&lt;/strong&gt; — play that pack with &lt;strong&gt;no AI inference&lt;/strong&gt;: HP bars, combos, difficulty modes, consumable powers, achievements, procedural SFX + battle music. Correct answers hurt the boss; misses hurt you and show the explanation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Slow and steady / International Sloth Day: the teacher stops inventing five MCQs by hand; students get a boss fight instead of a worksheet. Notes never leave the device.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://arjankc.github.io/QuestSloth/" rel="noopener noreferrer"&gt;https://arjankc.github.io/QuestSloth/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Forge&lt;/strong&gt; needs WebGPU (recent Chrome/Edge). First Gemma download is ~1.5GB for the f16 build (or ~2.5GB if your GPU lacks &lt;code&gt;shader-f16&lt;/code&gt; and Forge falls back to q4f32) and caches in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dungeon&lt;/strong&gt; works without loading any model — try &lt;strong&gt;Play sample quest&lt;/strong&gt; immediately. Unmute the header speaker for lobby pad / battle BGM / SFX.&lt;/li&gt;
&lt;li&gt;Forge &lt;strong&gt;Play in Dungeon&lt;/strong&gt; hands the pack over via &lt;code&gt;sessionStorage&lt;/code&gt; (plus a short local quest stash).&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/arjankc/QuestSloth" rel="noopener noreferrer"&gt;https://github.com/arjankc/QuestSloth&lt;/a&gt;&lt;/p&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/arjankc" rel="noopener noreferrer"&gt;
        arjankc
      &lt;/a&gt; / &lt;a href="https://github.com/arjankc/QuestSloth" rel="noopener noreferrer"&gt;
        QuestSloth
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Browser-local Gemma turns lecture notes into dungeon quizzes (Hacktoberfest 2026 Week 3)
    &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;QuestSloth&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Turn lecture notes into a dungeon-crawler quiz — entirely in the browser.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Built for &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge: Week 3 — Slow and Steady&lt;/a&gt;. Teachers paste notes; local &lt;strong&gt;Gemma 2 2B&lt;/strong&gt; (via &lt;a href="https://webllm.mlc.ai/" rel="nofollow noopener noreferrer"&gt;WebLLM&lt;/a&gt;) forges a &lt;code&gt;quest.json&lt;/code&gt;. Students fight the boss by answering — no inference on the play path.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why open weights?&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Notes never leave the device (Forge runs on-device WebGPU).&lt;/li&gt;
&lt;li&gt;No OpenAI/Claude bill for every quiz.&lt;/li&gt;
&lt;li&gt;Students only need the JSON file — the dreaded “write five MCQs by hand” chore becomes a paste → download.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Vite + React + TypeScript + Tailwind CSS&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@mlc-ai/web-llm&lt;/code&gt; · prefers &lt;code&gt;gemma-2-2b-it-q4f16_1-MLC-1k&lt;/code&gt; (~1.5GB); auto-falls back to &lt;code&gt;gemma-2-2b-it-q4f32_1-MLC&lt;/code&gt; (~2.5GB) when WebGPU &lt;code&gt;shader-f16&lt;/code&gt; is missing&lt;/li&gt;
&lt;li&gt;Static host: GitHub Pages (&lt;code&gt;base: '/QuestSloth/'&lt;/code&gt;, HashRouter)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Modes&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;AI?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Teacher Forge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#/forge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes — loads Gemma, emits strict quest JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Student Dungeon&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#/dungeon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No — upload JSON, forged handoff, sample, or&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/arjankc/QuestSloth" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Worth a look:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/lib/webllm.ts&lt;/code&gt; — Gemma load + f16 feature probe + q4f32 fallback + low-temperature JSON generation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/lib/questSchema.ts&lt;/code&gt; — Zod validation + JSON Schema for constrained decoding&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/lib/difficulty.ts&lt;/code&gt; / &lt;code&gt;src/lib/powers.ts&lt;/code&gt; / &lt;code&gt;src/lib/progress.ts&lt;/code&gt; — Easy/Normal/Hard, Hint/Shield/Focus, XP + achievements&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/lib/audio.ts&lt;/code&gt; — procedural Web Audio (no sound files)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/pages/Forge.tsx&lt;/code&gt; / &lt;code&gt;src/pages/Dungeon.tsx&lt;/code&gt; — the two halves of the product&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Constraints drove the stack: &lt;strong&gt;~30GB free disk&lt;/strong&gt;, &lt;strong&gt;4GB VRAM&lt;/strong&gt;, no Python/Ollama/Docker. Everything is a static SPA on GitHub Pages.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
  notes[LectureNotes] --&amp;gt; forge[TeacherForge]
  forge --&amp;gt; webllm[WebLLM]
  webllm --&amp;gt; gemma[Gemma2_2B]
  gemma --&amp;gt; pack[quest.json]
  pack --&amp;gt; dungeon[StudentDungeon]
  dungeon --&amp;gt; fight[BossFight]&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vite + React + Tailwind&lt;/strong&gt; for routing and game state (&lt;code&gt;HashRouter&lt;/code&gt;, &lt;code&gt;base: '/QuestSloth/'&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@mlc-ai/web-llm&lt;/code&gt;&lt;/strong&gt; prefers &lt;code&gt;gemma-2-2b-it-q4f16_1-MLC-1k&lt;/code&gt; (~1583MB VRAM). On GPUs that don't advertise WebGPU &lt;code&gt;shader-f16&lt;/code&gt;, Forge probes &lt;code&gt;adapter.features&lt;/code&gt; and loads &lt;code&gt;gemma-2-2b-it-q4f32_1-MLC&lt;/code&gt; instead (~2.5GB) — same Gemma 2 2B IT weights, no Canary flags required. If the probe misses, a create failure matching &lt;code&gt;shader-f16&lt;/code&gt; triggers one automatic retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict JSON:&lt;/strong&gt; &lt;code&gt;temperature: 0.15&lt;/code&gt;, WebLLM &lt;code&gt;response_format: { type: "json_object", schema }&lt;/code&gt;, then Zod parse + one repair retry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code-split Forge&lt;/strong&gt; so the Dungeon route never pulls WebLLM (phone-friendly play)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game loop:&lt;/strong&gt; difficulty tables, one-power loadout (Shield/Focus unlock at level 2), combos, level combat bonuses, achievements, CSS battle FX, lobby pad + battle BGM that speeds up on enrage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small models love to ignore free-form prompts. Constrained decoding plus a validator kept the dungeon from crashing on bad packs — the same lesson browser-Gemma builders keep rediscovering (&lt;a href="https://dev.to/faris0520/touch-soil-an-offline-garden-planner-with-gemma-running-in-your-browser-41pe"&gt;Touch Soil&lt;/a&gt; is a good peer example of schema-shaped WebLLM output).&lt;/p&gt;

&lt;p&gt;The f16 fallback was a live-demo fix: WebLLM's f16-1k build hard-requires &lt;code&gt;shader-f16&lt;/code&gt;, and shipping only that ID meant some Chrome/Edge users (especially integrated GPUs) got a Canary flag error instead of a quiz. Probe + q4f32 keeps Best Use of Gemma reachable on more hardware — the same pattern in-browser LLM posts keep hitting (&lt;a href="https://dev.to/mattbusel/run-an-llm-in-the-browser-webgpu-did-63-tokenss-wasm-did-16-24ob"&gt;WebGPU present ≠ WebGPU usable&lt;/a&gt;; &lt;a href="https://dev.to/kingcavan1988/what-breaks-when-you-ship-21-ai-tools-that-never-touch-a-server-3go4"&gt;ship a quantization per backend&lt;/a&gt;).&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Classroom notes stay on the laptop.&lt;/strong&gt; Forge never posts syllabus text to a paid API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero inference bill&lt;/strong&gt; after the one-time model cache — important if you forge quizzes every week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Students only need the JSON file.&lt;/strong&gt; Schools with locked-down or low-end devices can still play the dungeon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable brain.&lt;/strong&gt; The model id is one string in &lt;code&gt;webllm.ts&lt;/code&gt;; any WebLLM Gemma (or other open weight) can replace it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lazy payoff:&lt;/strong&gt; paste notes → download (or hand off) quest → share with the class. The chore of inventing five decent MCQs disappears.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Teacher Forge runs open-weight Gemma 2 2B in-browser via WebLLM to generate every quest pack.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>gemma</category>
      <category>webllm</category>
    </item>
    <item>
      <title>Local Listing Nepal: Bilingual Google/Facebook listing packs with Gemma in the browser</title>
      <dc:creator>Arjan kc</dc:creator>
      <pubDate>Sat, 17 Oct 2026 16:12:21 +0000</pubDate>
      <link>https://dev.to/arjankc/local-listing-nepal-bilingual-googlefacebook-listing-packs-with-gemma-in-the-browser-84h</link>
      <guid>https://dev.to/arjankc/local-listing-nepal-bilingual-googlefacebook-listing-packs-with-gemma-in-the-browser-84h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Local Listing Nepal&lt;/strong&gt; turns a short Nepal small-business brief into a ready-to-paste listing pack for the places local shops actually need to show up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Business short + full descriptions&lt;/li&gt;
&lt;li&gt;Suggested categories and services&lt;/li&gt;
&lt;li&gt;Facebook About / Intro&lt;/li&gt;
&lt;li&gt;3–5 low-hype Facebook starter captions&lt;/li&gt;
&lt;li&gt;Hamrobazar / marketplace title + description when it fits&lt;/li&gt;
&lt;li&gt;Nepali (Devanagari) short + full descriptions&lt;/li&gt;
&lt;li&gt;Honest local search phrases&lt;/li&gt;
&lt;li&gt;Assumptions / questions instead of invented “facts”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who would pay:&lt;/strong&gt; shop owners, cafes, clinics, tutors, and service businesses in Nepal who currently pay an agency or freelancer for listing rewrites; freelancers who want a productized micro-service; agencies that need a faster first draft before human polish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; a lot of Nepal SMBs have weak or empty Google Business and Facebook listings — missing categories, generic English-only copy, no Nepali text, weak local keywords, no clear call-to-action, inconsistent name/address/phone. A full marketing retainer is expensive when they only need a strong listing pack.&lt;/p&gt;

&lt;p&gt;I run client work through &lt;a href="https://gurkhatech.com" rel="noopener noreferrer"&gt;Gurkha Technology&lt;/a&gt; in Kathmandu and teach business/IT subjects. This is the reusable draft tool I wanted for that work: something I can operate from Nepal without depending on a paid API card for every generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works for the user:&lt;/strong&gt; fill in business name, category, location, phone, services, optional differentiators, and language mix (English / Nepali / bilingual). Generate. Copy any section, copy all Markdown, or download a &lt;code&gt;.md&lt;/code&gt; file. The UI states clearly that briefs are processed locally in the browser — nothing goes to a paid API by default.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live demo (GitHub Pages):&lt;/strong&gt; &lt;a href="https://arjankc.github.io/local-listing-nepal/" rel="noopener noreferrer"&gt;https://arjankc.github.io/local-listing-nepal/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use a recent &lt;strong&gt;Chrome&lt;/strong&gt; or &lt;strong&gt;Edge&lt;/strong&gt; on desktop (WebGPU required). The first generate downloads ~1–1.5 GB of open model weights into the browser cache; after that it can work offline.&lt;/p&gt;

&lt;p&gt;Try a brief like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business: Lakuri Hills Cafe
&lt;/li&gt;
&lt;li&gt;Category: cafe
&lt;/li&gt;
&lt;li&gt;Location: Lakuri Phedi, Lalitpur
&lt;/li&gt;
&lt;li&gt;Phone: your real number
&lt;/li&gt;
&lt;li&gt;Services: filter coffee, brunch, hiking snacks, outdoor seating
&lt;/li&gt;
&lt;li&gt;Language mix: bilingual
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Watch the pack stream in under the fixed section headings, then copy what you need into Google Business or Facebook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/arjankc/local-listing-nepal" rel="noopener noreferrer"&gt;https://github.com/arjankc/local-listing-nepal&lt;/a&gt;&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/arjankc" rel="noopener noreferrer"&gt;
        arjankc
      &lt;/a&gt; / &lt;a href="https://github.com/arjankc/local-listing-nepal" rel="noopener noreferrer"&gt;
        local-listing-nepal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Nepal SMB listing packs (Google/Facebook/marketplace) with Gemma in the browser via WebLLM
    &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;Local Listing Nepal&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Turn a Nepal small-business brief into ready-to-paste &lt;strong&gt;Google Business Profile&lt;/strong&gt;, &lt;strong&gt;Facebook Page&lt;/strong&gt;, and &lt;strong&gt;Hamrobazar / marketplace&lt;/strong&gt; listing copy in &lt;strong&gt;English and Nepali&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Open-weight &lt;strong&gt;Gemma&lt;/strong&gt; runs in your browser via &lt;a href="https://github.com/mlc-ai/web-llm" rel="noopener noreferrer"&gt;WebLLM&lt;/a&gt; + WebGPU. No backend. No paid API by default.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://arjankc.github.io/local-listing-nepal/" rel="nofollow noopener noreferrer"&gt;https://arjankc.github.io/local-listing-nepal/&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Who would pay&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Shop owners, cafes, clinics, tutors, and service businesses in Nepal who currently pay for listing rewrites&lt;/li&gt;
&lt;li&gt;Freelancers who productize listing packs for clients&lt;/li&gt;
&lt;li&gt;Agencies that want a faster first draft before human polish&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Simple business brief form (name, category, location, phone, services, optional extras, language mix)&lt;/li&gt;
&lt;li&gt;Structured listing pack with stable Markdown headings&lt;/li&gt;
&lt;li&gt;Copy per section (&lt;code&gt;navigator.clipboard.writeText&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Copy-all Markdown + download &lt;code&gt;.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Privacy note: briefs stay on-device; model loads into browser cache&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Recent &lt;strong&gt;Chrome&lt;/strong&gt; or &lt;strong&gt;Edge&lt;/strong&gt; on desktop with &lt;strong&gt;WebGPU&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;First generate downloads ~1–1.5 GB model weights into browser cache&lt;/li&gt;
&lt;li&gt;Modest integrated GPUs work; pick…&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/arjankc/local-listing-nepal" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Stack in short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vite + React + TypeScript + Tailwind (static SPA, no backend)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mlc-ai/web-llm" rel="noopener noreferrer"&gt;&lt;code&gt;@mlc-ai/web-llm&lt;/code&gt;&lt;/a&gt; for in-browser inference&lt;/li&gt;
&lt;li&gt;Default open model: &lt;strong&gt;Gemma 2 2B&lt;/strong&gt; (Qwen 2.5 1.5B and Llama 3.2 1B as lighter fallbacks)&lt;/li&gt;
&lt;li&gt;Temperature &lt;strong&gt;0.15&lt;/strong&gt; and a fixed Markdown heading schema so each section gets its own Copy button&lt;/li&gt;
&lt;li&gt;MIT license&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The WebLLM load/progress pattern (quantization probe, Gemma user-turn prompting) was proven earlier on a &lt;em&gt;different&lt;/em&gt; product, &lt;a href="https://github.com/arjankc/Localized-String-Assistant" rel="noopener noreferrer"&gt;Nepali String Localizer&lt;/a&gt;. This is a new repo and a new job: SMB listing packs, not UI string localization.&lt;/p&gt;

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

&lt;p&gt;Open-source AI is not a badge on the landing page — it &lt;em&gt;is&lt;/em&gt; the product. Without an open-weight model running locally, there is no listing pack.&lt;/p&gt;

&lt;p&gt;I built this on modest hardware (aging integrated graphics). That constraint shaped every choice: smallest viable Gemma in the WebLLM catalog by default, clear download progress, streaming output, and a lightweight UI so the tab does not fall over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In-browser inference with WebLLM + WebGPU.&lt;/strong&gt; On first generate, the app loads Gemma 2 2B into the tab. It checks whether the GPU supports 16-bit float shaders and picks &lt;code&gt;q4f16_1&lt;/code&gt; or &lt;code&gt;q4f32_1&lt;/code&gt;. There is no server of mine in the loop: GitHub Pages serves the static app; the visitor’s machine does the inference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One strict prompt, one fixed output schema.&lt;/strong&gt; The model is instructed to act as a Nepal SMB listing copywriter: never invent amenities, prices, awards, or hours; preserve name/address/phone and brand spelling exactly; use &lt;code&gt;[Ask the business]&lt;/code&gt; for gaps; avoid marketing fluff; write natural written Nepali for business listings, not awkward literal translation. Output must use stable &lt;code&gt;##&lt;/code&gt; headings so the UI can parse sections for per-section clipboard copy (&lt;code&gt;navigator.clipboard.writeText&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma as the core model.&lt;/strong&gt; Nepali + English listing copy is the hard part on a 2B-class model. Gemma 2 2B was the best of the small WebLLM options I could ship for Devanagari and bilingual packs. Gemma’s chat template has no system role, so the instructions travel in the user message — same practical detail as my earlier browser tool, applied here to a different prompt and product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I deliberately did not build:&lt;/strong&gt; auth, CRM, billing, auto-posting to Google/Facebook APIs, image generation, ads builders, or competitor scraping. The MVP is a listing pack writer someone would actually pay a freelancer for — not an unfinished platform.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
  brief["Business brief"] --&amp;gt; prompt["Listing prompt"]
  prompt --&amp;gt; webllm["WebLLM"]
  webllm --&amp;gt; gemma["Gemma 2 2B"]
  gemma --&amp;gt; pack["Markdown pack"]
  pack --&amp;gt; export["Copy / export"]&lt;/code&gt;&lt;/pre&gt;



</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Nepali String Localizer, context-aware UI translation for my fellow volunteer translators</title>
      <dc:creator>Arjan kc</dc:creator>
      <pubDate>Mon, 05 Oct 2026 03:19:05 +0000</pubDate>
      <link>https://dev.to/arjankc/nepali-string-localizer-context-aware-ui-translation-for-my-fellow-volunteer-translators-125f</link>
      <guid>https://dev.to/arjankc/nepali-string-localizer-context-aware-ui-translation-for-my-fellow-volunteer-translators-125f</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;&lt;strong&gt;Nepali String Localizer&lt;/strong&gt; translates isolated English UI strings into Nepali, using context about where the string appears. It runs in a browser tab on an ordinary laptop, with no install and no API key.&lt;/p&gt;

&lt;p&gt;I volunteer as a translator with &lt;strong&gt;Translators without Borders&lt;/strong&gt;, and I built this for the people I volunteer alongside: Nepali translators who give their time to humanitarian and open-source projects. Their "friend" here is the whole community. I'm sure there are volunteers who can use this tomorrow, starting with me.&lt;/p&gt;

&lt;p&gt;A lot of the software humanitarian teams rely on is open source. KoboToolbox, the data-collection platform that NGOs and field teams use for surveys and crisis response, is one example. Getting its interface into Nepali means someone, usually a volunteer, translating it string by string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; on localization platforms, a translator sees strings one at a time with almost no context. Take &lt;code&gt;Deploy&lt;/code&gt;. Is it a button, a status message, or a heading in the docs? Each one needs different Nepali. A technical word like "Server" or "Submit" also raises a question: should it be translated, transliterated into Devanagari, or left in English? Volunteers make that call hundreds of times per project, usually alone and in their spare time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; paste the string, add a line of context (for example &lt;em&gt;"Primary call-to-action button on the server settings page"&lt;/em&gt;), and get three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Formal&lt;/strong&gt;: standard written Nepali, for docs and strict UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colloquial&lt;/strong&gt;: natural, conversational Nepali, for friendly everyday app text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transliterated/Hybrid&lt;/strong&gt;: technical terms kept in English, written in Devanagari (सबमिट, सर्भर) or left in Latin script when translating them would lose the meaning.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The prompt tells the model to leave placeholders like &lt;code&gt;{name}&lt;/code&gt;, &lt;code&gt;%s&lt;/code&gt; and HTML tags untouched, so a translation doesn't break the app it goes into.&lt;/p&gt;

&lt;p&gt;It doesn't replace the translator. It gives them three starting points to pick from or edit, so they spend their time on judgment instead of a blank text box.&lt;/p&gt;

&lt;p&gt;My next step is sharing the link with other Nepali volunteers and collecting their feedback on which of the three styles they actually pick.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Try it in your browser:&lt;/strong&gt; &lt;a href="https://arjankc.github.io/Localized-String-Assistant/" rel="noopener noreferrer"&gt;https://arjankc.github.io/Localized-String-Assistant/&lt;/a&gt; (no install and no API key). The first translation downloads a ~1.5 GB open model into your browser cache.&lt;/p&gt;

&lt;p&gt;To try it, type a string like &lt;code&gt;Deploy Form&lt;/code&gt;, add context like &lt;em&gt;"Primary call-to-action button on the form builder page that publishes a survey"&lt;/em&gt;, and click &lt;strong&gt;Translate to Nepali&lt;/strong&gt;. A progress bar shows the model download, then the three options stream in. Once the model is cached, you can turn off Wi-Fi and keep translating.&lt;/p&gt;

&lt;p&gt;Prefer a desktop app? The same repo includes a Streamlit version that runs Gemma 3 4B locally through Ollama (setup steps in the README).&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/arjankc" rel="noopener noreferrer"&gt;
        arjankc
      &lt;/a&gt; / &lt;a href="https://github.com/arjankc/Localized-String-Assistant" rel="noopener noreferrer"&gt;
        Localized-String-Assistant
      &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;Nepali String Localizer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Context-aware English-to-Nepali UI string translation for open-source localization projects like KoboToolbox.&lt;/p&gt;
&lt;p&gt;Paste an isolated UI string (for example &lt;code&gt;Deploy Form&lt;/code&gt;), describe where it appears, and get three Nepali options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Formal&lt;/strong&gt;: standard written Nepali, for documentation or strict UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colloquial&lt;/strong&gt;: natural, conversational Nepali, for friendly everyday app text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transliterated/Hybrid&lt;/strong&gt;: technical terms kept in English, written in Devanagari (सबमिट, सर्भर) or left in Latin script when translating them would lose the meaning.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Placeholders such as &lt;code&gt;{name}&lt;/code&gt;, &lt;code&gt;%s&lt;/code&gt;, &lt;code&gt;%(count)d&lt;/code&gt; and HTML tags are preserved as-is.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why it exists&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Volunteer translators on platforms like Transifex or Weblate see strings one at a time, with little or no context. "Deploy" on a button, "Deploy" in a status message, and "Deploy" in docs often need different Nepali wording. This tool gives a translator three context-aware candidates to pick from or edit, so they spend their time reviewing…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/arjankc/Localized-String-Assistant" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;There are two front ends that share one prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docs/index.html&lt;/code&gt;: a single static page that runs the model in the browser (WebLLM + WebGPU).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app.py&lt;/code&gt;: a ~140-line Streamlit app that talks to a local Ollama server or Groq.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I built this on a 2018 laptop: an i5-8265U with 16 GB of RAM, integrated Intel UHD 620 graphics and no dedicated GPU. That constraint shaped everything. Volunteers don't usually have workstation GPUs, so if it runs on this machine, it should run on theirs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In-browser inference:&lt;/strong&gt; &lt;a href="https://github.com/mlc-ai/web-llm" rel="noopener noreferrer"&gt;WebLLM&lt;/a&gt; compiles open-weight models to WebGPU, so &lt;strong&gt;Gemma 2 2B&lt;/strong&gt; runs inside a browser tab on integrated graphics. The page checks whether the GPU supports 16-bit float shaders and picks the matching build. Qwen 2.5 1.5B and Llama 3.2 1B are there as lighter options. There's no backend at all: GitHub Pages serves one HTML file, and the model is cached in the browser after the first load.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local inference with Ollama:&lt;/strong&gt; for translators who prefer a desktop setup, the Streamlit app runs &lt;strong&gt;Gemma 3 4B&lt;/strong&gt; on the CPU through &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;. Ollama exposes an OpenAI-compatible endpoint, so the standard &lt;code&gt;openai&lt;/code&gt; Python client talks to it, or to &lt;strong&gt;Llama 3.3 70B&lt;/strong&gt; on Groq when more quality is needed. Switching between them only changes the &lt;code&gt;base_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choosing small models for Nepali:&lt;/strong&gt; this was the interesting part. Nepali is a lower-resource language, and many small models were trained mostly on English and a handful of major languages. I leaned on the Gemma family. Gemma 3 was trained on 140+ languages, which makes it the Ollama default, and Gemma 2 2B is the default in the browser. The lighter 1B options are there for very weak machines, with the tradeoff stated in the UI. Because nothing is hardcoded to one model, swapping in a better small multilingual model is a one-line change as WebLLM's catalog grows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompting:&lt;/strong&gt; one prompt does the heavy lifting. It makes the model act as an English-to-Nepali software localization expert, keep placeholders like &lt;code&gt;{name}&lt;/code&gt; and &lt;code&gt;%s&lt;/code&gt; intact, stay short enough for UI text, and return exactly three options in a fixed Markdown template. A low temperature (0.3) keeps the output consistent from string to string. Gemma's chat format has no system role, so the browser version sends the instructions in the user turn.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    user[Translator] --&amp;gt; web["Browser page: WebLLM + WebGPU"]
    user --&amp;gt; st[Streamlit app]
    web --&amp;gt; gemma2["Gemma 2 2B in the browser tab"]
    st --&amp;gt;|offline| ollama["Ollama: Gemma 3 4B on CPU"]
    st --&amp;gt;|online| groq["Groq: Llama 3.3 70B"]
    gemma2 --&amp;gt; out[Formal / Colloquial / Hybrid]
    ollama --&amp;gt; out
    groq --&amp;gt; out&lt;/code&gt;&lt;/pre&gt;



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

&lt;p&gt;&lt;strong&gt;It runs on an old laptop, in a browser tab, with no internet.&lt;/strong&gt; Volunteer translation happens on personal laptops, not fast office machines. Because the weights are open, a 2B model can be compiled to WebGPU and shipped as a static web page. After the first load, a volunteer can keep translating wherever connectivity is patchy or gone. A closed API simply stops working there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero setup for volunteers.&lt;/strong&gt; Nobody needs Python, Ollama or an API key. I can share one link in a volunteer group and anyone with a recent Chrome or Edge can use it. A closed model can't be shipped like that; it can only be rented through someone's server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; This is volunteer work. Nobody should have to put a credit card on file for a per-token API to translate humanitarian software for free. There's no server to pay for either: GitHub Pages hosts the page, and the visitor's own GPU does the inference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unreleased strings stay on the translator's machine.&lt;/strong&gt; Strings from unreleased features and internal admin screens never leave the device in the browser and Ollama versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We can swap models, and eventually fine-tune.&lt;/strong&gt; Nepali is a lower-resource language, and different open models handle Devanagari very differently. Because the app only depends on an OpenAI-compatible endpoint, switching from Gemma to Llama to Qwen is a config change, not a rewrite. The next step is fine-tuning a small open model on the existing, human-reviewed Nepali translations from KoboToolbox's own translation files, so it learns the project's established terms. That is only possible because the weights are open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open tools for open tools.&lt;/strong&gt; Humanitarian software like KoboToolbox is open source, and many of the people translating it are volunteers. It felt right that the tool helping them is open too. Volunteers working in other languages (Maithili, Newari, Tamang, or any language Translators without Borders supports) can fork it, change the prompt, and point it at whichever open model handles their language best.&lt;/p&gt;

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