HYB · Hatch Your Beta · v12.0

Turn your product launch into an actionable battle map

HYB is a local-first, multi-project product launch and growth distribution console built for indie hackers and SaaS founders. Manage launch materials across projects, track 500+ acquisition channels, and use OKRs to record every cold-start distribution — all data stays in your browser.

🔒 No login · no server upload 📦 500+ preloaded channels 📊 Project × channel matrix 🎯 Periodic OKR + coaching 🌐 Bilingual UI 💾 JSON import / export

1. Product overview

1.1 One-sentence positioning

HYB (Hatch Your Beta) is a local-first, multi-project product launch and growth distribution console for indie hackers and SaaS founders. It helps you manage launch materials, track 500+ acquisition channels, and record cold-start and live-URL distribution progress — with all data stored only in your browser's localStorage, never uploaded to a server.

1.2 What problem it solves

In the cold-start phase, the most draining work isn't writing code — it's tracking where to post, how far along each channel is, and where to resume next. HYB decomposes this into three quantifiable objects:

ObjectEntity in codeDescription
Platformplatforms[]Each channel has name / url / category / free / dr / custom
Projectprojects[]Each project has name / url / tagline / desc / collapsed — a copy-ready set of launch materials
Progressprogress[projectId][platformId]Each project × channel combination records status / followUp / notes / links[] independently

The three intersect into a "channel × project" matrix — the core data model of HYB. The "Launched" and "Featured" counts in the overview are counted by this matrix, not by channel.

1.3 Who it's for

2. Core features (mapped to the code)

① Multi-project launch materials

  • Each project maintains four fields independently: product name, website, tagline, and description.
  • "Copy all" copies in a four-block format — [Product Name] / [Website] / [Tagline] / [Description] — to the clipboard in one click.
  • Individual fields can also be copied on their own (each field has a copy button).
  • Project cards can be collapsed/expanded; the collapsed state is written to the collapsed field and persisted.

② 500+ acquisition channels

  • The built-in REAL_PLATFORMS array covers 9 categories: AI tool directories, SaaS software reviews, launch & startup, developer tools, social & content, community promotion, business & PR, search engines, and other channels.
  • Includes 17 Reddit subreddits (r/SideProject, r/indiehackers, r/SaaS, r/startups, etc.) and 7 search engine webmaster platforms (Google Search Console, Bing Webmaster Tools, Yandex Webmaster, Baidu Search Resource Platform, Naver Search Advisor, Seznam, IndexNow).
  • "Add channel" form: name (required), URL, category, fee (Free/Paid/Unknown), DR (0–100, optional).
  • Duplicate detection on add: same name or same host triggers a confirmation dialog.

③ Domain Rating (DR) system

  • The built-in PRELOADED_DR dictionary preloads DR values for hundreds of domains (e.g., producthunt.com 91, github.com 97, linkedin.com 99).
  • DR is not a filter — it's a sort: ascending (low → high) or descending (high → low), with null always last.
  • Click any DR value in the table to edit inline: Enter to save, Esc to cancel, with a toast confirmation.

④ Progress tracking (project × channel)

  • Four statuses: pending (Pending), submitted (Launched), approved (Featured), rejected (Rejected).
  • Follow-up date: when unfinished and earlier than today, the row shows an overdue marker on the left.
  • Notes: inline input, auto-saved on blur.
  • Live URLs (links): each project × channel can hold multiple URLs, each with url / title / date; the expandable panel supports add/edit/remove, and the date is used for goal counting.

⑤ OKR / goal system

  • Per-project goals with a selectable period: this week / this month / this quarter / this year.
  • The unit is "distribution points"; the calculation counts, for the current period, all live-URL entries whose date falls within the period.
  • Switching period auto-fills defaults: week=20, month=100, quarter=300, year=1000.
  • Progress bar + percentage + "N days left".
  • Coaching hints adapt to five conditions: no target set, 100% reached, ≤2 days left and <80%, time progress > completion +20%, completion ahead, and steady.

⑥ Filtering & search

  • Search matches channel name, URL, and category label (case-insensitive, 140 ms debounce).
  • Project filter: all / a specific project. When a specific project is selected, only its rows are shown.
  • Category filter, status filter, fee filter (Free/Paid/Unknown).
  • The status filter applies to project rows: when all project rows under a channel are filtered out, the channel is hidden.
  • "Reset filters" clears everything in one click.

