Behind the Scenes
How We Built Thoughtbook: A Social Platform With No Likes
Thoughtbook is the strangest product we have shipped, because it is defined by what it refuses to have. It is a public journaling platform: you write your thoughts, and others can read them. There are no likes, no followers, no comments, and no reposts. Not because we ran out of time, but because removing them was the entire idea. This is the story of building it: seven months, 221 commits, and one backend we threw away completely.

The idea: writing without a scoreboard
Every social platform turns writing into a competition. The moment a like counter exists, people write for the counter. We wanted the opposite: a quiet, monochrome place where students and overthinkers could write honestly because there is no score to chase. That decision shaped everything else:
- Three posts per day, hard limit. When you cannot post endlessly, you post deliberately. Our commit history shows how we got here: we first tried a timer between posts, tweaked it, then realized timers encourage waiting rather than thinking, and replaced the whole mechanism with a simple daily limit of three.
- No links or emails inside posts. Posts that contain URLs are rejected. This one rule removes almost the entire economy of spam before it starts.
- Copying is disabled on posts. A small anti-theft gesture: your words are yours, and scraping them at least takes effort.
- Analytics about you, for you. Instead of likes, you get private writing statistics: your streak, the hours and days you write most, and how your entries split between quick notes, reflections, and long essays.
- Your journal as a book. You can export everything you have written as a PDF book. We think of it as the real reward for a year of honest writing.
The stack
Next.js with the App Router, React, Tailwind CSS with a strict monochrome token system and the system font stack (no webfonts at all), PostgreSQL through Prisma with trigram indexes powering search, and custom JWT authentication with short-lived access tokens and rotating refresh cookies. Registration is protected by Cloudflare Turnstile instead of a traditional CAPTCHA, email is verified with a one-time code sent through Resend, and disposable email domains are blocked. Errors go to Sentry. There is an admin area for handling reported posts, because a public writing platform without moderation is a promise you cannot keep.
The hardest part: deleting our own backend
Thoughtbook originally ran as two applications: a Next.js frontend talking to a separate Express and MongoDB backend. It worked, but every feature meant changes in two codebases, two deployments, and two places for bugs to hide. In August we made the call we had been avoiding: we migrated the entire backend into Next.js API routes on PostgreSQL and deleted the Express app. The cutover took a focused week of commits: infrastructure first, then auth routes, then posts, users, analytics and PDF export, then the admin routes, and finally the switch. Losing a codebase you spent months on feels like failure. It is not. The product got faster, deployment became one step, and every feature since has taken half the time.
What actually ate our time
The big architecture was never the daily struggle. The struggle was, in roughly descending order: keeping the post input bar fixed at the bottom of a scrolling feed on mobile (a series of scroll and position fixes over many commits), the OTP input on the email verification screen (input bleeding, paste support, keyboard type on phones), sizing the Turnstile widget so it did not break the auth form layout, and, we confess, one entire day of commits that did nothing but adjust the logo and icons. We also shipped a cookie consent banner and later removed it together with the analytics scripts that required it: fewer third-party scripts, faster pages, no banner.
Testing like it matters
Thoughtbook has over a thousand lines of Playwright tests covering full user journeys: sign up with OTP, log in, post, hit the daily limit, search, check analytics, export the book, and the legal pages. The same suite runs against production after deploys, and our GitHub Actions pipeline runs linting, type checks, and database migrations automatically. For a small team, automated journeys are the difference between "we think it works" and "we watched it work an hour ago."
What we learned
Three lessons worth stealing. Constraints are features: the three-post limit does more for content quality than any algorithm could. Two codebases for one product is one too many when your team is small. And the work that shows up in no screenshot (auth hardening, rate limits, moderation tools, tests) is most of what separates a demo from a product people can trust with their private thoughts made public.