How to pivot a SaaS: from dating site to love letters

An old domain, a registered trademark and a saturated market. What I kept, what I threw away, and why the new product is smaller than the old one.

6 min readBuild logs

To pivot a SaaS, keep the asset that still has value and change what you build on it. For Crush on You the asset was a short domain, a name people say out loud and a registered trademark. The product on top was a dating site in a market I could not win. I kept the name and turned it into an app for love letters sent as a private link, forking another product of mine for everything that was not new.

What was there to pivot?

Crush on You was a dating site: sign up, sign in, "discreet encounters". It was registered as a trademark in Brazil for a relationship app, and the domain was still mine. The product itself had no reason to exist. Dating apps live or die on how many people are already near you, and a new one starts with nobody.

So the question was not "how do I make the dating site work". It was "what is this name good for, if not dating".

How do you pick the new idea?

I wrote down fifteen ideas and cut them against three things I could not change:

  • The name. "Crush" is the part before dating: the doubt, the "does she like me", the message you never send.
  • The trademark. It covers a relationship app, so the new product had to stay inside that description.
  • No network on day one. Anything that only works when thousands of people already use it was out.

That removed most of the list. Mutual crush matching needs a network. Anonymous confessions need heavy moderation and attract a young audience. What survived was the most literal reading of the name: a letter to your crush, designed, sent as a link, with a way for them to answer. One person can get value from it the first time they use it, which is the test I describe in validating a SaaS idea.

What did the fork keep?

The new product shares almost nothing with the old one, and almost everything with Copix. Copix already had Stripe embedded checkout with currency conversion, magic link sign in, encrypted personal data, Mailgun, a blog engine and a Railway deploy. I copied that repo, and then the rule from the Copix fork applied again: anything shaped like the old product gets deleted, not extended.

Out went the MCP server, the credits ledger, the SEO engine and the OAuth provider. In came one model, Letter, and the pages around it.

Kept from the fork Built new
Embedded checkout, currencies, webhooks The builder, with a live preview
Magic link sign in Drafts owned by a signed cookie, no account needed
Encryption at rest The letter page and the envelope
Blog and legal pages as files Three languages under /en, /pt-br and /es
Railway Dockerfile Photos in a Railway bucket

Decisions that kept it small

No account to write. The builder works signed out. The draft belongs to the browser through a signed cookie, and paying creates the account from the checkout email.

Pay per letter, never a subscription. Free (a simple design, the link lasts seven days), Letter, Letter+, and a one-time Unlimited pass that also sits in checkout as a single checkbox. I go through that trade-off in subscription or one-time pricing.

A letter never shows more than was paid for. Before a letter goes out, one method strips what its tier does not include: the paid design falls back to the free one, the song and the reply buttons go. The tier picker shows that list before anyone pays.

An open is a tap, not a page view. The recipient sees a closed envelope first. Opening it sends a small request to the server, and only that counts as "opened". Chat apps fetch links to build previews, so counting page views would have told every sender their letter was read the moment they pasted it into WhatsApp.

Three languages from the first commit

The name works in Brazil and in Spanish-speaking countries as well as in English, so the site shipped in all three at once. Every page people read lives under a language prefix and lists its alternates for search engines. On the blog, each article has one shared key, so every translation knows its siblings. A letter page speaks the language the letter was written in, whatever the recipient's browser says.

Prices are set in dollars and shown in local currency. A price ending in .99 stays one: at the day's rate, $9.99 showed as R$ 49,99, not R$ 50. Reais use a decimal comma, and on the Portuguese and Spanish pages dollars read as US$, because "quot; alone also means pesos.

What broke, and what caught it?

None of these were crashes, and every one would have shipped unnoticed:

  1. Share links carried ?locale=en. Rails added the page language to every URL, including the private letter link people paste into chats. The request specs caught it, and the fix drops the language from the routes that live outside a language prefix.
  2. An FAQ question printed %{free_days}. The answer was interpolated, the question was not. I only saw it when I pasted the page text into an SEO check.
  3. Dates showed in UTC. A letter sent at 11pm in São Paulo said 02:15. The browser now stores its time zone in a cookie and the server formats dates in it.
  4. The preview showed the free badge. A draft has no tier yet, so it rendered as free. The badge now appears only on letters that were sent free.

The landing page went through Copix before launch. The first check flagged the H1 as a slogan instead of the topic and the copy as too promotional. After the rewrite the H1 states what the product does ("Send a love letter online") and passes. The hype flag barely moved: what it asks for is real reviews and named people, which a product launched today does not have. That is the same order I follow in SEO for a small SaaS: fix the page, then earn the proof.

What I cut for later

No mobile app, even though the trademark covers one. No mutual matching. No printed cards or flowers at checkout. Each could come later, and none of them is needed to answer the only question that matters now: will people pay a few dollars to say something hard in a nicer way. Cutting to that question is the whole point of scoping an MVP you can finish.

If you are deciding whether to pivot something of your own, how to build a SaaS as a solo founder covers the earlier steps, from the idea to the first customers.


Crush on You, if there is something you have not said

A note on fit first. If you can say it in person, say it in person. Crush on You does not write the letter for you, and it will not change how anyone feels.

Crush on You lets you write a love letter or a crush confession, pick a design and send it as a private link. They open an envelope, read it, and with Letter+ they can answer in one tap. Free to start, in English, Portuguese and Spanish.

See Crush on You

Frequently asked questions

What is Crush on You?

A way to send a love letter or a crush confession as a private link. The recipient taps an envelope to open it, reads the letter in the design you picked and, on the Letter+ plan, answers Yes, Maybe, Let's talk or No. You see when it was opened. It runs in English, Portuguese and Spanish.

When should you pivot a SaaS instead of shutting it down?

When something you own still has value the product isn't using: a domain, a name people remember, a trademark, an audience or code. A pivot keeps that asset and changes what is built on top of it. If nothing like that exists, starting fresh is usually cheaper.

How do you pick what to pivot into?

List what you can't change (the name, the legal protection, the market you can reach), then list ideas and cut every one that fights those constraints. The idea that survives is the one the asset already argues for.

Is it faster to fork your own code for a pivot?

Yes, if the old and new products share the boring parts: checkout, sign in, email, encryption, deploy. Fork, then delete everything shaped like the old product before adding anything new. The deleting is what keeps the fork from becoming two products glued together.

The software I build and run

Everything on this blog is tested on these first. Each one was built alone, shipped in public and used every day, by me first.

Keep reading