<?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: Gustavo Sanchez</title>
    <description>The latest articles on DEV Community by Gustavo Sanchez (@gusanchedev).</description>
    <link>https://dev.to/gusanchedev</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%2F456876%2F6594bc8e-8c8e-4d3e-89a2-fd4c89704994.jpg</url>
      <title>DEV Community: Gustavo Sanchez</title>
      <link>https://dev.to/gusanchedev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gusanchedev"/>
    <language>en</language>
    <item>
      <title>EnglishChunks.guru — speak real English, one chunk a day, scored by open-source AI</title>
      <dc:creator>Gustavo Sanchez</dc:creator>
      <pubDate>Sun, 18 Oct 2026 19:18:10 +0000</pubDate>
      <link>https://dev.to/gusanchedev/englishchunksguru-speak-real-english-one-chunk-a-day-scored-by-open-source-ai-5f93</link>
      <guid>https://dev.to/gusanchedev/englishchunksguru-speak-real-english-one-chunk-a-day-scored-by-open-source-ai-5f93</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;&lt;a href="https://englishchunks.guru" rel="noopener noreferrer"&gt;EnglishChunks.guru&lt;/a&gt;&lt;/strong&gt; is a 12-minute daily speaking coach for English learners.&lt;/p&gt;

&lt;p&gt;Many learners &lt;em&gt;know&lt;/em&gt; the words but freeze when they have to speak. Native speakers don't build sentences word by word — they use &lt;strong&gt;chunks&lt;/strong&gt; like &lt;em&gt;“make a decision”&lt;/em&gt; or &lt;em&gt;“that makes sense”&lt;/em&gt;. So every day the app gives you &lt;strong&gt;one chunk at your level (A1–C2)&lt;/strong&gt; and walks you through it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Learn&lt;/strong&gt; — hear it and see three real examples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speak (twice)&lt;/strong&gt; — record yourself, get a 0–100 score and a tip on the exact sounds to fix&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write&lt;/strong&gt; — use it in three sentences of your own; they come back polished&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read aloud&lt;/strong&gt; — say your sentences and get today's score&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Who would pay:&lt;/strong&gt; adults who need English for work — interviews, meetings, moving abroad. Plans are $7–$11/month (1–5 practices a day). It's free while I test it.&lt;/p&gt;

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

