🌱 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 / ought before 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_cache table β€” anonymous device_id (crypto.randomUUID()), no email, no account.
  • quiet_letters table β€” 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, validates deliver_at between 7 days and 5 years, generates verification token, sends double-opt-in email via Resend, returns token.
  • verify-letter β€” sets verified_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." Sets sent_at = now().
  • purge-delivered β€” daily 3am UTC cron. Hard-deletes rows where sent_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_cache and quiet_letters tables 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

app-b3tuv7opfegx.appmedo.com

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

Share this project:

Updates

posted an update —

Day 14 update β€” catch-up across v38, v40–v44, and what's actually shipped now

Six days of changelog in one post, because I was building instead of writing about building.

v38 β€” The Quiet Letter (3 routes, 1 table, 4 edge functions, hard-deletes itself)

You write a letter today to your future self. You pick a date β€” 7 days out to 5 years out. We email it on that date, exactly once. Then within 24 hours we hard-delete the row from our database. No copy kept. The email is the only artifact.

  • Compose, sealed-confirmation, and verify routes at /letter, /letter/sealed/:token, /letter/verify/:token.
  • New Supabase quiet_letters table with RLS denying all client reads/writes β€” service-role only from edge functions.
  • 4 new Deno edge functions: seal-letter, verify-letter, deliver-letters (hourly cron), purge-delivered (daily 3am UTC cron that hard-deletes anything sent_at < now() - 24h and unverified drafts older than 7 days).
  • Double opt-in via verification token. The token is the only identity β€” no account, no login, no inbox, no edit-after-seal.
  • Reuses the existing Resend integration. Verification email + delivery email use the same template as the Sunday Pattern email.

Pitch I've been using: FutureMe has 15 million letters in its database. Evengood will have zero. The value isn't in the storage; it's in the deletion.

Zero modifications to existing reflection/witness/pattern/Sunday-email code. Entirely new surface area, because MeDo struggles with surgical edits across existing files. Lesson from earlier: structure every new feature as new files, never patches.

v40–v42 β€” Foundation design system pass (visual chrome only, zero business logic touched)

The original UI was a glassy lavender→peach gradient with translucent cards. Looked fine. Felt like every wellness app on the App Store. So I rebuilt the visual chrome across 3 versioned prompts:

  • Warm ivory canvas #FAF9F5 (Claude.ai inspired β€” never #FFFFFF).
  • Fraunces variable serif for headers, italic where it earns it.
  • JetBrains Mono for uppercase chrome labels β€” YOUR WEEK, A QUIET PATTERN, SAVED, RELEASED.
  • Dark ink buttons (#2D1B47 fill, cream text). No pill shapes. No gradients on buttons.
  • The lavenderβ†’peach gradient was deleted everywhere except as a 1px horizon line that appears in exactly four places and nowhere else: under the wordmark, as the only success animation (draws Lβ†’R over 600ms), as section divider, in the email footer.
  • All success/error feedback replaced with the Horizon. No toasts. No checkmarks. No modal backdrops.

The whole thing is locked behind a Tailwind config + global CSS. Tokens only β€” if it isn't a token, it can't appear. No new colors, no new radii, no new durations. The voice is enforced in CSS now, not just in copy.

v44 β€” Burn Mode (write-and-release, never stored)

A small low-contrast link under the saved sentence: "let it burn instead". Click it. A Fraunces italic confirmation replaces the save row: "this will not be saved. it will simply pass." with two quiet buttons. Confirm, and the text rasterizes to a canvas and dissolves into ash particles drifting upward over 2.2 seconds at 60% opacity. The page fades to a single italic line: "it passed." β€” visible for 4 seconds, then back to empty compose.

The burned sentence 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. Some things are not for tomorrow.

State as of today

  • Three quiet features shipped: 60-second reflection (home), The Quiet Letter (delivery + auto-delete), Burn Mode (release).
  • The Sunday Pattern email is still 52 sentences a year, total. No streaks. No notifications.
  • New design system applied uniformly. Single horizon mark is the brand fingerprint.
  • 5 edge functions in production (detect-pattern, seal-letter, verify-letter, deliver-letters, purge-delivered).
  • 2 Supabase tables, both with RLS denying client access.
  • Anonymous device_id is the only identifier that ever leaves the browser.

6 days to hackathon deadline.

Try it: app-b3tuv7opfegx.appmedo.com

The Quiet Letter is at /letter. Write to yourself. We'll deliver it once. Then we'll forget you wrote it.

BuiltWithMeDo

Log in or sign up for Devpost to join the conversation.

posted an update —

Day 5 update

Shipped v15 live. One additive feature today: Export as image.

After a reflection is complete (or when you tap a past dot in the history view), there's now a Save as image button next to Download audio. It renders the reflection into a 1080x1920 portrait PNG sized for Instagram Story, with the app's own lavender-to-peach gradient, the Tomorrow line in Playfair Display as the hero, a short excerpt of the reflection below a thin divider, and a tiny 'evengood' watermark. Client-side only via html2canvas, waits for document.fonts.ready before rasterizing so the serif types render crisp, downloads as evengood-YYYY-MM-DD.png.

Why this feature: journaling apps that no one talks about stay small. The keepsake we were already generating was only useful if you kept coming back. An image you can save to your camera roll (or share, if you want) creates a second life for the reflection outside the app.

Deliberately not doing: no social buttons, no share sheet, no watermark/app download prompt overlay. If someone shares it, it's because they wanted to.

Try v15: https://app-b3tuv7opfegx.appmedo.com

25 days to go.

Log in or sign up for Devpost to join the conversation.

posted an update —

Day 4 update

Shipped v12 live on the deployed app today. Three fixes landed in one prompt:

  1. Tappable past days. The 7 dots under YOUR WEEK used to be pure decoration. Now you can tap any filled dot to revisit that day's reflection + the Tomorrow prompt it gave you. Persists in localStorage keyed by ISO date.
  2. Loading state copy. Replaced the silent ~15-second wait after submit with a two-line message: "writing your tomorrow..." in Playfair italic + "(usually about 10 seconds)" in small Inter. Same wait, completely different feeling.
  3. English-only guardrail. A fellow builder flagged that the LLM was occasionally slipping Chinese characters into the keepsake text. Added a strict English-only system instruction + a CJK-unicode validator that re-generates the response once if any non-Latin script is detected.

One lesson that stuck: the best Day-4 features are usually the ones that make Day 1 finally feel finished. Adding an emotional-trends chart would've been flashier; fixing the streak ribbon that pretended to be interactive was the right call.

Try v12: https://app-b3tuv7opfegx.appmedo.com

Full write-up: https://dev.to/vineetnegi0101/i-built-an-app-to-help-myself-end-the-day-without-spiraling-day-4-of-30-4pp5

Log in or sign up for Devpost to join the conversation.

Submission history