Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥
This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3 (Slow and Steady).
Live demo: https://nightbrief-black.vercel.app/studio
Code: https://github.com/sherotree/nightbrief
Prize category: Best Use of Gemma.
What I built
Nightbrief is a browser-only morning brief for the overnight pile.
You paste a group-chat export or a mailbox dump — or drop a .txt / .md file — before you sleep. In the morning you open the studio, hit Digest overnight, and Gemma writes two short lines about what actually needs you. Things that can wait fold into a short list underneath. There is no Nightbrief server, no API key, and no account. The paste never leaves the page.
The product is deliberately lazy. It does not sync Slack. It does not OAuth Gmail. It does not try to be an inbox. It assumes you already have the text on the nightstand — the export you saved because you were too tired to read it — and it turns that into coffee-length English.
A fictional Maple Court building-chat sample is built in, so judges (and you) can try it without using a real inbox. Open the studio from the landing page, or choose Load fictional sample.
Demo
npm install
npm run dev
Open /studio. Load the fictional sample. Choose Digest overnight.
Needs a WebGPU browser (current desktop Chrome or Edge). The first run downloads open Gemma weights from Hugging Face into the browser cache — about 1.9 GB of VRAM for the default Gemma 2 2B q4f16 build. Later mornings use the cache. If your GPU has no shader-f16, pick Gemma 2 2B f32. If you want a lighter download, pick Gemma 3 1B.
Out of scope for this week: Slack/Gmail connectors, fine-tuning, and multi-user auth. Those would make the dump easier to fetch; they would also stop being “the messages stay on this machine.”
How I built it
Stack: Next.js (App Router), TypeScript, @mlc-ai/web-llm 0.2.86, WebGPU.
Default model: gemma-2-2b-it-q4f16_1-MLC (Gemma 2 2B instruction-tuned). Also on the menu: Gemma 3 1B, and Gemma 2 2B f32 when shader-f16 is missing. The studio checks that the chosen id is actually in WebLLM’s published catalog before it loads.
The useful engineering is not “ask an LLM to summarize.” It is making a tiny open-weight model behave like a morning note:
- Two lines are the product. The prompt asks for a hero output of exactly two short lines — decisions and time changes first — plus optional bullets for noise that can wait. The UI treats the two lines as the headline, not a chat transcript.
- Gemma runs in the tab. WebLLM + WebGPU. No server route calls a model host. After the weights are warm, the digest does not need a model API.
- Catalog edge cases are real. Gemma 3 1B’s published WebLLM record sets a 4k context on top of a sliding window, which the runtime rejects. Nightbrief turns the sliding window off and uses 2k so the lighter model actually loads.
- Sample first. Maple Court is a fake overnight dump with a stuck elevator, a potluck move, and hot water shutoff — enough structure to show the two-line shape without private mail.
I did not fine-tune Gemma. A 2B instruction model is enough for “what matters tomorrow morning” when the dump is a few pages, and small enough that asking someone to download it once is still a fair ask for a lazy tool.
Why open innovation matters here
Overnight chat and mail are not public blog drafts. They are names, addresses, complaints about the elevator, and “can you bring dessert.” Sending that pile through a hosted chat API is convenient and also the whole risk.
Open-weight Gemma changes the shape of the product in four concrete ways:
- Privacy. The overnight dump is handed only to an in-browser engine. Nightbrief does not upload it.
- No per-digest bill. After the first weight download, the meter is electricity you already bought — which is why a “summarize my chat every morning” habit does not turn into a token subscription.
- Swappable model. The studio can move between Gemma 2 2B, Gemma 3 1B, and the f32 build without changing providers or rewriting the product.
- Slow and Steady, literally. The tool rewards leaving the pile alone overnight and collecting two lines with coffee. That only works if the model is allowed to sit on the laptop and wait — not if every morning is a paid round-trip.
Gemma is the right default for Best Use of Gemma because it is small enough to contemplate in a tab and instruction-tuned enough to write a short morning note when you show it the dump and ask for two lines. It is not a reason to skip a WebGPU check or pretend software GPUs finish a full decode in five minutes. Nightbrief’s bet is that local Gemma + a ruthless two-line format is the product, not a chat window with a summary button.
The lazy payoff
You do not read the overnight pile. You paste it once. In the morning you get two lines — and then you get on with the day.
If the elevator is stuck and the potluck moved to Sunday, that is enough. The rest can wait.
Prize Categories
- Best Use of Gemma
Top comments (3)
Hey Sherotree! 👋
I really like the simplicity of Nightbrief. Running Gemma entirely in the browser, without accounts or a hosted inference API, is a thoughtful approach to handling private conversations. And making the two-line brief the actual product, rather than building another chat interface, is a nice design decision.
I downloaded the repository and spent some time going through the source code. I also ran the tests — all 9 passed! 😊
A couple of small observations, if you don’t mind:
The current fitDump() implementation keeps only the last 10,000 characters. I wonder whether an important message from earlier in the night could disappear before Gemma ever sees it. A chunked summarization approach might be worth exploring, especially for longer conversations.
I also noticed that the engine cleanup depends on engineRef.current. If someone navigates away while CreateMLCEngine() is still loading, the newly created engine might not be covered by that cleanup. Probably an interesting lifecycle edge case to test.
These are just suggestions, of course. I appreciate how deliberately you’ve kept the architecture focused. The local-first approach, model compatibility handling, and simple interface are all thoughtful choices.
Really nice work, and best of luck with the challenge!
Thanks Mustafa - glad the tests and the two-line shape landed. You're right that fitDump truncating to the last 10k can drop earlier overnight decisions; I'll look at a chunked pass for longer dumps. The CreateMLCEngine race on navigate-away is a real edge case too - I'll tighten that cleanup. Appreciate you reading the source.
You’re very welcome, Sherotree! 😊
I always enjoy seeing projects that solve a real problem without adding unnecessary complexity. Nightbrief is a great example of that. And thanks for being so open to feedback! That’s one of my favorite things about open source. We share ideas, learn from each other, and hopefully make things a little better along the way. Looking forward to seeing where you take Nightbrief next. Keep building, and good luck with the challenge!