Back to Explore
GuideVibeFix 编辑部Updated Oct 10, 2026

Don't Let Your Referral Link Collect Dust: Referral Programs and Invite-Code Growth for Vibe Projects

You shipped invite links in a weekend. A month later: 200 invites sent, 3 signups back, 2 from your own alt accounts. A referral program isn't 'adding a link' — it's an economic system. From the R < CAC x L unit-economics formula: one-sided vs two-sided rewards, pricing four reward types (cash, discount, credits, feature unlocks), runnable Next.js attribution and anti-fraud code, 5 fraud-detection moves, a three-stage launch cadence, K-factor metrics, and failure-mode postmortems.

Cover for the guide to referral programs and invite-code growth for vibe projects: referral link viral spread illustration

Your vibe project just launched. You posted on V2EX, tagged a few big accounts on X, and squeezed into the Product Hunt buzz. Three days, 400 signups — you stared at the dashboard numbers grinning all night. Then traffic flatlined, the signup curve turned into a straight line, and customer support (that's you) had nothing to do.

You have no budget for paid ads, and SEO takes three months. Then someone says: "Build a referral program, let users bring you users." You spend a weekend adding referral links and invite codes. A month later you check the data: 200+ invites sent, 3 signups came back, and 2 of them were your own alt accounts. The referral link lies asleep in the user dashboard, gathering dust.

The idea of referrals isn't the problem. Dropbox went from 100K to 4M users in 15 months on a referral program — the thing works. The problem is that a referral program isn't "adding an invite link," it's an economic system: reward pricing, fraud prevention, attribution plumbing, growth metrics — miss one link and it doesn't turn. The good news: the actual code is small enough for a weekend. The hard part is everything you need to think through before writing it. That's what this guide covers — the full playbook a solo team can follow directly, from unit economics to launch cadence.

1. Do the math first: when a referral program is worth it

Cold water first: referral acquisition isn't free. Every reward you hand out is a cost, and whatever the fraudsters siphon off is pure loss. So before the first line of code, do one calculation and answer one question: is a user acquired through referrals cheaper than one from your other channels?

The formula is one line:

R < CAC × L

R: average reward cost per acquired user. Note "cost," not "face value" — if you issue 100 rewards and only 40 get claimed, cost is computed on actual redemption.
CAC: your cost per acquisition on your cheapest current channel.
L: the conversion-rate lift of referred users versus ordinary channels. Referrals arrive with built-in trust, so conversion is typically 2–5× higher.

A concrete example. Say you built an AI portrait app, and paid social costs you $4 per signup (CAC). Referred users convert to paid at 3× the rate of ad-driven users (L=3), so any R under $12 is a win. Now compute R: your reward is "50 generation credits for both referrer and referee," and 50 credits cost you about $0.25 in inference. 100 shares bring 20 signups, 8 of whom finish onboarding and trigger the reward — total reward cost 8 × $0.50 = $4, so R = $4 ÷ 20 = $0.20. $0.20 versus $12 — that's the point of referrals for indie developers: your acquisition cost can be an order of magnitude lower than a big company's, because you can pay rewards in things with near-zero marginal cost (credits, features).

Conversely, two cases where you should skip it. One: you already have near-free traffic — say you're a KOL and one post brings 500 signups at zero marginal cost; building a referral system is then a waste of time. Two: your product is low-frequency and users forget you exist twice a year; no L multiplier can save that. The formula's real value is in the "don't do it" decisions, which are worth more than the "do it" ones.

One-sided or two-sided? Check the table first

Who gets rewarded is the first fork in the road. One-sided rewards only the referrer; two-sided rewards both sides:

One-sided (referrer only)Two-sided (both sides)
CostLow — one rewardHigh — roughly two rewards
Referee conversionLow — they open the link, see nothing in it for them, and leaveHigh — "sign up and get something" closes the deal
Referrer motivationStrong (keeps it all)Medium (the benefit is split)
FitsUsers who are natural evangelists — dev tools where sharing signals tasteThe default choice, especially on a tight budget
ExamplesSome SaaS referral cashback schemesDropbox (storage for both), Airbnb (credit for both)

My call is blunt: solo developers should default to two-sided. The reasoning is counterintuitive: two-sided looks expensive, but you can fund it with zero-marginal-cost rewards (credits, feature unlocks); one-sided programs usually have to motivate referrers with cash — the most expensive of the four reward types, and the biggest fraud magnet. The only exception to one-sided is when your users are born evangelists: dev tools and AI gadgets where sharing says "I have good taste" — there, users want social currency and the reward is just a garnish.

2. Reward design: four types, don't pick the wrong one

A reward isn't "some perk." The wrong perk equals no perk. Each of the four types has its own destiny:

TypeFitsUpsideThe catch
Cash / cashbackHigh-ticket, high-consideration productsThe most direct incentive, everyone gets itBiggest fraud magnet; payout rails and taxes cost money
DiscountSubscription SaaSLow marginal cost, controllable amountsMeaningless to free users — they weren't paying anyway
CreditsAI apps, usage-based API productsNear-zero marginal cost — the top pick for vibe projectsOver-issue and credits inflate; users hoard them unused
Feature unlockTool-type productsZero cost, and users taste paid features (which converts)The unlocked thing must be genuinely valuable — a useless feature is no reward

Linger on the "credits" row. For AI apps built with vibe coding, credit rewards are a match made in heaven: your cost is the wholesale inference API price, the user's perception is the retail price, and the spread is your margin. Give 100 credits the user values at $3 while it costs you $0.45. That "perceived value far above actual cost" is the only price war an indie developer can afford to fight.

How much to give? Remember 20–40%

The pricing rule in one sentence: reward face value ≈ 20–40% of first-order profit. Note "first-order profit," not order value — you fund rewards with money you've already earned, not money you hope to earn.

Back to the AI portrait example: first order $6.90, inference plus payment fees ≈ $2.10, first-order profit ≈ $4.80. Reward face value lands between $0.96 and $1.92. "50 credits each side" at $3 face value? Over budget. Change it to "30 credits each side" (≈$1.70 face value, under $0.60 actual cost) — right in the band.

Two more field notes. First, start small, scale up later. Raising rewards is easy — announce "double rewards this week" and users cheer; cutting rewards gets you publicly shamed. Start at the 20% end, raise once it's working. Second, cash has no "perception premium" — a dollar is a dollar; credits and features do, users systematically overvalue them. So keep cash rewards near the bottom of the band, and credit/feature rewards can ride the top.

3. Shipping the code: invite links, attribution, redemption

The code for a referral program is genuinely small — three jobs: issuing codes, attribution, paying out. Below is a Next.js App Router implementation with complete, runnable logic.

1. Code generation: never use auto-increment IDs

Never use database auto-increment IDs as invite codes — they can be enumerated. And skip UUIDs: long and unpronounceable. Eight base32 characters (dropping confusables like 0/O and 1/I/L) survive even being read aloud to a friend:

// lib/referral.ts
import { randomBytes } from 'crypto';

// Confusables (0/O, 1/I/L) removed — safe to read aloud
const ALPHABET = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';

export function generateReferralCode(length = 8): string {
  const bytes = randomBytes(length);
  let code = '';
  for (const b of bytes) {
    code += ALPHABET[b % ALPHABET.length];
  }
  return code;
}

// Create an invite code: re-roll on unique-key collision,
// throw after 5 collisions
export async function createReferralCode(ownerId: string) {
  for (let i = 0; i < 5; i++) {
    const code = generateReferralCode();
    try {
      return await prisma.referralCode.create({
        data: { code, ownerId },
      });
    } catch (e: any) {
      if (e?.code !== 'P2002') throw e; // rethrow non-unique violations
    }
  }
  throw new Error('referral code collision, please retry');
}

Eight base32 characters give trillions of combinations — collision probability is negligible, and the unique key re-roll covers the rest. The invite link is yoursite.com/r/ABCDEFGH: short, memorable, poster-friendly.

2. The /r/[code] route: attribute on landing

The first thing that must happen when someone opens an invite link isn't "render a page" — it's "record the attribution." Do it server-side, never trust frontend JS for this:

// app/r/[code]/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(
  req: NextRequest,
  { params }: { params: { code: string } }
) {
  const code = params.code.toUpperCase().trim();
  const record = await prisma.referralCode.findUnique({
    where: { code },
  });

  const res = NextResponse.redirect(new URL('/signup', req.url));

  // Only write the attribution cookie for valid codes;
  // invalid codes still land on signup, no error
  if (record && !record.revoked) {
    res.cookies.set('referred_by', record.code, {
      maxAge: 60 * 60 * 24 * 30, // 30-day attribution window
      path: '/',
      httpOnly: true, // invisible to frontend JS, tamper-resistant
      sameSite: 'lax',
      secure: process.env.NODE_ENV === 'production',
    });
  }
  return res;
}