⑦ Import / export / reset

  • Export: a JSON file with a full snapshot of app / version / exportedAt / lang / platforms / projects / progress / okr, filename hyb-console-backup-YYYY-MM-DD.json.
  • Import: supports HYB's own full format and the older flat-array (legacy) format; a confirmation dialog before import explicitly warns that current data will be overwritten.
  • Reset: restores the default channel library + default project (ffee.me sample) + default OKR (month / 100).

⑧ Bilingual UI

  • A complete i18n dictionary (I18N.zh / I18N.en). Switching language re-renders page copy, filter dropdowns, the table, and the overview, and persists to hyb_v12_lang.
  • Category labels are also mapped bilingually (e.g., "AI工具目录" ↔ "AI Directories").

⑨ Local-first & privacy

  • All persistence goes through localStorage with the hyb_v12_ key prefix.
  • No login, no backend, no account system; the footer explicitly states "No login · no server upload".
  • The only external requests are the Microsoft Clarity analytics script (clarity.ms) and the logo image; business data itself never leaves the browser.
  • Storage write failures (e.g., quota exceeded) are caught and surfaced as "local storage is full — could not save".

3. How it compares to common alternatives

DimensionHYBSpreadsheets (Excel / Notion)Built-in platform dashboards
Channel library✅ 500+ preloaded channels + DR❌ Build it yourself❌ Only their own channels
Multiple projects✅ Native project × channel matrix⚠️ Requires manual design❌ Usually single product
Material copy✅ Four-block one-click copy❌ Manual stitching❌ Not available
Goal tracking✅ Auto-counted by period and live-URL date⚠️ Manual formulas❌ Not available
Data location✅ Browser local❌ Cloud❌ Platform cloud
Login✅ Not required❌ Required❌ Required

4. FAQ

Every number and behavior below can be verified against the source code.

Q1: Do I need an account? Where is my data stored?

No account is required — there is no account system at all. All data (channels, project materials, progress, notes, live URLs, OKRs) is stored in your browser's localStorage, with keys prefixed hyb_v12_. Switching browsers, switching devices, or clearing browser data will make your data disappear. Use the Export feature to back up.

Q2: How many channels are in the channel library?

The built-in REAL_PLATFORMS array is organized into 9 categories, including Product Hunt, Hacker News, GitHub, G2, Capterra, AlternativeTo, Indie Hackers, BetaList, AppSumo, Chrome Web Store, Google Search Console, Bing Webmaster Tools, Baidu Search Resource Platform, Naver Search Advisor, and 17 Reddit subreddits. There is also a mergeCatalog mechanism: when the local channel count is ≥300 and the catalog version is below CATALOG_VERSION (currently 3), newly added channels are merged in on upgrade.

Q3: What is DR? Is the data accurate? Does it update?

DR stands for Domain Rating (0–100). HYB preloads values for hundreds of domains in PRELOADED_DR — these are static preset values and do not update automatically. DR is not a filter but a sort (ascending/descending, with null always last). You can click any DR value in the table to edit it manually; changes are persisted.

Q4: Why does a channel disappear when I filter by "Featured"?

Because the status filter applies to project rows: when all project rows under a channel are filtered out, the entire channel is hidden. To see only one project's featured status, set the Project filter to that specific project first, then choose the status.

Q5: How are "distribution points" in the OKR calculated?

The calculation counts, for the current project and current period, all entries in each channel's links array whose date falls within the period's start and end dates. Only live URLs with a date count toward the goal. Newly added live URLs default to today's date. Switching period (week/month/quarter/year) auto-fills default targets of 20/100/300/1000, which you can change manually.

Q6: What does the left-side bar / red follow-up date mean?

When a project × channel follow-up date is earlier than today and the status is neither "Featured" nor "Rejected", the row is marked overdue (row-overdue) with a 2px black inset on the left. It reminds you that follow-up is due but not yet closed.

Q7: Can I manage multiple products at once?

Yes. Each project has its own four-field materials, its own progress matrix, and its own OKR. The overview's per-project breakdown lists each project's live URLs, launched count, and featured count separately. Deleting a project also deletes its progress, notes, live URLs, and OKR (with a confirmation dialog).

Q8: Does import overwrite my existing data?

Yes. A confirmation dialog appears before import, explicitly stating that importing will overwrite all current channels, project materials, distribution progress, and goal settings. Import supports two formats: the full JSON exported by HYB (with platforms/projects/progress/okr), and the older flat array format (migrated as legacy into the first project).

Q9: What should I do when adding a channel triggers a "same name or host already exists" warning?

This is duplicate protection. It is based on platformUrlKey (host, with path preserved for some hosts) and platformNameKey (normalized name comparison, including alias mappings such as twitter→x and blogspotcom→bloggercom). If you really want to add it, click "Confirm" in the dialog to continue; it will be added as a custom channel (custom: true).