&lt;p&gt;👉 &lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://englishchunks.guru" rel="noopener noreferrer"&gt;https://englishchunks.guru&lt;/a&gt; (sign up with Google or email)&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/FNLvIlkco74" width="710" height="399"&gt;
  &lt;/iframe&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/gusanchefullstack" rel="noopener noreferrer"&gt;
        gusanchefullstack
      &lt;/a&gt; / &lt;a href="https://github.com/gusanchefullstack/englishchunks.guru" rel="noopener noreferrer"&gt;
        englishchunks.guru
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn real English chunks daily with self-hosted open-source pronunciation scoring
    &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;EnglishChunks.guru&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A web app that teaches English &lt;strong&gt;chunks&lt;/strong&gt; — the ready-made phrases native speakers use, like &lt;em&gt;“that makes sense”&lt;/em&gt; or &lt;em&gt;“get used to”&lt;/em&gt; — to learners from A1 to C2, with one daily session: hear it, say it twice, write it, read it aloud, and get pronunciation scores and friendly tips from &lt;strong&gt;open-source AI running on infrastructure we control&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://englishchunks.guru" rel="nofollow noopener noreferrer"&gt;https://englishchunks.guru&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/ae85ea65c31462cb1fb16a174757ab95f98ae7839f08ba4e959ba10d22c8ab7b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f677573616e63686566756c6c737461636b2f656e676c6973686368756e6b732e677572752f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d4349"&gt;&lt;img src="https://camo.githubusercontent.com/ae85ea65c31462cb1fb16a174757ab95f98ae7839f08ba4e959ba10d22c8ab7b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f677573616e63686566756c6c737461636b2f656e676c6973686368756e6b732e677572752f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d4349" alt="CI"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/30749c4de0ed2aa91c8685f9a2276d7f2b2cff857b9c541dced6b3740673b081/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f63616c6962726174696f6e2d38392e312532352532307061697225323061636375726163792d316464366134"&gt;&lt;img src="https://camo.githubusercontent.com/30749c4de0ed2aa91c8685f9a2276d7f2b2cff857b9c541dced6b3740673b081/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f63616c6962726174696f6e2d38392e312532352532307061697225323061636375726163792d316464366134" alt="Scoring calibration"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/7cb0cb6689fc4f9e7507904b1381e234e1adc7fa2b60efbcff5a8093c726f8cc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6578742e6a732d31362d303830393061"&gt;&lt;img src="https://camo.githubusercontent.com/7cb0cb6689fc4f9e7507904b1381e234e1adc7fa2b60efbcff5a8093c726f8cc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6578742e6a732d31362d303830393061" alt="Next.js"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/bff76f256c7cb22c98d20da985b6d08065937de097e23263a3885e79baf63224/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322d333737364142"&gt;&lt;img src="https://camo.githubusercontent.com/bff76f256c7cb22c98d20da985b6d08065937de097e23263a3885e79baf63224/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322d333737364142" alt="Python"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e5b6dac5a3a84d823d1757962ac4608ee93ccfc073110175216ac771d00d44a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f574341472d322e3225323041412d383738396330"&gt;&lt;img src="https://camo.githubusercontent.com/e5b6dac5a3a84d823d1757962ac4608ee93ccfc073110175216ac771d00d44a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f574341472d322e3225323041412d383738396330" alt="WCAG"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#why-englishchunksguru" rel="noopener noreferrer"&gt;Why EnglishChunks.guru?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#screenshots" rel="noopener noreferrer"&gt;Screenshots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#how-it-works" rel="noopener noreferrer"&gt;How it works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#api-reference" rel="noopener noreferrer"&gt;API Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#project-structure" rel="noopener noreferrer"&gt;Project Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#tests" rel="noopener noreferrer"&gt;Tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#deployment" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#what-i-learned" rel="noopener noreferrer"&gt;What I learned&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#credits" rel="noopener noreferrer"&gt;Credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/englishchunks.guru#author" rel="noopener noreferrer"&gt;Author&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why EnglishChunks.guru?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Most apps teach single words, but fluent speakers think in chunks: &lt;em&gt;“by the way”&lt;/em&gt;, &lt;em&gt;“make a decision”&lt;/em&gt;, &lt;em&gt;“I tend to…”&lt;/em&gt;. Learners need to &lt;strong&gt;say&lt;/strong&gt; those chunks out loud and know exactly which sounds to fix — and pronunciation feedback usually means sending your voice to a closed cloud API.&lt;/p&gt;
&lt;p&gt;This project does the speech scoring with…&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/gusanchefullstack/englishchunks.guru" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;The open models do the core job — listening to your voice and coaching you:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Open model&lt;/th&gt;
&lt;th&gt;Runs on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Find your speech&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Silero VAD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;my own server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What you said&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;NVIDIA Parakeet TDT 0.6B&lt;/strong&gt; (int8 ONNX)&lt;/td&gt;
&lt;td&gt;my own server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How each sound was pronounced&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;wav2vec2 phoneme model&lt;/strong&gt; + forced alignment&lt;/td&gt;
&lt;td&gt;my own server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Friendly tips &amp;amp; writing feedback&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 4 26B&lt;/strong&gt; (open weights)&lt;/td&gt;
&lt;td&gt;Vercel AI Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Checks every library chunk&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;gpt-oss-20b&lt;/strong&gt; as an independent auditor&lt;/td&gt;
&lt;td&gt;Vercel AI Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;scoring service&lt;/strong&gt; is Python/FastAPI on one &lt;strong&gt;DigitalOcean Droplet&lt;/strong&gt; (2 vCPU, 4 GB). A score comes back in &lt;strong&gt;~1.1 s&lt;/strong&gt; on a typical recording.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;web app&lt;/strong&gt; is Next.js 16 on Vercel with Postgres on Neon; audio examples come from &lt;strong&gt;ElevenLabs&lt;/strong&gt; and are cached on &lt;strong&gt;DigitalOcean Spaces&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The AI never invents the teaching: pronunciation hints come from a curated table of ~40 English sounds, and the model only wraps them in a warm sentence.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; your voice never goes to a third-party API. Recordings are scored in memory on my server and &lt;strong&gt;deleted immediately&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; a cloud speech API charges per minute of audio. Self-hosted models cost a flat &lt;strong&gt;$28/month&lt;/strong&gt;, which is what makes $7 plans possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; I can see &lt;em&gt;why&lt;/em&gt; a sound scored low (phoneme-level alignment) and calibrate it on a public, expert-rated dataset — it ranks the better pronunciation higher in 89% of pairs. That's impossible with a black-box API.&lt;/li&gt;
&lt;/ul&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; — Gemma 4 writes every tip and grades every sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of DigitalOcean&lt;/strong&gt; — the self-hosted speech scoring runs on a Droplet; audio and avatars live on Spaces + CDN.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; — every chunk, example and learner sentence is spoken by ElevenLabs voices (generated once, then cached).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to the Hacktoberfest team for creating these challenges! A lot of learnings from every week! 👏👏👏💪&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>My learning path to software engineer</title>
      <dc:creator>Gustavo Sanchez</dc:creator>
      <pubDate>Mon, 12 Oct 2026 04:26:28 +0000</pubDate>
      <link>https://dev.to/gusanchedev/my-learning-path-to-software-engineer-2lb</link>
      <guid>https://dev.to/gusanchedev/my-learning-path-to-software-engineer-2lb</guid>
      <description>&lt;p&gt;Since the COVID-19 pandemic, I've become interested in software engineering. Even though I'm an electronics and telecommunications engineer, 20 years ago I had no real experience with software technologies for frontend or backend — neither at university nor at my first jobs. But the lockdown gave me time to explore new technical concepts, libraries, and frameworks, and it was definitely the seed that made me want to become a software engineer.&lt;/p&gt;