Three details. First, attribution lives in an httpOnly cookie — frontend JS can't read it, so it can't be tampered with. Second, a 30-day attribution window — someone clicks today and signs up three weeks later, the referrer still gets credit; too short a window chills referrer enthusiasm. Third, invalid codes never error out — they still land on signup. Invite links get forwarded around social media; a 404 on an expired code kills the whole chain.

One extra insurance policy: landing-page JS reads the ?ref= URL param and writes a localStorage backup. Safari's ITP occasionally eats cookies in these flows — belt and suspenders, no lost attribution.

3. Binding at signup: attribution counts exactly once

Bind attribution at the moment signup succeeds. Trust the cookie, not URL params (params get lost across redirects and intermediary pages):

// app/api/auth/signup/route.ts (excerpt; doSignup is your existing signup logic)
import { createHash } from 'crypto';

const hashIp = (ip: string) =>
  createHash('sha256').update(ip + (process.env.IP_SALT || '')).digest('hex');

export async function POST(req: NextRequest) {
  const user = await doSignup(req); // your existing signup flow first
  const res = NextResponse.json({ ok: true });

  const referredBy = req.cookies.get('referred_by')?.value;
  if (referredBy) {
    const code = await prisma.referralCode.findUnique({
      where: { code: referredBy },
    });
    // Three checks: code exists, not revoked, not self-referral
    if (code && !code.revoked && code.ownerId !== user.id) {
      try {
        await prisma.referral.create({
          data: {
            codeId: code.id,
            referrerId: code.ownerId,
            refereeId: user.id, // @unique: one user can be referred only once
            ipHash: hashIp(getIp(req)),
            deviceFingerprint: req.headers.get('x-device-id'),
          },
        });
      } catch (e: any) {
        if (e?.code !== 'P2002') throw e; // user already has attribution, ignore
      }
    }
    res.cookies.delete('referred_by'); // attribution is single-use
  }
  return res;
}

