惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

Rokcso's Blog

Tax Filing for Non-Resident's US LLC: Form 5472 Filing Guide 非美国居民的 US LLC 税务申报:Form 5472 填写指南 Tax Filing for Non-Resident's US LLC: Form 1120 Filing Guide 非美国居民的 US LLC 税务申报:Form 1120 填写指南 Tax Terms Explanation for US LLC: Tax Basics for Independent Developers 美国 LLC 报税名词解释:给独立开发者的税务入门 Mercury 企业账户申请全流程和审核经验分享 译> 我如何使用 Claude Code 译> 我的 AI 应用之路
Building Shipstry: 640 Commits, 9 Days, One Launch
hi@rokcso.com (rokcso) · 2026-03-13 · via Rokcso's Blog

On March 3, 2026, I started with an empty folder. On March 11, 2026, Shipstry went live.

In between: 640 commits, countless cups of coffee, and a lot of lessons learned about building on the edge.

This is the story of how I built it, the technical decisions I made, and what I learned along the way.

Shipstry.com

The Name

Before writing a single line of code, I needed a name.

I spent an entire afternoon brainstorming with AI. I must have asked for hundreds of suggestions. The AI probably hated me by the end of it.

I wanted something that captured the essence of what makers do — we ship products. And I wanted it to feel like a registry, a place where products are officially recorded and discovered.

Ship + Registry = Shipstry

It sounded nautical, it felt right, and the .com was available. Done.