&lt;p&gt;Over these last 2 years, I've had the opportunity to learn about software from several sources and online education platforms, but the most remarkable one — and my personal recommendation — is &lt;a href="http://www.masters.dev" rel="noopener noreferrer"&gt;www.masters.dev&lt;/a&gt; (previously FrontendMasters), with all content in English. It includes extensive learning paths in programming languages, frontend libraries and frameworks, and backend technologies. All of these courses and options can be overwhelming, so I decided to share the path I'm currently following and the rationale behind those decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The primary goal&lt;/strong&gt;&lt;br&gt;
Every good plan starts with a primary goal upfront, and after many iterations, I've decided I want to be an engineer with the skills to create applications that solve real problems for users — applications with the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;End-to-end applications&lt;/em&gt; deployed in the cloud, covering frontend, backend, database, and APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Beautiful user interfaces (UI)&lt;/em&gt; with smooth and intuitive user experiences (UX)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Responsive design&lt;/em&gt; that displays properly on mobile, web, and desktop screens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Scalable and maintainable architectures&lt;/em&gt; in both frontend and backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;AI-native or AI-enhanced applications&lt;/em&gt; that leverage the power of artificial intelligence technologies such as agents, LLMs, and RAG, among others, to create compelling and innovative capabilities that improve or speed up business outcomes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can be a daunting goal. In fact, it is. But with that goal in mind, it's easier to break the job down into small, digestible steps that allow me to learn and enjoy the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big steps
&lt;/h2&gt;

&lt;p&gt;To reach my goal, I've structured my learning process into key phases that cover the minimum knowledge required to build end-to-end applications. These steps are:&lt;/p&gt;

&lt;h3&gt;
  
  
  Programming Language
&lt;/h3&gt;

&lt;p&gt;I have chosen &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/a&gt; (a JavaScript superset). It's a compiled, strongly typed language, well supported by Microsoft and the community, with a clear roadmap. For me, the main reason was the possibility of using it not just in the frontend (every browser supports JavaScript, which is the result of compiling TypeScript) but also in the backend, so I can develop core applications for Node.js (among other runtimes) using TS/JS. In my case, it's just a matter of time.&lt;/p&gt;

&lt;p&gt;Some useful resources for learning TypeScript:&lt;/p&gt;

&lt;p&gt;📌 The TypeScript Handbook (free): &lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/docs/handbook/intro.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Frontend Masters' path (paid): &lt;a href="https://frontendmasters.com/learn/typescript/" rel="noopener noreferrer"&gt;https://frontendmasters.com/learn/typescript/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  React.js in the Frontend
&lt;/h3&gt;

&lt;p&gt;There are a lot (I mean… a lot) of frameworks and libraries for developing beautiful and functional user interfaces. I selected &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React.js&lt;/a&gt; because it's currently the most in-demand and widely used framework across several industries. There is extensive documentation, along with courses and tutorials. Even though support and future development recently migrated from Meta to The React Foundation, companies like Amazon, Huawei, Meta, Microsoft, and Vercel back its continued evolution. The main reason here: adoption in enterprises and startups.&lt;/p&gt;

