Repository
Pitchless
Reads what people are asking on Reddit, tells you which questions your product genuinely answers, and writes a reply for you to check before it goes anywhere.
Find the Reddit posts where your app is the answer.
Private repository. Everything below is written from the code; none of it is a link you can follow.
What it is
You connect an app. It monitors the subreddits where its users are, scores every new post for whether your product genuinely answers it, drafts a reply in a human register, and shows you the queue. You approve or discard.
Why it exists
Every indie developer has the same distribution problem and the same two bad options: post about your launch and be ignored, or lurk hoping to catch a relevant question. The second works and does not scale, because it means reading everything. This automates the reading and leaves the judgement.
As a business
The most obviously commercial thing I have built — a clear buyer, a clear alternative, and usage costs that map to pricing. The uncomfortable part is the point: a tool that drafts replies designed not to read as marketing is one product decision away from being a spam engine. What separates them is entirely in the scoring, and the architecture takes the honest side — a human approves every reply.
Stack
- Client
- React · Vite · shadcn/ui · Capacitor
- Backend
- Supabase · Twelve edge functions
The decision
The problem
The scoring model faces a badly imbalanced problem. The overwhelming majority of posts are not answerable by your product, and the two errors cost wildly different amounts: a missed opportunity costs nothing, and a false positive costs a reply that reads as spam, in public, attached to your product's name. The naive version of this tool is worthless precisely because it optimises for finding something.
What I did
Fit is judged per thread before any reply is drafted, and the score is surfaced to the human rather than used to post. Drafting is a separate function, so a low-scoring post never reaches it. Splitting fetch, analyse and save also means a post can be re-scored without being re-fetched.
What it costs
A model call per candidate post is the dominant cost, and it is spent mostly on posts that will be discarded — the economics are the inverse of the value. Any attempt to cut that by pre-filtering cheaply is exactly where the false positives would come back.
Where it ended
Built and parked. Complete enough to run — onboarding, auth, analytics, digests — with no evidence of a launch.
On screen

A piece of the code
supabase/functions/fetch-opportunities/index.ts
const ageHours = getPostAgeHours(post.created_utc);if (ageHours > 24) continue; // Skip dead threads// Quick score to avoid expensive comment fetch on bad postsconst quickScore = calculateOpportunityScore({ post_age_hours: ageHours, upvotes: post.score, comment_count: post.num_comments, op_replied: false, post_title: post.title, post_body: post.selftext,});if (quickScore.total < scoreThreshold - 20) continue;const { opReplied, topComments } = await fetchPostComments( sub.subreddit_name, post.id,);Excerpt — trimmed for reading, not a full file.