<?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: Aditya Kumar</title>
    <description>The latest articles on DEV Community by Aditya Kumar (@adityakumar2358).</description>
    <link>https://dev.to/adityakumar2358</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%2F4152822%2F9a5cf499-275d-4935-b473-c7ce914c5856.png</url>
      <title>DEV Community: Aditya Kumar</title>
      <link>https://dev.to/adityakumar2358</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adityakumar2358"/>
    <language>en</language>
    <item>
      <title>Please Give this a read</title>
      <dc:creator>Aditya Kumar</dc:creator>
      <pubDate>Sat, 03 Oct 2026 15:17:23 +0000</pubDate>
      <link>https://dev.to/adityakumar2358/please-give-this-a-read-f4i</link>
      <guid>https://dev.to/adityakumar2358/please-give-this-a-read-f4i</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8" class="crayons-story__hidden-navigation-link"&gt;Salt &amp;amp; Story: My Maasi's Recipes, Saved in Her Own Voice&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;Hacktoberfest: Maintainer Spotlight&lt;/p&gt;

&lt;/a&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/adityakumar2358" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4152822%2F9a5cf499-275d-4935-b473-c7ce914c5856.png" alt="adityakumar2358 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/adityakumar2358" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Aditya Kumar
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Aditya Kumar
                
                
              
              &lt;div id="story-author-preview-content-4792488" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/adityakumar2358" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4152822%2F9a5cf499-275d-4935-b473-c7ce914c5856.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Aditya Kumar&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 3&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8" id="article-link-4792488"&gt;
          Salt &amp;amp; Story: My Maasi's Recipes, Saved in Her Own Voice
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devchallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/weekendchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;weekendchallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hf26challenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hf26challenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hacktoberfest"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hacktoberfest&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;18&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Salt &amp; Story: My Maasi's Recipes, Saved in Her Own Voice</title>
      <dc:creator>Aditya Kumar</dc:creator>
      <pubDate>Sat, 03 Oct 2026 15:16:50 +0000</pubDate>
      <link>https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8</link>
      <guid>https://dev.to/adityakumar2358/salt-story-my-maasis-recipes-saved-in-her-own-voice-56g8</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;blockquote&gt;
&lt;p&gt;⭐ &lt;strong&gt;If this story means something to you, please star the repo:&lt;/strong&gt; &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story" rel="noopener noreferrer"&gt;github.com/ADITYA-KUMAR-2358/salt-and-story&lt;/a&gt;. It helps more families find it.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;h3&gt;
  
  
  Who I built it for
&lt;/h3&gt;