&lt;p&gt;Some available learning resources:&lt;/p&gt;

&lt;p&gt;📌 React.js (free): &lt;a href="https://react.dev/learn" rel="noopener noreferrer"&gt;https://react.dev/learn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 React.js Tutorial for Beginners on YouTube (free): &lt;a href="https://youtube.com/playlist?list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&amp;amp;si=o7qhFfrwYhdp-L5g" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&amp;amp;si=o7qhFfrwYhdp-L5g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Frontend Masters' path (paid): &lt;a href="https://frontendmasters.com/learn/react/" rel="noopener noreferrer"&gt;https://frontendmasters.com/learn/react/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js for frontend and backend
&lt;/h3&gt;

&lt;p&gt;Although I have some previous experience with &lt;a href="https://expressjs.com/en/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt;, I decided to adopt &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; as a backend framework that lets me develop the API connecting front and back — all with the power of React.js components. Next.js is sponsored by &lt;a href="http://www.vercel.com" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, and the option to deploy directly to Vercel's platform, where I've already deployed some small projects, gives me solid knowledge of a well-known enterprise framework. It's recommended to have some experience with React.js to speed up the learning process for Next.js, and I personally recommend the following resources:&lt;/p&gt;

&lt;p&gt;📌 Next.js tutorial from Vercel (free): &lt;a href="https://nextjs.org/learn" rel="noopener noreferrer"&gt;https://nextjs.org/learn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Next.js Foundations (free): &lt;a href="https://vercel.com/academy/nextjs-foundations" rel="noopener noreferrer"&gt;https://vercel.com/academy/nextjs-foundations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Frontend Masters' path (paid): &lt;a href="https://frontendmasters.com/learn/react/" rel="noopener noreferrer"&gt;https://frontendmasters.com/learn/react/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Structures &amp;amp; Algorithms
&lt;/h3&gt;

&lt;p&gt;Building real backend apps requires you to know about data structures and algorithms. It's perhaps the toughest part of the process, but it's highly recommended if you really want a rewarding job as a software engineer. Based on what I know so far, I recommend these 2 resources:&lt;/p&gt;

&lt;p&gt;📌 Algorithms by Abdul Bari (free): &lt;a href="https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Grokking Algorithms, Second Edition: An Illustrated Guide for Programmers and Other Curious People (paid): &lt;a href="https://www.manning.com/books/grokking-algorithms" rel="noopener noreferrer"&gt;https://www.manning.com/books/grokking-algorithms&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Databases
&lt;/h3&gt;

&lt;p&gt;Like every step listed here, databases alone are a knowledge area that could take months or years to master. My goal isn't to become an expert; it's to be able to build something with enough background to ship it. So my path includes these 2 courses, which cover the fundamentals of databases and the details of SQL, the most widely used query language for databases.&lt;/p&gt;

&lt;p&gt;📌 Complete Intro to Databases, v2 (paid): &lt;a href="https://frontendmasters.com/courses/databases-v2/" rel="noopener noreferrer"&gt;https://frontendmasters.com/courses/databases-v2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Complete Intro to SQL &amp;amp; PostgreSQL (paid): &lt;a href="https://frontendmasters.com/courses/databases-v2/" rel="noopener noreferrer"&gt;https://frontendmasters.com/courses/databases-v2/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Agents
&lt;/h3&gt;

&lt;p&gt;This is one of the hottest and most exciting areas to learn right now. There are also plenty of frameworks and platforms for deploying agents, but my goal here is to build agents from the ground up with a complete framework, leveraging the power of AI. &lt;a href="http://Mastra.ai" rel="noopener noreferrer"&gt;Mastra.ai&lt;/a&gt; 's team is doing a great job developing the open source framework and platform and since mastra supports Typescript, is the chosen option in this phase. The purpose of having agents in web apps is to handle many backend or frontend tasks through them. If you really want to understand the basics, I highly recommend these 2 free courses and the Scrimba full path:&lt;/p&gt;