Note the @unique on refereeId: each user can only be referred once. Without it, a fraudster registers one account with 10 invite codes and collects 10 rewards. The cookie is deleted after use — no "swap codes and re-attribute" games.

4. The reward state machine: never pay out at signup

The classic rookie mistake: paying the reward the moment someone signs up. Then you discover bot registrations outnumber real users. The trigger must be the referee completing the aha moment — generating their first piece of work, connecting a data source, sending their first invite, whatever it is for your product. Signup is "I showed up"; the aha moment is "I'm staying." The state machine:

// schema.prisma (excerpt)
model ReferralCode {
  id         String     @id @default(cuid())
  code       String     @unique
  ownerId    String
  revoked    Boolean    @default(false)
  maxRewards Int        @default(50) // per-code reward cap — the circuit breaker
  createdAt  DateTime   @default(now())
  referrals  Referral[]
}

model Referral {
  id                String         @id @default(cuid())
  codeId            String
  referrerId        String // the referrer
  refereeId         String         @unique // the referee — referred only once
  status            ReferralStatus @default(PENDING)
  ipHash            String?
  deviceFingerprint String?
  riskFlags         String[]       @default([])
  qualifiedAt       DateTime?
  createdAt         DateTime       @default(now())
}

enum ReferralStatus {
  PENDING   // attributed, waiting on the referee's aha moment
  QUALIFIED // reward conditions met, pending review/auto-approval
  APPROVED  // review passed, awaiting payout
  PAID      // paid out
  REJECTED  // fraud or invalid, reason in riskFlags
}
// Payout: call only after the aha moment, never at signup
export async function qualifyReferral(referralId: string) {
  const referral = await prisma.referral.update({
    where: { id: referralId, status: 'PENDING' },
    data: { status: 'QUALIFIED', qualifiedAt: new Date() },
  });

  const flags = await fraudChecks(referral);
  if (flags.length === 0) {
    await grantReward(referral); // clean record: auto-approve and pay
  } else {
    await prisma.referral.update({
      where: { id: referralId },
      data: { riskFlags: flags }, // flagged: into the manual review queue
    });
  }
}

