<?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: Shreyas Prajapati</title>
    <description>The latest articles on DEV Community by Shreyas Prajapati (@shreyas_prajapati_7911096).</description>
    <link>https://dev.to/shreyas_prajapati_7911096</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%2F4158032%2Fea6ae8c8-f3ed-4759-8043-32cb7f1a5b5e.png</url>
      <title>DEV Community: Shreyas Prajapati</title>
      <link>https://dev.to/shreyas_prajapati_7911096</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shreyas_prajapati_7911096"/>
    <language>en</language>
    <item>
      <title>Email became my second job, so I built Snoozebox: a sleepy inbox where Gemma reads my mail and Snorlax eats my tasks</title>
      <dc:creator>Shreyas Prajapati</dc:creator>
      <pubDate>Sun, 25 Oct 2026 13:13:49 +0000</pubDate>
      <link>https://dev.to/shreyas_prajapati_7911096/email-became-my-second-job-so-i-built-snoozebox-a-sleepy-inbox-where-gemma-reads-my-mail-and-ikh</link>
      <guid>https://dev.to/shreyas_prajapati_7911096/email-became-my-second-job-so-i-built-snoozebox-a-sleepy-inbox-where-gemma-reads-my-mail-and-ikh</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One morning I opened my inbox and found an email from Internshala saying my L'Oréal application was not complete. It was already 17 hours overdue. It was sitting between a Codeforces reminder and three LinkedIn job alerts.&lt;/p&gt;

&lt;p&gt;I'm not bad at email. Email is just built so that everything looks equally important. A thread with five replies gives you five notifications, and the one message with a real deadline looks exactly like the newsletter above it.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Snoozebox&lt;/strong&gt;. Your inbox, asleep on the job. Mostly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR.&lt;/strong&gt; Snoozebox is a local-first email manager. Gemma 2 2B runs on your own laptop through Ollama, reads your Gmail, sorts it, pulls out deadlines, merges threads into single tasks and gives you a 30-second morning report. Every label comes with a real quote from the email. Nothing leaves your computer, and every email costs €0.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A morning report with Snorlax in it.&lt;/strong&gt; It says things like "Only one thing is worth waking up for today." Each urgent item shows what to do, when it's due, and the exact line from the email that proves it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One task per thread.&lt;/strong&gt; If someone emails Tuesday, follows up Wednesday and moves the deadline on Thursday, you get one task. The old date is crossed out and the new one is highlighted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quotes or nothing.&lt;/strong&gt; Every priority label is backed by a verbatim quote. If the model can't quote it, the email is marked "Not analyzed" and you check it yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deadlines in plain words.&lt;/strong&gt; "Friday noon" and "before 6 PM today" are turned into real timestamps by code, not guessed by the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quiet hours.&lt;/strong&gt; From 22:00 to 08:00 nothing gets through except your VIP senders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Done means munch.&lt;/strong&gt; Hit Done and Snorlax eats the task. You get five seconds to undo it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I picked Snorlax because the challenge theme is "reward laziness", and nobody is lazier or more committed to it.&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%2F9159xshpu0636nuuw58g.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%2F9159xshpu0636nuuw58g.png" alt="Analyzed Mail" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just ask a cloud model?
&lt;/h2&gt;

&lt;p&gt;An inbox is one of the most private things on a computer. Mine has contracts, password resets, flight details and job applications. I didn't want to send that to someone else's API, and I didn't want to pay per token for 100 emails a day.&lt;/p&gt;

&lt;p&gt;So everything runs locally. Gemma 2 2B uses about 1.6 GB of VRAM and runs at roughly 62 tokens per second on my RTX 3050 laptop GPU. It's a small model, which brings me to the main design rule.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Gemma reads, code checks.&lt;/strong&gt; The model suggests a category, a priority, an action and a supporting quote. Then plain code takes over: it checks that the quote really appears in the email, converts date phrases into exact timestamps, and decides which messages belong to the same task. A 2B model is good at reading and bad at being exact, so I never ask it to be exact.&lt;/p&gt;