&lt;p&gt;📌 Mastra 101 — Learn how to build agents (free): &lt;a href="https://mastra.ai/course" rel="noopener noreferrer"&gt;https://mastra.ai/course&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Build Your First Agent in TypeScript (free): &lt;a href="https://mastra.ai/learn" rel="noopener noreferrer"&gt;https://mastra.ai/learn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Scrimba AI Engineer path (paid):&lt;br&gt;
&lt;a href="https://scrimba.com/ai-engineer-path-c02v/?via=u449ade2" rel="noopener noreferrer"&gt;Scrimba AI Engineer Path&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment on the Cloud
&lt;/h3&gt;

&lt;p&gt;Once you have the application built, the final step is to deploy it to the cloud to make it available to users. The 2 options I'm considering so far are &lt;a href="http://www.vercel.com" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; and AWS, although I'll try the first one initially.&lt;/p&gt;

&lt;p&gt;📌 Vercel Academy (free): &lt;a href="https://vercel.com/academy" rel="noopener noreferrer"&gt;https://vercel.com/academy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 AWS Cloud Practitioner Essentials (free): &lt;a href="https://skillbuilder.aws/learn/94T2BEN85A/aws-cloud-practitioner-essentials/8D79F3AVR7" rel="noopener noreferrer"&gt;https://skillbuilder.aws/learn/94T2BEN85A/aws-cloud-practitioner-essentials/8D79F3AVR7&lt;/a&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm3t53njcxxizonpvgjp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm3t53njcxxizonpvgjp.png" alt="My Software Engineering Journey" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In future posts, I'll document my key learnings at each step. I'll also share the capstone project I'll be building incrementally to put what I've learned into practice.&lt;/p&gt;

&lt;p&gt;I look forward to having you back here.&lt;/p&gt;

&lt;p&gt;Gustavo&lt;/p&gt;

</description>
      <category>career</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>I Built My Wife a Patient English Idiom Coach That Runs on Our Laptop</title>
      <dc:creator>Gustavo Sanchez</dc:creator>
      <pubDate>Sun, 04 Oct 2026 00:15:40 +0000</pubDate>
      <link>https://dev.to/gusanchedev/i-built-my-wife-a-patient-english-idiom-coach-that-runs-on-our-laptop-2m0h</link>
      <guid>https://dev.to/gusanchedev/i-built-my-wife-a-patient-english-idiom-coach-that-runs-on-our-laptop-2m0h</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;My wife Eugenia moved to San Francisco and is learning English. She's at an &lt;strong&gt;A2 (elementary) level&lt;/strong&gt;, and the thing that trips her up most isn't grammar, it's &lt;strong&gt;idioms&lt;/strong&gt;. People here say "it's a piece of cake", "let's call it a day" and "I'm under the weather" all the time, and a textbook doesn't teach you how to &lt;em&gt;say&lt;/em&gt; them.&lt;/p&gt;

&lt;p&gt;So I built her &lt;strong&gt;IdiomsMasterGirl&lt;/strong&gt;: a patient practice partner that teaches &lt;strong&gt;one common idiom a day&lt;/strong&gt; and then listens to her use it.&lt;/p&gt;