Q10: Is my data uploaded to a server?

Business data is not uploaded. The only external scripts on the page are Microsoft Clarity (clarity.ms) for visit analytics and the hyb.vip/logo.svg image. Your channels, projects, progress, notes, and live URLs are written only to localStorage. If a write fails (e.g., private mode or full storage), you'll see a "local storage is full — could not save" message.

Q11: Which browsers are supported?

The code uses modern APIs including localStorage, navigator.clipboard (falling back to execCommand('copy') in non-secure contexts), Intl.DateTimeFormat, URL, and Array.from(...normalize('NFKC')). The structured data declares browserRequirements: Requires JavaScript. Data is stored in localStorage. and operatingSystem: Any. Recent versions of Chrome, Edge, Firefox, and Safari are recommended.

Q12: Can I switch the UI language? Does it affect my data?

Yes — the language switcher in the top-right supports English and Simplified Chinese. Switching only changes UI copy (including bilingual category labels) and does not affect data. The language choice is persisted in hyb_v12_lang. The default language is English (the code sets lang = storedLang === 'zh' ? 'zh' : 'en').

Q13: How do I back up, and how often should I?

Click "Export" in the top-right to download hyb-console-backup-YYYY-MM-DD.json, containing a full snapshot of platforms, projects, progress, and okr. It is recommended to export after every significant change (bulk channel additions, bulk status updates) and keep multiple dated versions. To restore, import the same file.

Q14: Why did my data disappear after clearing browser cache?

Because data lives in localStorage — clearing cache/site data clears it too. That is the cost of local-first, and also the cost of privacy. Make a habit of exporting backups.

Q15: Is HYB free?

The structured data declares isAccessibleForFree: true with offers of price: 0, priceCurrency: USD. The current version (v12.0) is free to use with no login and no paywall.

5. How it works

Told in data-flow order. All function names and key names are from the source code.

5.1 Data model (three layers)

projects[]                    each project: id, name, url, tagline, desc, collapsed
platforms[]                   each channel: id, name, url, category, free, dr, custom
progress[projectId][platId]   each combination: status, followUp, notes, links[{url,title,date}]
okrMap[projectId]             each project: cycle(week|month|quarter|year), target

Relationship: progress is a sparse matrix of projects × platforms; only combinations that have been operated on have entries. On read, getProgress(pid, platId) auto-creates an empty record if missing (emptyProgress() returns status: 'pending').

5.2 Boot flow (init())

  1. loadState(): decides between migration and direct read based on the version number.
    • If hyb_v12_version < 12 or there is no v12 platforms, it first tries migrateFromV10() (migrating from ffee_console_v10_*).
    • Reads hyb_v12_platforms; if missing, reads the legacy ffee_promo_data_final_v2; if still missing, uses defaultPlatforms() (i.e., REAL_PLATFORMS + PRELOADED_DR).
    • When the catalog version is below CATALOG_VERSION (3) and the channel count is ≥300, mergeCatalog() merges new channels and records catalogAdded.
    • Reads projects / progress / okr / lang / ui / savedAt, cleans each via normalize*, and ensures unique ids via dedupeIds.
  2. bindEvents(): wires up all buttons, filters, table event delegation, keyboard Esc, page visibility, and pagehide/beforeunload saves.
  3. applyI18n() + startClock() (refreshes the top date/time every second).
  4. buildFilterOptions() → renderProjects() → updateMaterialsUi() → renderTable() → renderOverview().
  5. If needsCatalogPersist or needsCopyRefresh is set, one extra persistence pass is made.

5.3 Render flow

5.4 Interaction & saving

5.5 Import / export / reset

5.6 Migration & compatibility

5.7 Privacy & boundaries

6. Step-by-step tutorial

6.1 First launch

  1. Open the HYB console in your browser. The current date, weekday, and time are displayed at the top (refreshed every second).
  2. Switch between English / Simplified Chinese in the top-right. Switching only changes UI copy, not data.
  3. The page has four blocks: Overview (stats + goal), Launch Materials, Growth Channels, and the footer (reset entry).

6.2 Create your first project

  1. In the Launch Materials section, click Add project. An empty card is generated, scrolled into view, and the cursor lands in "Product name".
  2. Fill in the four fields:
    • Product name: e.g., ffee.me
    • Website: e.g., https://ffee.me/ (the card subtitle shows the host in real time)
    • Tagline: one sentence that says what it is
    • Description: selling points, target users, differentiation
  3. Each field has a Copy button for copying that field alone.
  4. Copy all in the card's top-right copies in a four-block format in one click:
    [Product Name] …
    [Website] …
    [Tagline] …
    [Description] …
  5. Click the chevron on the right of the card to collapse/expand; the state is persisted.
  6. To manage multiple products, repeat "Add project". Each project has independent materials, progress, and OKR.
  7. To delete a project, click the trash icon; the confirmation dialog warns that "materials, progress, notes, live URLs, and goals will all be removed".