&lt;p&gt;The stack is a Go backend, pure-Go SQLite (no CGO, so it builds on Windows without drama), a React 19 and TypeScript frontend served by the same Go binary, and the Gmail API with the OAuth token stored only on disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does it work?
&lt;/h3&gt;

&lt;p&gt;I wrote 30 test emails with known answers and ran the whole pipeline on them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&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;Urgent recall&lt;/td&gt;
&lt;td&gt;3 of 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Urgent precision&lt;/td&gt;
&lt;td&gt;3 of 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deadlines exactly right&lt;/td&gt;
&lt;td&gt;16 of 17 (94.1%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;about 62.5 tokens/sec&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is a small test. Three urgent emails proves nothing about the real world. It tells me the pipeline isn't broken, not that it's finished. [ONE LINE: describe the one deadline it got wrong and why.]&lt;/p&gt;

&lt;h3&gt;
  
  
  Bugs I'm not proud of
&lt;/h3&gt;

&lt;p&gt;When I connected my real Gmail, things got embarrassing fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same task appeared twice on the Morning screen, so the "items that need your brain" counter was wrong.&lt;/li&gt;
&lt;li&gt;The screen said "1 threads" and "1 urgent things".&lt;/li&gt;
&lt;li&gt;A backend JSON error showed up with a green check mark next to it.&lt;/li&gt;
&lt;li&gt;Emails all showed the same time instead of when they actually arrived.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test data was too clean to catch any of this. Real inboxes are messy, and I'd recommend connecting a real one earlier than I did.&lt;/p&gt;

&lt;h3&gt;
  
  
  My first design looked like a robot made it
&lt;/h3&gt;

&lt;p&gt;The first redesign was tidy and looked like every AI dashboard: identical white cards, identical stat tiles, a tiny mascot in the corner. So I rebuilt it around one character, gave the copy a dry and sleepy voice, and made Snorlax react to how many urgent items there are. Zero urgent and he sleeps. A few and he opens an eye.&lt;/p&gt;

&lt;p&gt;Before&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbiwcy8i0avia5u1dt3n.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%2Fqbiwcy8i0avia5u1dt3n.png" alt="AI Slop" width="799" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp2n5x7ovv0c1hj5zzobf.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%2Fp2n5x7ovv0c1hj5zzobf.png" alt="Creative UI" width="799" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you hit Done, the card shrinks toward Snorlax, he munches, and a toast says "Munch." with an Undo button. This is the part I'm proudest of, and it took the least code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxr5v3d3mea9s2dujvnlb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxr5v3d3mea9s2dujvnlb.gif" alt="Tasks Done Snorlax Eats it " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;p&gt;This only makes sense if the model is free to run and stays on your machine. With open weights nobody pays per email, and your inbox never trains anyone's next model.&lt;/p&gt;

&lt;p&gt;The honest tradeoff is that a small local model is less clever than a frontier one. That's why code handles everything that must be exact, and why anything uncertain is labeled "Not analyzed" instead of being guessed.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;A small model works well when it only has to read and quote. The moment I asked it to also be right about dates, it stopped being reliable, so dates became code.&lt;/li&gt;
&lt;li&gt;Making the app say "I don't know" is a feature. The "Not analyzed" badge makes the other labels easier to trust.&lt;/li&gt;
&lt;li&gt;Lazy software is harder to build than busy software. The best moment in the app is when you do nothing.&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 2 2B through Ollama does all the reading, entirely on a laptop GPU.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/PresenceOP-Coder/Hacktoberfest-Week3" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=D7nUILStDoU&amp;amp;list=LL&amp;amp;index=1" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;br&gt;
Snorlax is © Nintendo / Creatures / GAME FREAK. This is a fan project, not affiliated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I drafted this post with AI help and edited it myself. The numbers come from the test suite in the repo.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