// Fraud checks: returns an array of risk flags, empty means clean
async function fraudChecks(r: Referral): Promise<string[]> {
  const flags: string[] = [];
  const referee = await prisma.user.findUnique({
    where: { id: r.refereeId },
    select: { email: true },
  });
  const [sameIp, sameDevice, referrerCount] = await Promise.all([
    prisma.referral.count({
      where: { ipHash: r.ipHash, status: { not: 'REJECTED' } },
    }),
    prisma.referral.count({
      where: { deviceFingerprint: r.deviceFingerprint, status: { not: 'REJECTED' } },
    }),
    prisma.referral.count({
      where: { referrerId: r.referrerId, status: { not: 'REJECTED' } },
    }),
  ]);
  if (sameIp >= 3) flags.push('same_ip_3_plus');
  if (sameDevice >= 2) flags.push('same_device_2_plus');
  if (referrerCount >= 20) flags.push('referrer_over_cap'); // monthly cap review
  if (referee?.email && isDisposableEmail(referee.email)) flags.push('disposable_email');
  return flags;
}

async function grantReward(r: Referral) {
  await prisma.$transaction([
    // Two-sided payout: referrer and referee credited together
    prisma.creditLedger.create({
      data: { userId: r.referrerId, amount: 100, reason: 'referral:' + r.id },
    }),
    prisma.creditLedger.create({
      data: { userId: r.refereeId, amount: 50, reason: 'referred:' + r.id },
    }),
    prisma.referral.update({
      where: { id: r.id },
      data: { status: 'PAID' },
    }),
  ]);
  // Notifications always go OUTSIDE the transaction: a failed push must not
  // roll back an already-credited reward — a user told "reward received"
  // who then finds nothing destroys more trust than no reward at all
  await notifyReward(r.referrerId, r.refereeId);
}

Read the order in grantReward: both sides' credits and the status change commit in one transaction first, then push/email goes out. Notifications always stay outside the transaction — a notification failure must never roll back a credited reward, or users get a "reward received" ping, open the app, find nothing, and trust dies harder than if you'd never paid at all.

Referral attribution pipeline diagram: the full path from shared invite link to reward payoutFigure 1: The attribution pipeline — /r/[code] writes the cookie on landing, signup binds the referrer, and the reward fires after the aha moment.

4. Fraud prevention: 5 moves against bonus hunters

One brutal truth first: any referral program with cash or high-value rewards will be discovered by bonus hunters within 48 hours of launch. Not "if" — "when." Fraud prevention isn't a patch you ship later; it's designed alongside the rewards, on day one. Five moves, ordered by impact:

  1. Block self-referrals.ownerId !== refereeId is just the start. Real self-referral detection treats matching device fingerprints, IPs, and payment card numbers as self-referral too. Record all three at signup (see the schema in section 3) — the comparison is O(1), don't skip it.
  2. Delay payouts.T+7 minimum; for subscriptions, wait out the refund window. Bonus hunters' time has a cost too — a reward that takes 14 days to arrive holds no appeal for them, while real users just see "arriving in a few days." The highest-ROI anti-fraud move there is.
  3. Gate on behavior. Only "valid referrals" earn rewards, and valid means the referee completed the aha moment. Spinning up 100 fake registrations is easy; faking 100 genuine usage sessions is hard. Set the bar where hunters find it not worth it and real users cross it naturally.
  4. Cap everything. Monthly reward cap per user, redemption cap per code (maxRewards in the schema exists for exactly this). Caps aren't stinginess — they're circuit breakers. Even if every defense above gets bypassed, losses have a ceiling.
  5. Watch the patterns. Spend 10 minutes a week on three numbers: a single code converting above 60% (normal is 5–20%), 10+ signups clustered within 5 minutes, a sudden spike in disposable-email domains. Any one of them: freeze that code's payouts first, investigate second.

The review queue: three lanes, don't hand-review everything

A one-person team has no risk department, so review must be triaged automatically. The riskFlags array returned by fraudChecks is the triage key:

  • Auto-approve: no flags, referee behavior looks real. 90%+ of volume — don't waste human time here.
  • Manual review: 1–2 low-risk flags. Batch them, spend 10 minutes a day working down the risk-score-sorted list; one glance at the behavior timeline is usually enough to judge.
  • Auto-reject: confirmed self-referral (duplicate device fingerprint + IP), obvious farm patterns. Rejections need documented reasons so appeals have something to stand on — false-positiving a real user costs more than letting a hunter through. The former loses trust; the latter only loses money.

One principle to remember: the goal of fraud control isn't zero fraud, it's making fraud cost more than it pays. Chasing zero fraud blocks real users too, and that's a worse trade.

5. Launch cadence: three stages, never go full-traffic on day one