6.3 Pick channels and record progress

  1. Scroll to "Growth Channels". Columns: Category / Channel / DR / Project / Status / Follow-up / Live URLs / Notes.
  2. Filters (the row above the table header):
    • Search box: type a channel name, URL, or category keyword (140 ms debounce).
    • Project: All projects / a specific project. When a specific project is selected, only its rows are shown.
    • Category, status, fee: combine as needed.
    • DR sort: default / ascending / descending (null always last).
    • Reset filters: clears all conditions in one click.
  3. Change status: use the inline dropdown to pick Pending / Launched / Featured / Rejected. Saved immediately.
  4. Set a follow-up date: the inline date field. If the date is earlier than today and the status is neither Featured nor Rejected, a black bar appears on the left of the row to mark overdue.
  5. Write notes: the inline notes field auto-saves on blur; its placeholder is "Click to add…".
  6. Record live URLs:
    • Click the button in the "Live URLs" column to expand the panel; the number on the button is the current live-URL count.
    • Click Add live URL to add a row: URL, title/note, date (defaults to today).
    • The date matters — OKRs count by live-URL date.
    • Each row has a trash icon to delete it.
  7. Multiple projects on the same channel: when a channel has multiple projects attached, the table shows a main row + sub-rows, each with independent status/date/notes/live URLs.

6.4 Set a goal and watch progress

  1. In the Overview's "Goal" row:
    • Choose a period: this week / this month / this quarter / this year (switching auto-fills the default target: 20/100/300/1000).
    • Enter "Achieve __ distribution points".
    • The right side shows the percentage, progress bar, "X of Y done", and "N days left".
  2. Calculation rule: only counts live-URL entries under the current project whose date falls within the current period. Live URLs without a date are not counted.
  3. Coaching hints change based on the situation:
    • Target is 0 → prompt to set a target
    • 100% reached → congratulations
    • ≤2 days left and <80% → warning to sprint
    • Time progress > completion +20% → behind schedule
    • Completion > time progress → ahead of schedule
    • Otherwise → steady

6.5 Add a custom channel

  1. Click Add channel in the top-right of the channel table.
  2. Fill in: channel name (required), URL, category, fee (Free/Paid/Unknown), DR (0–100, optional).
  3. If the same name or host already exists, a confirmation dialog appears; confirming adds it as a custom channel (shown with a small "Custom" tag in the table).
  4. Custom channels participate in filtering, sorting, and progress tracking just like preloaded ones.

6.6 Edit DR

  1. In the DR column, click any DR value (showing DR — means empty).
  2. It turns into an input; enter 0–100, Enter to save, Esc to cancel.
  3. Invalid values (non-numeric, out of range) are cleared to null.
  4. A toast confirms "DR saved: xx" or "DR cleared".

6.7 Export backup & import to restore

Export

  1. Click Export in the top-right.
  2. Downloads hyb-console-backup-YYYY-MM-DD.json, containing full platforms/projects/progress/okr data.
  3. Export after every bulk change and keep multiple copies.

Import

  1. Click Import in the top-right and select a JSON file.
  2. A confirmation dialog appears: "Importing will overwrite all current channels, project materials, distribution progress, and goal settings".
  3. Confirm to replace everything and re-render; a toast shows "Imported: X channels · Y projects".
  4. Supports the older flat-array format (migrated into the first project).

6.8 Reset data

  1. Click Reset data in the footer.
  2. The confirmation dialog warns that "all channel distribution progress, notes, live records, project materials, and goals will be restored to their initial state".
  3. Confirming restores the default channel library + default project + default OKR (month/100).

6.9 Suggested daily rhythm

7. Troubleshooting

SymptomCauseFix
Data disappeared after refreshCleared site data / switched devicesImport the exported JSON
"Local storage is full" messagelocalStorage full or private modeExport a backup, clear site data, use a normal window
Copy does nothingNon-secure context and execCommand failedSelect and copy manually, or access via https
Channel disappears after choosing a statusStatus filter applies to project rowsPick a specific project first, then the status
OKR doesn't increaseLive URL has no date or date is outside the periodAdd a date to the live URL
DR sort doesn't changeNull DR always sorts lastClick the DR value to edit it manually