&lt;p&gt;A daily session takes under 20 minutes (her first full session did) and has six steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Learn&lt;/strong&gt; – the idiom, its meaning in simple English, a "when to use it" note, a literal-vs-figurative note and 3 example sentences. Every line has a ▶ button with a natural American voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speak (try 1)&lt;/strong&gt; – she records the idiom and each example. She gets &lt;strong&gt;accuracy&lt;/strong&gt;, &lt;strong&gt;clarity&lt;/strong&gt; and a &lt;strong&gt;combined score&lt;/strong&gt;, plus 1–3 warm tips that name the exact word that went wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speak (try 2)&lt;/strong&gt; – she records everything again and sees &lt;strong&gt;+N points&lt;/strong&gt; next to each line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write&lt;/strong&gt; – she writes 3 sentences of her own. Each one gets an idiom-use grade, a grammar grade, a corrected version with the change highlighted, and a short &lt;em&gt;why&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read aloud&lt;/strong&gt; – she listens to her corrected sentences, then reads them and gets scored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score&lt;/strong&gt; – a daily score, a 30-day chart and a 🔥 streak.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The part I care most about is the feedback. It's never "wrong". It's &lt;em&gt;"I heard “banana” for “school”. Say 'school' slowly. Make sure you say the 'oo' sound clearly."&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;The app runs on our laptop on purpose: the speech recognition, the tutor model and her recordings all stay there. So there's no hosted link. The screenshots below are the real app on a demo account. To keep anyone's real voice out of the post, the recordings were made with the Mac's built-in voice, with one word swapped on purpose so you can see a tip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn&lt;/strong&gt; — today's idiom, with a play button on every line:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskdtkh3imnj9jpd7oyhd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskdtkh3imnj9jpd7oyhd.png" alt="Learn step: the idiom " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speak&lt;/strong&gt; — every recording is scored, and the tips name the actual words:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqzfgej2sqvr8xveo03v.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqzfgej2sqvr8xveo03v.png" alt="Speak step: a score of 92 with accuracy and clarity, a " width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write&lt;/strong&gt; — her own sentences, corrected with the smallest change and a reason:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nl1t86ipvdih0p4e17i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nl1t86ipvdih0p4e17i.png" alt="Write step: " width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Progress&lt;/strong&gt; — a streak and a 30-day chart, to keep her coming back:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdk90xvhk19ji2x53fo81.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdk90xvhk19ji2x53fo81.png" alt="Progress page: a 5-day streak, 14 days practiced, an average of 79, and a line chart of daily scores" width="800" height="342"&gt;&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/gusanchefullstack" rel="noopener noreferrer"&gt;
        gusanchefullstack
      &lt;/a&gt; / &lt;a href="https://github.com/gusanchefullstack/idioms-master-girl" rel="noopener noreferrer"&gt;
        idioms-master-girl
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      One English idiom a day – learn it, say it, write it. A local-first practice partner built for my wife (Gemma via Ollama + faster-whisper).
    &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;IdiomsMasterGirl 💬&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;One English idiom a day: learn it, hear it, say it, write it, and read it aloud.&lt;/strong&gt; A
