Thu. Mar 26th, 2026

Building Shipstry: 640 Commits, 9 Days, One Launch

The topic of Building Shipstry: 640 Commits, 9 Days, One Launch is currently the subject of lively debate — readers and analysts are keeping a close eye on developments.

This is taking place in a dynamic environment: companies’ decisions and competitors’ reactions can quickly change the picture.

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.

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.

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.

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.

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 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.

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.

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.

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.

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

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

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:

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

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

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.

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.

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.

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.

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.

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.

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

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.

For further actions, you may consider blocking this person and/or reporting abuse

DEV Community — A space to discuss and keep up software development and manage your software career

Built on Forem — the open source software that powers DEV and other inclusive communities.

Why it matters

News like this often changes audience expectations and competitors’ plans.

When one player makes a move, others usually react — it is worth reading the event in context.

What to look out for next

The full picture will become clear in time, but the headline already shows the dynamics of the industry.

Further statements and user reactions will add to the story.

Related Post