Every referral bug is a money bug — overpaid rewards are real cash you can't claw back. So the launch cadence has exactly one iron rule: use small traffic as your firewall.

StageDurationWhat to doGate metrics (all required)
Internal test1 weekGet 20 friends to run the full pipeline100% attribution accuracy: every referral record matches a real person and a real story; payouts exact to the cent
Small traffic2 weeksOpen the invite entry to 5–10% of usersK-factor measurable and above 0.3; fraud rate under 5%; fewer than 5 related support tickets per week
Full rolloutOngoingOpen it up, start watching growth metrics weeklyK-factor trending up; per-user reward cost within budget

Each stage answers exactly one question: internal test answers "does the pipeline work," small traffic answers "is it worth it and can we defend it," and only full rollout answers "how big can it go." The worst case I've seen from skipping small traffic: the reward trigger was misconfigured to "signup," 20K credits got farmed in 3 days, and the program was killed overnight — all of it discoverable in a week at 5% traffic.

The K-factor > 0.3 bar is a rule of thumb. Below 0.3 the referral loop basically doesn't turn; going full-traffic just amplifies "nobody shares" by 20×. Go back and work the 4 levers in section 6 first — don't rush the rollout.

6. Growth metrics: watch K-factor and the funnel

A referral program has exactly one core metric: K-factor = average invites sent per user × invite conversion rate, K = i × c. K > 1 compounds; K < 1 decays every round — that's math, not effort.

Watch it work: 100 seed users, each sends 2 invites on average (i=2), each invite brings 0.3 new users (c=0.3), K=0.6. Round one brings 60 people, round two 36, round three 22… total converges at 250 and stops, not one more. To break the ceiling there's exactly one path: get K above 1.

The second metric is viral cycle time: how long from A sending an invite until the invited B sends their first invite. K decides "how much each round multiplies," cycle time decides "how fast a round is." Designs like two-sided "instant credit + push notification" optimize the cycle — getting B to share at peak enthusiasm, the moment the reward lands.

Third is the invite conversion funnel — instrument every layer:

  1. Users who see the invite entry
  2. Share click-through rate
  3. Friends who open the link (open rate)
  4. Opens that convert to signup (signup conversion)
  5. Signups that complete the aha moment (valid conversion)

K-factor is the outcome; the funnel tells you which layer is leaking. Always read the funnel first when optimizing: low share rate and low signup conversion are completely different diseases — don't prescribe the same medicine.

Invite conversion funnel diagram: five layers from seeing the invite entry to completing the aha momentFigure 2: The invite conversion funnel — K-factor is the outcome, the funnel tells you which layer to fix.

4 levers when K-factor < 1 (ordered by ROI)

  1. Move the invite entry to after the aha moment. Share rate at the moment a user just made their first creation — peak sense of accomplishment — runs 3–5× the baseline. Popping "invite friends for rewards" before they understand the product is like discussing wedding budgets on a first date.
  2. Give referrers ready-made ammunition. Write three share copy variants (one-liner, social-post, tech-group versions) and generate a personalized poster with their name on it. Users often don't share not because they won't, but because they don't know what to say — write it for them and sharing becomes one click.
  3. Personalize the referee landing page. After "/r/ABCDEFGH" lands, the page should read "Your friend Lao Wang invited you — sign up for 30 free credits," not a generic "Welcome, sign up." Named landing pages convert meaningfully better than generic ones — trust is the only currency a referral program has, don't waste it.
  4. Make rewards visible and tangible. Progress bars ("1 more invite to unlock Pro"), instant credit notifications, leaderboards. Delayed gratification kills the urge to share — people can't resist being "one step away," a piece of human nature the games industry has validated for 20 years.

7. Failure modes: rewards went out, nobody shared

The most common way referral programs die: the system works, rewards go out, nobody shares. Three causes — find yours:

  1. The reward is meaningless. You gave users something they don't want. A "20% off renewal" coupon for free-tier SaaS users is nothing — they weren't paying anyway. Fix: tie rewards to core value. Credits for AI apps, features for tools, status for communities. The test: would a user pay money for the reward on its own? If not, change it.
  2. The chain is too long. More than 3 steps from "I want to share" to "I got my reward," and every extra step halves conversion. Fix: one-click poster generation on the share button, automatic payout, one push on arrival. Turn "go claim your reward" into "the reward grows legs and comes to you."
  3. No social currency. Does sharing your product make users look good or bad? AI gadgets and productivity tools look good; expense trackers and group-buy coupons don't. Fix: attach identity to sharing — "founding tester" badges, invite leaderboards, exclusive skins. What gets shared is never the reward itself — it's the superiority of "I got here before you."

