<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: QUN ZOU</title>
    <description>The latest articles on DEV Community by QUN ZOU (@qun_zou_5f50f061cca33d266).</description>
    <link>https://dev.to/qun_zou_5f50f061cca33d266</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3869363%2Fa0ec77d7-d114-49cd-bc68-b6ef5682d443.png</url>
      <title>DEV Community: QUN ZOU</title>
      <link>https://dev.to/qun_zou_5f50f061cca33d266</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qun_zou_5f50f061cca33d266"/>
    <language>en</language>
    <item>
      <title>From Writing Requirements Docs to Shipping My First Solo Product</title>
      <dc:creator>QUN ZOU</dc:creator>
      <pubDate>Thu, 09 Apr 2026 09:47:46 +0000</pubDate>
      <link>https://dev.to/qun_zou_5f50f061cca33d266/from-writing-requirements-docs-to-shipping-my-first-solo-product-2dfb</link>
      <guid>https://dev.to/qun_zou_5f50f061cca33d266/from-writing-requirements-docs-to-shipping-my-first-solo-product-2dfb</guid>
      <description>&lt;p&gt;For most of my career, I was the person around the code.&lt;/p&gt;

&lt;p&gt;I wrote requirements documents. I planned sprints. I argued about pricing models. I sat in rooms with engineers and said things like "can we ship by Friday?" I understood software deeply — but I'd never built an entire product by myself, from idea to deployment.&lt;/p&gt;

&lt;p&gt;This year, I decided to change that.&lt;/p&gt;

&lt;p&gt;The result: chinanam.online — a Chinese name generator for foreigners. It's live, it takes real payments, and I built every line of it myself.&lt;/p&gt;

&lt;p&gt;Here's what that actually looked like.&lt;br&gt;
Why This Project&lt;br&gt;
I've always been fascinated by how foreigners get Chinese names. Most tools online just phonetically map English sounds to random characters — which produces names that native speakers find odd or meaningless.&lt;/p&gt;

&lt;p&gt;I thought: someone should build this properly. Then I realized — that someone could be me.&lt;/p&gt;

&lt;p&gt;It was small enough to ship alone, but complex enough to teach me something. Good enough.&lt;br&gt;
What It Does&lt;br&gt;
You enter your English name, birthday, gender, and a style preference. The generator produces:&lt;br&gt;
Authentic Chinese characters — selected for meaning and phonetic harmony, not just transliteration&lt;br&gt;
Pinyin pronunciation guide&lt;br&gt;
Character meanings — so you understand what your name actually says&lt;br&gt;
Chinese zodiac sign from your birthday&lt;br&gt;
A personalized lucky phrase drawn from your name's characters&lt;br&gt;
A downloadable "Lucky Card" — a decorated digital card with your name and zodiac animal ($1 via PayPal)&lt;br&gt;
The Parts That Humbled Me&lt;br&gt;
Coming from a planning background, I thought I understood what "building software" involved. I did not.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There's no one to hand the ticket to
When I wrote requirements, someone else figured out the hard parts. Now I was the someone else. Every ambiguous edge case, every API quirk, every "how do we actually do this?" — that was mine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Canvas API was a good example. I wanted the Lucky Card to render instantly, client-side, with no server involved. That meant embedding all artwork as base64 in a TypeScript constants file and drawing everything programmatically:&lt;br&gt;
const canvas = document.createElement('canvas');&lt;br&gt;
const ctx = canvas.getContext('2d');&lt;/p&gt;

&lt;p&gt;const bg = new Image();&lt;br&gt;
bg.src = CARD_BACKGROUNDS[style]; // base64, loads instantly&lt;br&gt;
ctx.drawImage(bg, 0, 0, 1200, 800);&lt;br&gt;
// then zodiac animal, name text, lucky phrase...&lt;/p&gt;

&lt;p&gt;It took me three days to get the text rendering right across different screen densities. Three days on text rendering. I'd never budgeted for that in a requirements doc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decisions don't wait for a meeting
Every day brought 10 decisions I'd normally escalate. Do we support 2-character names, 3-character, or both? What happens if the zodiac year lookup is off by one? Is $1 the right price?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I had to just... decide. And live with it. That was uncomfortable at first, then liberating.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Shipping is the hardest part of the spec to write
I've written "Definition of Done" criteria hundreds of times. I've never felt the weight of them until I was the one deciding whether something was done.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Deploying to Cloudflare Pages with @cloudflare/next-on-pages was straightforward once I understood the edge runtime constraints. But deciding it was ready to show people? That took longer than the deployment itself.&lt;br&gt;
The Stack (and Why)&lt;br&gt;
Next.js 15 — I knew React from reading PRDs for React projects. Close enough to start.&lt;br&gt;
Tailwind CSS v4 — Fast to iterate without a designer (me).&lt;br&gt;
Cloudflare Pages — Free tier, global CDN, deploys in under 2 minutes.&lt;br&gt;
PayPal JS SDK — One-time payments, no subscription complexity, buyers don't need an account.&lt;br&gt;
Canvas API — Client-side card rendering, zero server cost.&lt;/p&gt;

&lt;h1&gt;
  
  
  My entire deploy command
&lt;/h1&gt;

&lt;p&gt;npx @cloudflare/next-on-pages&lt;/p&gt;

&lt;h2&gt;
  
  
  wrangler pages deploy .vercel/output/static --project-name chinese-name-v2
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What I Got Right (By Accident)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Going client-side for everything I could.&lt;/strong&gt; No backend means no server to maintain, no database to babysit. Name generation and card rendering are 100% in the browser. The only server interaction is the PayPal payment flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Keeping the MVP tiny.&lt;/strong&gt; I resisted every urge to add user accounts, name history, social sharing, bulk generation. Ship first. Add later.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bundle size.&lt;/strong&gt; Base64-encoding all images keeps things self-contained but bloated the homepage to ~970KB. I'd use Cloudflare R2 for assets next time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Mobile testing earlier.&lt;/strong&gt; Canvas pixel ratio differences between iOS and Android bit me late in the process. A requirements doc never would have caught that either — but I would have asked an engineer about it.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Where I Am Now
&lt;/h2&gt;

&lt;p&gt;The site is live. It gets real traffic. Someone paid $1 for a Lucky Card last week, and I felt something I'd never felt before in my career: the specific satisfaction of someone paying for a thing you made entirely yourself.&lt;br&gt;
I'm not a "real developer" by most definitions. I still think in requirements and user stories. But I'm learning that those instincts — thinking about the user, questioning assumptions, caring about the whole product — are actually useful when you're the only one in the room.&lt;br&gt;
👉 &lt;a href="https://chinanam.online" rel="noopener noreferrer"&gt;https://chinanam.online&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  If you've made a similar transition — from PM, analyst, designer, or any non-engineering role into solo building — I'd genuinely love to hear how you approached it.
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Built with Next.js 15, Tailwind CSS v4, Cloudflare Pages, Canvas API, and PayPal JS SDK.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>nextjs</category>
      <category>cloudflarechallenge</category>
      <category>indiehacker</category>
    </item>
  </channel>
</rss>
