π± Why this exists
For two years I've closed my laptop at 11pm and kept working inside my own head until 1am. I've tried every journaling app on the App Store. They all feel like homework β notebooks I abandon, streaks I fail at, prompts I resent. I wanted the opposite: a closing ritual that takes under a minute, leaves you with something small and beautiful, then quietly gets out of the way.
Evengood is the calm reflection app for people who are tired of being managed by their apps.
Tagline: end every day on an even, good note.
The thesis: every wellness app weaponizes attention. Push notifications. Streak shaming. Daily badges. Premium upsells for features that already exist in iOS. Evengood is the opposite stance β the only journaling app where the only email it sends is 52 sentences a year, total, and where some features (The Quiet Letter, Burn Mode) actually delete what you wrote rather than archive it.
βοΈ What it does
Three features. Each one is also a constraint on what we'll never build.
1. The 60-second reflection (home page) You tap the mic β or type, if you'd rather β and talk for sixty seconds about your day. Evengood holds the silence, then gives you back:
- a Tomorrow line β one small thing to notice tomorrow, read aloud in a soft voice. Not a to-do. Not advice. A whole-word forbidden-word filter strips
should / must / need / oughtbefore the sentence is ever shown, so Tomorrow can never become a prescription. - a watercolor keepsake β a unique image of the feeling behind what you said, generated from a one-word theme the app extracts from your reflection. No faces. No text. No logos.
- after 5+ reflections, A Quiet Pattern β one observational sentence naming what tends to drain you and what tends to lift you. Heavier days in peach. Lighter days in lavender. Seen once a week and quietly held. No score. No streak. No share button.
2. The Quiet Letter (/letter)
The feature judges remember.
You write a letter today to your future self. You pick a date β anywhere from 7 days out to 5 years out. We seal it. On that date, exactly once, we email it to you. Then, within 24 hours of sending, we hard-delete the row from our database. We don't keep a copy. You'll have the email; that's the only artifact.
Architected as 3 routes, 1 Supabase table with RLS denying all client access, and 4 Deno edge functions: seal-letter, verify-letter, deliver-letters (hourly cron), purge-delivered (daily 3am UTC cron that hard-deletes anything past its retention window). Double opt-in via verification token. The token is the only identity β there is no account, no login, no inbox, no draft saves, no edit-after-seal.
FutureMe has 15 million letters in its database. Evengood will have zero.
3. Burn Mode (Release, inside /letter)
You write a sentence. You tap "let it burn instead." A calm Fraunces italic line replaces the save row: "this will not be saved. it will simply pass." You confirm. The text rasterizes to a canvas, dissolves into ash particles drifting upward over 2.2 seconds, and the page fades to a single italic line: "it passed." It is never written to localStorage, never sent to Supabase, never counted in the weekly Pattern. It simply ceases to exist.
No undo. No "are you sure?" No log of what was destroyed. Some things are not for tomorrow.
π οΈ How I built it
Built entirely inside MeDo in ~14 days, versioned across 44 prompt iterations (v1 β v44). Every file written inside the MeDo editor.
Frontend β React + TypeScript + Tailwind + Vite, generated and iterated inside MeDo. Design system v40+: warm ivory canvas (#FAF9F5), Fraunces variable serif for headers, JetBrains Mono for uppercase chrome labels (YOUR WEEK, A QUIET PATTERN, SAVED, RELEASED), deep ink (#2D1B47) for text, locked lavender (#E8DFF5) β peach (#FDDCB5) horizon gradient that appears as a 1px line in exactly four places and nowhere else: under the wordmark, as the only success animation, as section divider, in the email footer. The horizon is the visual realization of the tagline.
Speech β Web Speech API for transcription. Web Audio for the optional ambient track (silent / rain / soft piano).
LLM β MeDo's Gemini plugin, three distinct calls each behind a forbidden-word validator and a CJK-unicode validator that re-generates once if any non-Latin script slips through.
Image generation β Kling AI via MeDo's image plugin. Fixed prompt template so every watercolor belongs to the same emotional family. Negative prompts enforce the locked palette: people, faces, hands, text, watermark, logo.
Backend β Supabase Postgres with Row Level Security denying all client reads/writes:
pattern_cachetable β anonymous device_id (crypto.randomUUID()), no email, no account.quiet_letterstable β service-role access only, from edge functions.
5 edge functions in Deno:
detect-patternβ sentiment scoring + keyword extraction + a non-streaming Gemini call with a whole-word forbidden-word validator.seal-letterβ POST endpoint, validates body 1β4000 chars, validatesdeliver_atbetween 7 days and 5 years, generates verification token, sends double-opt-in email via Resend, returns token.verify-letterβ setsverified_at = now(), returns success/already_verified.deliver-lettersβ hourly cron. Selects verified, unsent, due rows. Sends each via Resend with the original date in the subject and a footer line "this letter has now been deleted from our server." Setssent_at = now().purge-deliveredβ daily 3am UTC cron. Hard-deletes rows wheresent_at < now() - 24h. Also hard-deletes unverified drafts older than 7 days.
Email β Resend, reused across all three email types (Sunday Pattern, Quiet Letter verification, Quiet Letter delivery). Same template: Fraunces italic header, warm canvas background, JetBrains Mono labels, the lavenderβpeach horizon as the only brand mark.
Export β html2canvas, client-side only, waits for document.fonts.ready so the serif renders crisp. 1080Γ1920 portrait PNG sized for Instagram Story. No share buttons, no app-download overlay. If someone shares it, it's because they wanted to.
Observability β every plugin call is wrapped in a stage-labeled try/catch. In production, failures are silent (the user never sees a spinner or a toast β the page returns to its empty state). In debug mode (?debug=1 + x-debug-token header), the response includes the failed stage so I can fix it without touching production behavior.
π§ Challenges I ran into
The streaming SSE parser for The Pattern returned null on every first call. I'd built the whole edge function before realising the plugin's response shape didn't match what my parser expected. Folded a same-day patch: non-streaming POST, expanded stopwords, auto-heal refetch. The lesson stuck: ask for observability first, then ship.
The LLM also occasionally slipped Chinese characters into the watercolor keepsake text. A fellow MeDo builder flagged it on Day 4. Fixed in one prompt with the CJK validator.
The hardest decision wasn't technical. It was killing the Text-to-Video feature I'd scoped on Day 1. I got it working β and a still image with a single sentence felt calmer than the video. So I pulled the video and shipped the stillness. Small app, not big app.
The other hard one: the v40 design pass. The original UI was a glassy lavenderβpeach gradient background with translucent cards. It looked fine. It felt like every wellness app on the App Store. I did 4 prompt iterations (v40 β v44) to swap the entire visual chrome to warm-paper / Fraunces / hairline borders, while modifying zero edge functions, zero email templates, and zero business logic. Pure styling pass. The product became calmer in a way I can't quite describe but every user can feel.
MeDo limitation I learned the hard way: it struggles with surgical edits. When you ask it to "modify only X," it tends to rewrite whole files. So I structured every new feature (Quiet Letter, Burn Mode) as entirely new surface area β new routes, new components, new tables, new edge functions β rather than patches on existing code. This kept all 44 versions stable in production.
β Challenge Compliance
Evengood qualifies for the Build with MeDo Hackathon main submission and uses MeDo deeply across plugins and backend:
- MeDo AI plugins β Gemini (Tomorrow line, Pattern detection, theme extraction, TTS), Kling AI (watercolor keepsake), Speech-to-Text.
- MeDo Backend / Supabase β
pattern_cacheandquiet_letterstables with RLS, 5 edge functions in Deno, 2 scheduled cron jobs. - HTTP plugin β Resend for all email (Sunday Pattern, Quiet Letter verification, Quiet Letter delivery).
- Full-stack original build β no scaffolding, no boilerplate, every file written inside the MeDo editor across 44 versioned prompts.
π What I gained (that has nothing to do with code)
I stopped shipping features that would make Evengood bigger, and started shipping the ones that would make it quieter. That's a weirdly hard rewiring for a builder. The Pattern is one of the features I'm proudest of, and the only thing it does is show you one sentence you already knew about yourself. The Quiet Letter is the other β the value isn't in the database, it's in the deletion.
No metric in the world would've told me to build either of them. I had to trust that something small would feel like something real.
π What's next
- The Echo β when you open the app, if you have an entry older than 30 days, surface one quietly above tonight's prompt with the framing "you wrote this 47 days ago β no need to do anything with it." Anti-attention version of Day One's "On This Day."
- Multi-week Pattern evolution β "the rhythm changed this week."
- Native iOS share sheet for the watercolor.
Never: ads, premium tier, social feed, leaderboard, streak push notifications, "you haven't journaled in 3 days!" emails.
π Try it
60 seconds. No account. Nothing to install. If you've ever ended a day feeling like you were still at work inside your own head β I built this for that version of you.
The Quiet Letter is at /letter. Write to yourself. We'll deliver it once. Then we'll forget you wrote it.
Built With
- ai
- baidu
- cloud
- deno
- gemini
- html2canvas
- kling
- medo
- postgresql
- react
- resend
- speech
- supabase
- tailwindcss
- tts
- typescript
- vite
- web
Log in or sign up for Devpost to join the conversation.