The nautical theme evolved into something more organic:

  • Primary color: Olive Moss (#6B8A67)
  • Accent: Warm Sand (#D4A574)
  • Pricing tiers: Harbor, Voyage, Expedition, Admiral
  • The logo: a geometric sailboat with twin sails

The Why

After launching several side projects over the years, I kept running into the same problem: Product Hunt is great, but it’s not built for indie makers anymore.

Big-budget launches dominate. Marketing teams game the algorithm. Great products from solo developers get buried in hours.

I wanted something different:

  • A place that celebrates builders, not marketers
  • Weekly cycles instead of daily chaos
  • Quality over quantity
  • Built by a maker, for makers

So I built Shipstry — “The Launch Registry.”

The Stack Decision

Before writing code, I spent time on stack selection. This is the most important decision you make at the start of a project — it will haunt you for months if you get it wrong.

I chose:

TanStack Start for the framework. It’s a full-stack React framework with file-based routing and excellent TypeScript support. The type safety is incredible — if you change a route, the compiler tells you everywhere that needs updating.

Cloudflare Workers for deployment. Edge computing means my users in Singapore, London, and New York all get the same fast experience. No cold starts, global distribution.

Cloudflare D1 for the database. It’s SQLite at the edge. Yes, SQLite — the same database that powers your phone, now running in 300+ locations worldwide. For a product like Shipstry, it’s perfect.

Cloudflare R2 for file storage. When users upload product logos and preview images, they go here. It’s S3-compatible but with zero egress fees, which means I don’t have to worry about surprise bandwidth bills.

Better Auth for authentication. Email/password plus Google OAuth, and it integrates natively with TanStack Start.

Stripe for payments, Resend for emails, Tailwind CSS v4 for styling, shadcn/ui for components.

The key insight: TanStack Start + Cloudflare is a powerful combination. You get React’s ecosystem with edge performance, and D1 gives you a real database with zero configuration.

The First Week

Day 1-2: Foundation

The first commits set up the entire foundation — TanStack Start with SSR, Cloudflare Workers adapter, Drizzle ORM, basic routing structure.

I also built the design system. I didn’t want another generic AI landing page with purple gradients. I created a custom “Olive Moss” palette — muted greens and warm grays that feel organic and calm.

By end of Day 2, I had a working dev server, a distinctive visual identity, and basic page layouts.

Day 3-4: Authentication

Authentication is always more complicated than you expect.

Better Auth needs to create its auth instance per-request, not as a singleton. In Cloudflare Workers, each request is isolated anyway, so this architecture actually works well. But figuring that out took a few hours of head-scratching.

I also designed the database schema upfront. The key decision: separating drafts from products.

Drafts have all nullable fields — users can save at any point in the submission flow and return later. Products have required fields — they only exist when fully submitted. This kept the data model clean and the code simple.

Day 4-5: The Submission Flow

The submission form is the heart of Shipstry. I wanted it to feel smooth, not overwhelming.

I built a progressive form with collapsible sections. Each section tracks its completion status. Users can save at any point, leave, and pick up where they left off days later.

For the product description, I integrated Milkdown — a plugin-driven Markdown editor with a custom toolbar. The tricky part was focus management: the toolbar kept stealing focus from the editor. I eventually fixed it by preventing default on mousedown for toolbar buttons.

Day 5: Pricing and Payments

I designed a nautical-themed pricing system:

  • Harbor (Free): Basic submission, normal review
  • Voyage ($9.9): Fast 24-hour review, same-week ship
  • Expedition ($29): Featured on homepage, 7 days exposure
  • Admiral ($59): 30 days featured, premium badge

Stripe integration was straightforward, but the webhook handler needed careful attention. D1 doesn’t support nested transactions, so I had to restructure the code to use sequential queries instead of wrapping everything in a transaction.

The AI Feature

Filling out product forms is tedious. Users paste a URL and then have to manually enter the name, tagline, description, logo, preview image…

So I built an AI-powered metadata fetcher.

✨ AI Stow…

When a user pastes their product URL, the system:

  1. Fetches the page and extracts Open Graph tags
  2. Sends the information to AI to generate an enhanced, compelling description
  3. Auto-fills all the form fields

The user can review and edit everything before submitting. It’s not about replacing human input — it’s about reducing friction.

Multi-Provider Failover

AI APIs are unreliable. They timeout, they rate limit, they have outages.

I built a failover system that tries multiple AI providers in priority order. If one fails, it automatically tries the next. The configuration is a simple JSON array in environment variables:

[
  {"name": "openai", "priority": 1},
  {"name": "claude", "priority": 2},
  {"name": "gemini", "priority": 3}
]

If all providers fail, the form still works — users just fill it manually. Graceful degradation is key.

SSRF Protection

Allowing users to fetch arbitrary URLs is dangerous. You don’t want someone hitting your internal services through your server.

I implemented multiple layers of protection:

  • Block private IP ranges (10.x, 172.x, 192.168.x)
  • Block localhost
  • Only allow HTTP and HTTPS protocols
  • Rate limit: 5 requests per minute per user

Comments and Voting

Comments support nesting — users can reply to replies. I used soft deletes instead of hard deletes, so if a parent comment is removed, the threading structure stays intact.

For voting, I wanted instant feedback. Nobody wants to wait for a server round-trip to see their vote register.

I implemented optimistic updates: when you click vote, the UI updates immediately. The server request happens in the background. If it fails, the UI rolls back. This makes the app feel snappy and responsive.

Notifications

Users get notified for:

  • Comments on their products
  • Replies to their comments
  • Award wins (weekly and monthly)
  • Product status changes (approved, rejected)

For email delivery, I used Cloudflare’s waitUntil() function. This sends the response to the user immediately while the email sends in the background. The user doesn’t wait for the email to send.

The Final Days

Caching

To reduce database load, I built a caching layer using D1 itself as the cache store. Cached data has TTLs, and mutations trigger automatic cache invalidation.

This pattern dramatically reduced read load on the main tables during high-traffic periods.

Environment Configuration

I centralized all environment variables with validation. In development, the app validates that all required secrets exist and throws clear errors if something is missing. In production, I trust that Cloudflare has the secrets configured.

This caught several configuration mistakes during development that would have been painful to debug in production.

Launch

On March 11, 2026, Shipstry went live.

The final commits added a launch promo banner with a 50% discount code, and adjusted the ship week logic to allow immediate launches during the launch period.

What I Learned

TanStack Start is ready for production. The framework is stable, well-typed, and SSR works seamlessly with Cloudflare Workers.

D1 is good enough. SQLite at the edge sounds limiting, but for most applications, it’s perfect. Zero configuration, fast queries, generous free tier. The main gotcha is no nested transactions.

Edge functions change how you think. No global state, waitUntil() for background tasks, zero cold starts, environment access through imports rather than process.env.

AI integration is easier than expected. With the right abstraction — multi-provider failover and graceful degradation — you can build reliable AI features.

640 commits in 9 days. That’s roughly 71 commits per day. Each commit was small, focused, and reversible. The discipline of atomic commits saved me multiple times when I needed to roll back a bad decision.

What Happened After Launch

Shipstry has been live for two days.

In that time, I’ve been doing link building — submitting to directories, reaching out to communities, getting featured on various platforms.

The results? DR went from 0 to 14 in two days.

Try It

Built with TanStack Start, Cloudflare Workers, D1, R2, and too much coffee.