Three product types that should skip referral programs

Save the weekend for something else. Some products are structurally unfit — forcing it just burns time:

  1. Privacy-sensitive. Expense trackers, health, mental wellness, dating-adjacent — users don't want friends knowing they use these. Your invite link will never get tapped.
  2. Low-frequency tools. The tax-filing tool used twice a year — by the time users think of sharing you, they've forgotten your name. Referrals need high-frequency contact plus instant share impulse; low-frequency products have neither.
  3. Supply-constrained. Limited-seat betas, consulting or services delivered by you personally — you can't serve the people who get referred, which means paying for bad reviews and burning the referrer's trust.

One-line test: would your users publicly post "I'm using this" on their social feed? If not, skip the referral program and spend the time on a different growth lever.

8. Final pre-launch checklist

  • Attribution pipeline: /r/[code] → cookie → signup binding, tested end-to-end by 3 real humans
  • Reward trigger: fires on the aha moment, not on signup
  • State machine: PENDING / QUALIFIED / APPROVED / PAID / REJECTED all in place, rejections documented
  • Fraud defenses: at least 4 of the 5 moves shipped; delayed payout + behavior gating are the floor
  • Pricing: reward face value inside 20–40% of first-order profit
  • Entry placement: invite entry sits after the aha moment, not in onboarding
  • Instrumentation: every funnel layer tracked, K-factor reviewed weekly
  • Circuit breakers: monthly per-user reward cap, per-code redemption cap

One last thing — no seed users for a cold start? One sentence: a waitlist plus "invite 3 friends to jump 1,000 spots" referral-accelerated queueing is the classic cold-start combo — queue mechanics are their own design problem (ranking algorithms, a whole new fraud surface) and out of scope here. But remember: referral programs need a first batch of seeds, and the queue is how you buy them.

A referral program's essence is moving your acquisition budget from "paying platforms" to "paying users." Platforms take $4 a click; users take $0.20 a genuine recommendation — with a trust endorsement attached. A one-person team can't win an ad war, but it can win a trust war. Don't let your referral link lie there asleep — it may be the cheapest growth lever you own.

If you can do exactly one thing this week: run the R < CAC × L calculation. If the math says yes, next week ship the /r/[code] route and the attribution cookie — the code takes half a day, thinking it through takes a week. Don't get the order backwards.

Browse projectsPublish your project

Related articles

Waitlist conversion funnel illustration: signup, confirmation, warm-up, activation
Guide
Waitlist Playbook: How to Bank Your First Users in the 30 Days Before Launch

A waitlist is not a wishing well — it's a conversion funnel. This guide covers the four waitlist models and a decision table, a one-day Next.js + Supabase implementation (signup API, double opt-in, queue ranking, referral scoring), a week-by-week 30-day operating rhythm, anti-fraud tactics, five launch-day moves, metric thresholds for validation, and how to fix the classic failure of a long queue with nobody showing up.

Growth & MarketingStartup JourneyNext.js
A rocket lifting off at dawn, symbolizing a product launch day
Guide
Dead on Launch? A Cold-Start Combat Manual for Vibe Project Launch Day

Most vibe projects don't die from being bad — they die from nobody knowing they launched. This combat manual covers the 14-point pre-launch checklist, a 24-hour T-day timeline with five action nodes, copy templates for Product Hunt / Show HN / X / Xiaohongshu, the warm-up arsenal (waitlist, build in public, KOL test list), comment-section combat scripts, a three-level traffic plan with Vercel/Cloudflare setups, and the five funnel numbers that decide whether to keep going.

Product LaunchGrowth & MarketingIndie Development
A new user's first screen in a vibe project — the empty state and signup flow decide whether they stay or close the tab
Guide
First-Minute Aha: User Onboarding Design for Vibe Projects

Vibe projects rarely die from missing features — they die in the first minute after signup. This field guide argues onboarding's job isn't to teach the product but to deliver the promised value fast: a Value Promise Canvas to find your Aha moment, a decision table for three onboarding patterns, 7 signup fields to cut, empty-state copy templates, a paste-ready 3-step React tour component on localStorage, 4 funnel metrics with event naming, and a 10-item pre-launch audit.

Design ExperienceProject BuildingIndie Development