&lt;p&gt;My &lt;strong&gt;Maasi&lt;/strong&gt; (my mom's sister, my aunt) has cancer. A few weeks ago we learned she probably has two to three years left.&lt;/p&gt;

&lt;p&gt;She makes the best food I know. Not fancy food: comforting, tasty, the kind you remember for the rest of your life.&lt;/p&gt;

&lt;p&gt;A few days back I saw her writing in her diary. When I asked, she told me it was her famous &lt;strong&gt;chili and lemon pickle&lt;/strong&gt; recipe. She had written a few others too, each with a lovely message and the name of the person it was for. My favourite thing she cooks is her &lt;strong&gt;Dahi Wada&lt;/strong&gt;, and guess what: there it was, a recipe addressed to me.&lt;/p&gt;

&lt;p&gt;She had spent hours writing those pages by hand. So I thought: what if she could just &lt;em&gt;talk&lt;/em&gt;, the way she does in the kitchen, and her recipe came out exactly in her words?&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;Salt &amp;amp; Story&lt;/strong&gt;. Maasi has now recorded those recipes with her voice, and they are live, written the way she said them. I also added a way to turn them into a personalised book, and a lot more, because &lt;em&gt;every recipe has a story&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem it solves for her
&lt;/h3&gt;

&lt;p&gt;Writing recipes by hand is slow and tiring, and the way Maasi really cooks ("a pinch of this, cook it till it looks right") never fits neatly on a page anyway. Salt &amp;amp; Story lets her simply speak, and it keeps her exact words instead of flattening them into a generic recipe. For our family, it means her food and her voice stay with us.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Salt &amp;amp; Story&lt;/strong&gt; is a web app that turns spoken recipes into a printable family cookbook.&lt;/p&gt;

&lt;p&gt;You record a voice memo in the browser (or upload one, or paste the words), and Salt &amp;amp; Story:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transcribes it,&lt;/li&gt;
&lt;li&gt;structures it into ingredients, steps and tips,&lt;/li&gt;
&lt;li&gt;turns vague measures like "a fistful" into rough quantities &lt;strong&gt;while keeping the original phrase right next to them&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;keeps one memorable line, &lt;strong&gt;verbatim&lt;/strong&gt;, as a pull-quote (checked against the transcript in code),&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;never invents&lt;/strong&gt; an ingredient, amount or step that wasn't said,&lt;/li&gt;
&lt;li&gt;exports everything as a designed A5 PDF cookbook.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was never a recipe database. It was a book that sounds like Maasi.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's in it
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;What you can do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Capture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Record in the browser with a live level meter, upload a memo (mp3, m4a, wav, webm, ogg), paste a transcript, or write a recipe by hand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recipe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read it with an ingredient checklist and tappable steps, edit everything (with an unsaved-changes guard), add a photo, keep the original transcript one tap away&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cook mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One step at a time in large type, the screen kept awake, arrow keys or big buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Listen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ElevenLabs narration of the whole recipe, cached so it is paid for once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Book&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pick and order recipes, a live cover preview, a dedication, an editable "Recipes told by" line, and an A5 PDF with contents and page numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Organise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search, favourites, delete with confirmation, backup and restore as JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accounts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sign in with Google; each family's recipes are private to their account; delete your account and everything in it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Start fast&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Six American and European family classics with openly licensed photos, added in one tap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comfort&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Light and dark mode, 17px base text, 44px tap targets, keyboard and screen reader friendly, reduced-motion support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://salt-and-story-web.onrender.com/" rel="noopener noreferrer"&gt;https://salt-and-story-web.onrender.com/&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%2Fspfwzty8m25p9rscmgi6.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%2Fspfwzty8m25p9rscmgi6.png" alt="Salt &amp;amp; Story landing page with the tagline " width="800" height="372"&gt;&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%2Fauyje16v47xz95xp3ss0.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%2Fauyje16v47xz95xp3ss0.png" alt="A recipe page in Salt &amp;amp; Story showing the photo, a pull-quote in the cook's own words, an ingredient checklist and numbered steps" width="800" height="363"&gt;&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%2Fimyr4o3y2ejshy5ticuo.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%2Fimyr4o3y2ejshy5ticuo.png" alt="Cook mode on a phone: a single recipe step in large type with big Previous and Next buttons" width="800" height="387"&gt;&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%2Fh1o12s0lt1bda5doomqr.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%2Fh1o12s0lt1bda5doomqr.png" alt="A two-page spread from the printed A5 PDF cookbook: photo, title, story and the cook's words on the left; ingredients, method and tips on the right" width="800" height="386"&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/ADITYA-KUMAR-2358" rel="noopener noreferrer"&gt;
        ADITYA-KUMAR-2358
      &lt;/a&gt; / &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story" rel="noopener noreferrer"&gt;
        salt-and-story
      &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;Salt &amp;amp; Story&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Because Every Recipe Has A Story&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Salt &amp;amp; Story turns voice memos of a relative cooking into clean, printable recipes, while keeping the speaker's own words beside them. Record or upload a memo, an open-weight model (&lt;strong&gt;Gemma 4&lt;/strong&gt;) writes it up, and you export a cookbook PDF that looks like a gift.&lt;/p&gt;
&lt;p&gt;It is built for one real family: the person who tells recipes out loud and has never written them down, and the grandchild who wants to keep them.&lt;/p&gt;
&lt;p&gt;Built by &lt;strong&gt;Aditya Kumar&lt;/strong&gt; (&lt;a href="https://github.com/ADITYA-KUMAR-2358" rel="noopener noreferrer"&gt;@ADITYA-KUMAR-2358&lt;/a&gt;) for the DEV Hacktoberfest Weekend Challenge, "Build for a Friend".&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Agents and contributors: start with &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/" rel="noopener noreferrer"&gt;&lt;code&gt;docs/&lt;/code&gt;&lt;/a&gt; (&lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/PRD.md" rel="noopener noreferrer"&gt;PRD&lt;/a&gt;, &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/ARCHITECTURE.md" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt;, &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/RULES.md" rel="noopener noreferrer"&gt;Rules&lt;/a&gt;, &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/DESIGN.md" rel="noopener noreferrer"&gt;Design&lt;/a&gt;, &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/TASKS.md" rel="noopener noreferrer"&gt;Tasks&lt;/a&gt;, &lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story/docs/MEMORY.md" rel="noopener noreferrer"&gt;Memory&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capture&lt;/strong&gt;: record in the browser (live level meter), upload a memo, paste a transcript, or write a recipe by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write it up&lt;/strong&gt;: ElevenLabs…&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/ADITYA-KUMAR-2358/salt-and-story" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;⭐ A star on the repo would genuinely make my day.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Open-source AI at the core:&lt;/strong&gt; &lt;strong&gt;Gemma 4&lt;/strong&gt; (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;, Google's open-weight model) structures every recipe. I call it through the Gemini API's OpenAI-compatible endpoint on the free tier, so the same code also runs against &lt;strong&gt;local Ollama&lt;/strong&gt; (for example &lt;code&gt;gemma3:4b&lt;/code&gt;) by changing three environment variables. The model turns a rambling transcript into structured JSON, and it is the heart of Salt &amp;amp; Story.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+--------------------------------------+
| BROWSER                              |
| React 19, Vite, TypeScript 7         |
| Tailwind v4, GSAP                    |
+--------------------------------------+
    |             |              |
    | app files   | JSON +       | Sign in
    |             | Bearer       | with Google
    v             v              v
+--------+  +-------------+  +----------+
| Static |  | FastAPI     |  | Google   |
| site   |  | Python 3.14 |  | Identity |
+--------+  +-------------+  +----------+
                   |
                   +--&amp;gt; SQLite: accounts, recipes
                   +--&amp;gt; Files: photos, audio
                   +--&amp;gt; ElevenLabs: STT + TTS
                   +--&amp;gt; Gemma 4: Gemini API
                   |             or Ollama
                   +--&amp;gt; WeasyPrint: HTML -&amp;gt; PDF

  Hosted on Render (or docker compose locally)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, Vite, TypeScript 7, Tailwind v4, GSAP&lt;/td&gt;
&lt;td&gt;Fast to build, strict types, a few deliberate animations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;FastAPI, Pydantic v2, SQLModel on Python 3.14&lt;/td&gt;
&lt;td&gt;Typed models end to end; background tasks for slow AI work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI writer&lt;/td&gt;
&lt;td&gt;Gemma 4 26B (A4B) via an OpenAI-compatible API&lt;/td&gt;
&lt;td&gt;Open weights, swappable host, free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech&lt;/td&gt;
&lt;td&gt;ElevenLabs Scribe (speech-to-text) and multilingual TTS&lt;/td&gt;
&lt;td&gt;Handles messy kitchen audio; natural narration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF&lt;/td&gt;
&lt;td&gt;WeasyPrint with Jinja2 templates&lt;/td&gt;
&lt;td&gt;Real print CSS: page counters, running headers, leaders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accounts&lt;/td&gt;
&lt;td&gt;Google Identity Services + signed sessions&lt;/td&gt;
&lt;td&gt;No passwords to store&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;Render Blueprint: Docker web service + static site&lt;/td&gt;
&lt;td&gt;One &lt;code&gt;render.yaml&lt;/code&gt; describes both&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  From a voice memo to a recipe
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Cook records or uploads a voice memo
        |
        v
 ElevenLabs Scribe ----&amp;gt; transcript
        |
        v
 Gemma 4 &amp;lt;---- rules: never invent,
        |             keep their words
        v
 recipe as JSON
        |
        v
 Pydantic check --bad JSON--&amp;gt; retry,
        |                     error fed back
        v
 Is the quote really in the transcript?
        |   no --&amp;gt; use closest real sentence
        v
 Ready to read, cook, edit and print
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The status moves &lt;code&gt;uploaded → transcribing → structuring → ready&lt;/code&gt; (or &lt;code&gt;failed&lt;/code&gt;, always with a reason and a next step). If the server restarts mid-memo, it marks that memo as interrupted instead of leaving a spinner forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things I had to get right
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not inventing things.&lt;/strong&gt; The prompt forbids adding ingredients or steps that weren't said, the JSON is validated with Pydantic, and bad output is retried with the validation error fed back. For Maasi's recipes this mattered more than anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeping her voice.&lt;/strong&gt; The pull-quote must be an exact substring of the transcript. The code checks this and falls back to the closest real sentence if the model paraphrases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable models.&lt;/strong&gt; The model endpoint is three environment variables, so the same code runs against local Ollama or a hosted open-weight model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A book that looks like a gift.&lt;/strong&gt; Each recipe is a two-page spread: photo, title, story and their words on the left; ingredients, method and tips on the right. Steps never split across pages, headings never strand at the bottom, and continuation pages carry the recipe name in a running header. I checked it by rendering real books and looking at every page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A free API key that strangers can't drain.&lt;/strong&gt; See the next section.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Protecting a free API key
&lt;/h3&gt;

&lt;p&gt;A public demo on free tiers needs guardrails, so every request passes through several layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Sign in with Google
   |-- throwaway email domain?  --&amp;gt; refused
   |   (about 9,200 blocked)
   |-- 2+ new accounts from this
   |   network today?           --&amp;gt; refused
   v
 Ask for a recipe
   |-- account used its 5 today? --&amp;gt; try tomorrow
   |-- network used its 10?      --&amp;gt; refused
   |-- same transcript before?   --&amp;gt; reused, free
   v
 Throttle + queue (one call at a time)
   |-- 429 or 5xx --&amp;gt; wait, retry, then explain
   v
 Gemma 4 writes the recipe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guard&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recipes (or narrations) per account per day&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Fair share of the free quota&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New accounts per network per day&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Stops one device making many accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI requests per network per day&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Stops one device spending many accounts' quota&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throwaway email domains refused&lt;/td&gt;
&lt;td&gt;about 9,200&lt;/td&gt;
&lt;td&gt;No disposable sign-ups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests per account per 10 minutes&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Stops bursts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model calls per minute / per day (whole server)&lt;/td&gt;
&lt;td&gt;10 / 300&lt;/td&gt;
&lt;td&gt;Last line of defence for the key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identical transcripts&lt;/td&gt;
&lt;td&gt;reused&lt;/td&gt;
&lt;td&gt;"Try a sample" costs nothing the second time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only real AI calls count against an account's 5: writing by hand, editing, photos, classics and books are free. IP addresses are stored only as salted hashes, and the visitor's IP is read from Cloudflare's &lt;code&gt;True-Client-IP&lt;/code&gt; header on Render, never from a header the client can fake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Numbers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Time to write one recipe, Gemma 4 default reasoning&lt;/td&gt;
&lt;td&gt;80 to 190 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same, with minimal thinking (&lt;code&gt;thinking_level: minimal&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;12 to 44 seconds&lt;/strong&gt; in most runs (one slow free-tier run took about 2 minutes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend tests&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;83&lt;/strong&gt;, all mocked (no quota used)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend branch coverage&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;92%&lt;/strong&gt; (CI requires at least 90%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser checks against the Docker build&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;123&lt;/strong&gt;: every page, every link, the book PDF, a real Gemma recipe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responsive audit&lt;/td&gt;
&lt;td&gt;14 pages at 5 widths (320 to 768px) plus 6 sizes up to 1920px: no text overflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A six-recipe book&lt;/td&gt;
&lt;td&gt;19 A5 pages including cover, contents and closing page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python versions tested&lt;/td&gt;
&lt;td&gt;3.13 and 3.14&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quality checks on every pull request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Pull request
   |
   +--&amp;gt; Lint + format (ruff, Oxlint) -----+
   |                                      |
   +--&amp;gt; Security (CodeQL, Gitleaks,       |
   |    pip-audit, npm audit) ------------+
   |                                      |
   +--&amp;gt; Tests (Py 3.13 + 3.14,            |
   |    coverage &amp;gt;= 90%) ---+             |
   |                        |             |
   +--&amp;gt; Type check + build -+             |
                            |             |
                            v             |
              Docker build + 123          |
              browser checks -------------+
                                          |
                                          v
                              All checks passed
                                          |
                                          v
                                   Ready to merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dependabot keeps Python, npm, Docker images and GitHub Actions up to date, and every update goes through the same checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was hard
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed.&lt;/strong&gt; Gemma 4 reasons before it answers, and my first recipes took up to three minutes. Passing a minimal thinking level brought that down to well under a minute with the same quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reasoning text in the output.&lt;/strong&gt; Gemma 4 prefixes its answer with a &lt;code&gt;&amp;lt;thought&amp;gt;&lt;/code&gt; block, which broke JSON parsing until I stripped it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free-tier limits.&lt;/strong&gt; 429s and the occasional 500 from the provider needed polite retries, a one-at-a-time queue and clear "try again in a minute" messages instead of crashes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The PDF engine everywhere.&lt;/strong&gt; WeasyPrint needs native libraries (Pango): easy in Docker and on Render, painful on Windows until I scripted a private install.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The real visitor IP.&lt;/strong&gt; Behind Render's proxy, the usual &lt;code&gt;X-Forwarded-For&lt;/code&gt; header can be faked by the client, so the per-network limits read Cloudflare's &lt;code&gt;True-Client-IP&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling on the newest versions.&lt;/strong&gt; TypeScript 7 is so new that typescript-eslint doesn't support it yet, so I lint with Oxlint instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I'd do next
&lt;/h3&gt;

&lt;p&gt;Hindi and Hinglish support (with a Devanagari PDF font), so Maasi's recipes can be printed in the language she actually speaks; shared family libraries so several relatives can add to one book; playback of the original voice memo, so we can always hear her say it; and a printed hardcover option.&lt;/p&gt;

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

&lt;p&gt;Salt &amp;amp; Story handles something deeply personal: a family member's voice and memories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Control.&lt;/strong&gt; With an open-weight model, the structuring step can run on my own machine or server. In the hosted demo, audio goes to ElevenLabs for transcription and transcripts go to Google's Gemini API, which runs Gemma; switching &lt;code&gt;LLM_BASE_URL&lt;/code&gt; to local Ollama keeps transcripts on my own computer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappability.&lt;/strong&gt; Because the model sits behind a standard endpoint, I can change models without rewriting the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; It's free to run, on the free tier or locally, which matters when the "user" is a family member and not a customer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tunability.&lt;/strong&gt; I could shape the prompt and behaviour to protect what mattered most: faithfulness to what was actually said.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a closed model, Maasi's words would only ever be processed wherever one company decided. With open weights, they can stay with our family.&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 structures every recipe, with its output validated and its quotes checked against the transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: Salt &amp;amp; Story is deployed on Render from a Blueprint: a Docker web service for the API and a static site for the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt;: speech-to-text turns voice memos into transcripts, and text-to-speech reads recipes aloud.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Somewhere in that app is a Dahi Wada recipe with my name on it, in Maasi's own words. That's the whole reason it exists.&lt;/p&gt;

&lt;p&gt;If you have someone whose recipes live only in their head, record them while you can. &lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://salt-and-story-web.onrender.com/" rel="noopener noreferrer"&gt;https://salt-and-story-web.onrender.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if this story touched you, please ⭐ &lt;strong&gt;&lt;a href="https://github.com/ADITYA-KUMAR-2358/salt-and-story" rel="noopener noreferrer"&gt;star Salt &amp;amp; Story on GitHub&lt;/a&gt;&lt;/strong&gt;. Thank you for reading. ❤️&lt;/p&gt;

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