local-first practice partner for an A2 English learner. It listens to her speak, tells her
kindly which exact words to fix, and corrects her own sentences. The AI runs on the laptop
so her voice and mistakes stay private.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3e592dc9fab467e9454644992f27f0167f4a06b2d6a93de584c64dcff938ed81/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334432362d3333393933333f6c6f676f3d6e6f6465646f746a73266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/3e592dc9fab467e9454644992f27f0167f4a06b2d6a93de584c64dcff938ed81/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334432362d3333393933333f6c6f676f3d6e6f6465646f746a73266c6f676f436f6c6f723d7768697465" alt="Node.js"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/acb4bcc287a08738500b5c70aba1a5ae3eb70cf2c06a914cecdf5f8038d5af5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31322d3337373641423f6c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/acb4bcc287a08738500b5c70aba1a5ae3eb70cf2c06a914cecdf5f8038d5af5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31322d3337373641423f6c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465" alt="Python"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/8c3ae444958c6a370b6960696d0ec2242e61aad90d2137ab4b793153ee0892ee/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6578742e6a732d31362d3030303030303f6c6f676f3d6e657874646f746a73266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/8c3ae444958c6a370b6960696d0ec2242e61aad90d2137ab4b793153ee0892ee/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6578742e6a732d31362d3030303030303f6c6f676f3d6e657874646f746a73266c6f676f436f6c6f723d7768697465" alt="Next.js"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a404566f2cdad6daeddac889c0185b98fab7b669388f6c01f238c04f9261e595/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f6c6c616d612d47656d6d61253230342532304532422d3030303030303f6c6f676f3d6f6c6c616d61266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/a404566f2cdad6daeddac889c0185b98fab7b669388f6c01f238c04f9261e595/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f6c6c616d612d47656d6d61253230342532304532422d3030303030303f6c6f676f3d6f6c6c616d61266c6f676f436f6c6f723d7768697465" alt="Ollama"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a94d5573ebd0e2b7219fff405dca6c320d6c17111d132c379f58399e626015d1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d3535253230756e697425323025324225323034253230736d6f6b652d627269676874677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/a94d5573ebd0e2b7219fff405dca6c320d6c17111d132c379f58399e626015d1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d3535253230756e697425323025324225323034253230736d6f6b652d627269676874677265656e" alt="Tests"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/ccb60519979fec500ff4014c14e40fcd15700cc48f15f04299f53347a76a06c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d537065632532304b69742d366634326331"&gt;&lt;img src="https://camo.githubusercontent.com/ccb60519979fec500ff4014c14e40fcd15700cc48f15f04299f53347a76a06c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d537065632532304b69742d366634326331" alt="Spec Kit"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/06584450b37ef9f4988fdd0b12c3c949db2668886f72551239191d3b6a916751/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f677573616e63686566756c6c737461636b2f6964696f6d732d6d61737465722d6769726c"&gt;&lt;img src="https://camo.githubusercontent.com/06584450b37ef9f4988fdd0b12c3c949db2668886f72551239191d3b6a916751/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f677573616e63686566756c6c737461636b2f6964696f6d732d6d61737465722d6769726c" alt="Last commit"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/gusanchefullstack/idioms-master-girl/assets/screenshots/02-speak.png"&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%2Fgusanchefullstack%2Fidioms-master-girl%2FHEAD%2Fassets%2Fscreenshots%2F02-speak.png" alt="The Speak step: each recording gets accuracy and clarity scores, the words that were missed or unclear, and a warm tip"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#why-this-exists" rel="noopener noreferrer"&gt;Why this exists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#how-it-works" rel="noopener noreferrer"&gt;How it works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#quick-start" rel="noopener noreferrer"&gt;Quick start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#api-reference" rel="noopener noreferrer"&gt;API reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#project-structure" rel="noopener noreferrer"&gt;Project structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#tests" rel="noopener noreferrer"&gt;Tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#what-i-learned" rel="noopener noreferrer"&gt;What I learned&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#open-models-privacy-and-why-open-matters" rel="noopener noreferrer"&gt;Open models, privacy and why open matters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#known-limitations" rel="noopener noreferrer"&gt;Known limitations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#credits" rel="noopener noreferrer"&gt;Credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#screenshots" rel="noopener noreferrer"&gt;Screenshots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gusanchefullstack/idioms-master-girl#author" rel="noopener noreferrer"&gt;Author&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why this exists&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;I built this for &lt;strong&gt;Eugenia&lt;/strong&gt;, my wife. She is learning English in San Francisco at an A2
(elementary) level. Idioms are everywhere in American life ("it's a piece of cake", "let's call
it a day"), and they are hard to learn from a textbook.&lt;/p&gt;
&lt;p&gt;General apps don't fit her well. Flashcard…&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/gusanchefullstack/idioms-master-girl" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It's MIT-licensed. Setup is four commands (&lt;code&gt;nvm use&lt;/code&gt;, &lt;code&gt;npm install&lt;/code&gt;, &lt;code&gt;npm run setup&lt;/code&gt;, &lt;code&gt;npm run dev&lt;/code&gt;). The README covers configuration, the API and what I learned along the way.&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;Chrome (localhost)
  │  records webm/opus · falls back to the Mac's on-device voice
  ▼
Next.js 16 API routes
  ├── scoring ───► pure TypeScript: word alignment (WER), clarity, problem words
  ├── tutor ─────► Ollama + Gemma 4 E2B (4.6B, Apache 2.0), JSON-schema output
  ├── listening ─► Python sidecar: FastAPI + faster-whisper small.en
  ├── voice ─────► ElevenLabs (opt-in, text only, cached on disk)
  └── storage ───► SQLite via Node 26's built-in node:sqlite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Gemma is the tutor.&lt;/strong&gt; It writes the 3 example sentences for each day's idiom, the coaching hints, and the grades and corrections for her sentences. Every call uses Ollama's JSON-schema &lt;code&gt;format&lt;/code&gt;, and the code then &lt;strong&gt;validates&lt;/strong&gt; the answer: an example must contain the idiom and have at most 15 words, a correction must keep the idiom, and an explanation must be 40 words or fewer. A failed answer is retried once, then falls back honestly. The app never shows an invented grade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whisper is the ear.&lt;/strong&gt; &lt;a href="https://github.com/SYSTRAN/faster-whisper" rel="noopener noreferrer"&gt;faster-whisper&lt;/a&gt; gives a &lt;strong&gt;confidence for every word&lt;/strong&gt;, which is the whole scoring model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy&lt;/strong&gt; = &lt;code&gt;100 × (1 − word error rate)&lt;/code&gt; against the target sentence (case, punctuation and contractions ignored).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clarity&lt;/strong&gt; = the average word confidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combined&lt;/strong&gt; = 70% accuracy + 30% clarity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem words&lt;/strong&gt; = words that were missed, replaced, or heard with less than 0.6 confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;code&gt;temperature=0.0&lt;/code&gt; and &lt;code&gt;condition_on_previous_text=False&lt;/code&gt;, the same recording gets the same score every time. In my tests it was identical.&lt;/p&gt;

&lt;h3&gt;
  
  
  The lesson that changed the design
&lt;/h3&gt;

&lt;p&gt;My first version asked Gemma to write the tips. The tips were warm but vague, full of other idioms ("don't let tricky words get under your skin!"). In my first test, &lt;strong&gt;0 of 4&lt;/strong&gt; named the word that was actually missed.&lt;/p&gt;

&lt;p&gt;The fix was to &lt;strong&gt;split the job&lt;/strong&gt;. The code writes the facts it already knows, and Gemma writes only the coaching:&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="cm"&gt;/** The factual part of a tip is written in code, so every tip names a real word. */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;leadFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProblemWord&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="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;substituted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`I heard “&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heard&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;” for “&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;word&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="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;missing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`I didn't hear “&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;word&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="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unclear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`“&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;” was a little unclear.`&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;// final tip = leadFor(word) + " " + gemmaHint(word)   // e.g. "Make the 'oo' sound long."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that change, in a check of &lt;strong&gt;20 recordings, 20 of 20 tips named the right word&lt;/strong&gt;, and 18 of 20 hints were fully written by Gemma. When a recording is clean, there's no model call at all, just praise, so it never invents a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measured on a MacBook (M4):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Score and tips after a recording:&lt;/strong&gt; 1.1–2.9 s.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Today's examples:&lt;/strong&gt; about 2.6 s.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saved audio replay:&lt;/strong&gt; 17 ms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grammar corrections:&lt;/strong&gt; 13 of 15 known errors fixed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I planned and built it spec-first with &lt;a href="https://github.com/github/spec-kit" rel="noopener noreferrer"&gt;GitHub Spec Kit&lt;/a&gt;. The spec, plan, research, contracts and tasks are all in the repo under &lt;code&gt;specs/&lt;/code&gt;, with Claude Code as my pair programmer.&lt;/p&gt;

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

&lt;p&gt;For this project, open isn't a nice extra. It's the reason it works for her.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Her mistakes stay hers.&lt;/strong&gt; A learner's recordings are personal: the hesitations, the wrong words, the accent. With an open-weight model and open speech recognition running locally, &lt;strong&gt;her voice never leaves our laptop&lt;/strong&gt;. Recordings go to a helper on &lt;code&gt;127.0.0.1&lt;/code&gt;, are scored in memory and are never saved. There's no telemetry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's built to work offline.&lt;/strong&gt; The tutor, the speech recognition and the database all run locally, and the speech helper is started in offline mode. Only new natural-voice audio needs the internet, and saved clips plus the Mac's own voice cover that. (A full run with Wi-Fi switched off is next on my list.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's tuned to one person.&lt;/strong&gt; The prompts are Markdown files, the idioms are a curated JSON list I control, and the model is one line in &lt;code&gt;config/settings.json&lt;/code&gt;. Changing the tutor's personality ("warm, patient, playful big-sister tutor") is editing a text file. Grounding it in a &lt;strong&gt;curated list of 100 real A2–B1 idioms&lt;/strong&gt; means it can't invent fake idioms, which is a real risk with a 4.6B model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; There's no per-session API bill for something meant to be used every day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where open beat closed:&lt;/strong&gt; the scoring needs &lt;strong&gt;per-word confidence&lt;/strong&gt; and &lt;strong&gt;repeatable&lt;/strong&gt; results. Open Whisper gives both directly. A closed speech API would hide the confidences, or change them under me without notice. Being able to read and change every prompt also let me fix the vague-tips problem in an evening.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one non-open piece is the optional ElevenLabs voice, and I kept it honest. It's &lt;strong&gt;off by default&lt;/strong&gt;, it only ever receives the sentence to speak (never her audio or answers), and each sentence is generated &lt;strong&gt;once&lt;/strong&gt; and cached.&lt;/p&gt;

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

&lt;p&gt;I built this with Claude Code, following the Spec Kit flow from constitution to spec, plan, tasks and implementation.&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; – Gemma 4 E2B (via Ollama) is the tutor. It writes the daily examples, the pronunciation coaching and the writing grades and corrections, all with schema-constrained output that the code validates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; – the natural American voice she imitates. It's used in a privacy-respecting way: opt-in, text only, cached per sentence, with an on-device fallback when it's off or offline.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This post was written with AI assistance (Claude Code) and checked by me before publishing.&lt;/em&gt;&lt;/p&gt;

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