[{"data":1,"prerenderedAt":511},["ShallowReactive",2],{"navigation":3,"index":26,"mdc-8b92tz-key":185,"mdc--fz8gtw-key":198,"mdc--cms94b-key":207,"mdc-e0ris3-key":216,"index-blogs":225},[4],{"title":5,"path":6,"stem":7,"children":8,"page":25},"Blog","\u002Fblog","blog",[9,13,17,21],{"title":10,"path":11,"stem":12},"How I Built a Reusable Component Library from Scratch","\u002Fblog\u002Fbuilding-a-reusable-component-library","blog\u002Fbuilding-a-reusable-component-library",{"title":14,"path":15,"stem":16},"From Idea to Production: My End-to-End Engineering Process","\u002Fblog\u002Ffrom-idea-to-production","blog\u002Ffrom-idea-to-production",{"title":18,"path":19,"stem":20},"Web Performance Is a Feature","\u002Fblog\u002Fweb-performance-is-a-feature","blog\u002Fweb-performance-is-a-feature",{"title":22,"path":23,"stem":24},"The Case for Boring Technology and Maintainable Code","\u002Fblog\u002Fwriting-maintainable-code","blog\u002Fwriting-maintainable-code",false,{"id":27,"title":28,"about":29,"blog":32,"body":35,"description":36,"experience":37,"extension":50,"faq":51,"hero":94,"meta":152,"navigation":153,"path":154,"seo":155,"stem":158,"testimonials":159,"__hash__":184},"index\u002Findex.yml","Hey, I'm Rong Yuthean Software Engineer",{"title":30,"description":31},"about","I'm a software engineer with 6 years of experience building full-stack web and mobile applications. I spent four years at E-Power CCL Co., Ltd, and since 2024 I've been working as a freelancer, helping clients turn ideas into production-ready products.\nI care about clean architecture, well-tested code, and shipping products that are fast, secure, and easy to maintain, working across TypeScript, Node.js, Go, and cloud infrastructure.\n",{"title":33,"description":34},"latest articles","Notes on software architecture, engineering practices, and lessons from production",null,"I design and build reliable software, from clean APIs and scalable backends to fast, accessible front-ends. Turning complex problems into simple, maintainable code.",{"title":38,"items":39},"experience",[40,43],{"position":41,"date":42},"Freelance Software Engineer","2024 - Present",{"position":44,"date":45,"company":46},"Software Engineer at","2020 - 2024",{"name":47,"logo":48,"color":49},"E-Power CCL Co., Ltd","i-lucide-zap","#f59e0b","yml",{"title":52,"description":53,"categories":54},"faq","Answers to common questions about how I work and what I build.",[55,70,85],{"title":56,"questions":57},"Services & Process",[58,61,64,67],{"label":59,"content":60},"What services do you offer?","I build end-to-end software: full-stack web applications, REST and GraphQL APIs, backend services, and internal developer tools. I also help with system design and architecture reviews, performance optimization, cloud infrastructure and CI\u002FCD setup, and modernizing legacy codebases.\n",{"label":62,"content":63},"What is your development process like?","I start by understanding the problem and requirements, then write a short technical design covering architecture, data models, and trade-offs. From there I work in small, reviewable increments with automated tests, continuous integration, and regular demos, followed by monitoring and iteration once the system is in production.\n",{"label":65,"content":66},"What is your tech stack?","I mostly work with TypeScript, Vue\u002FNuxt, React, Node.js, Go, and Python, backed by PostgreSQL, Redis, and message queues. For infrastructure I use Docker, Kubernetes, Terraform, and AWS\u002FGCP, with GitHub Actions for CI\u002FCD. That said, I pick the tools that best fit the problem and the team.\n",{"label":68,"content":69},"Do you work with startups?","Absolutely! I enjoy helping startups go from idea to a production-ready MVP, choosing a pragmatic architecture that can ship quickly today and scale tomorrow.\n",{"title":71,"questions":72},"Pricing & Timelines",[73,76,79,82],{"label":74,"content":75},"How much does a project typically cost?","Project costs vary based on scope, complexity, integrations, and timeline. Full-stack engagements typically start around $5,000, with average projects ranging between $8,000 and $25,000. For consulting, code reviews, or architecture work, my day rate is $700.\n",{"label":77,"content":78},"What are your payment terms?","I generally require a 40% deposit to schedule the project and begin work, with the remaining 60% due upon successful delivery. I accept payments via bank transfer and Stripe.\n",{"label":80,"content":81},"How long does a typical project take?","Smaller projects such as an API, integration, or feature might take 3-4 weeks, while larger applications can range from 2 to 4 months. I always provide a detailed estimate and milestones after the initial discovery phase.\n",{"label":83,"content":84},"Do you offer retainers or ongoing support?","Yes, I offer monthly retainers for ongoing feature development, maintenance, dependency upgrades, and on-call support. Let's discuss what fits your needs.\n",{"title":86,"questions":87},"About Me",[88,91],{"label":89,"content":90},"What do you enjoy most about your work?","I love taking a messy, complex problem and breaking it down into a simple, well-structured system. There's nothing quite like seeing a service handle real traffic smoothly, or a refactor that makes a codebase a joy to work in again.\n",{"label":92,"content":93},"What do you do outside of work?","When I'm not coding, I enjoy contributing to open-source projects, tinkering with side projects and homelab setups, reading about distributed systems, and getting outdoors to recharge.\n",{"name":95,"role":96,"links":97,"stack":103},"Rong Yuthean","Software Engineer",[98],{"label":99,"to":100,"icon":101,"color":102},"Email me","mailto:yuing556@gmail.com","i-lucide-mail","neutral",[104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149],{"label":105,"icon":106},"TypeScript","i-simple-icons-typescript",{"label":108,"icon":109},"Vue","i-simple-icons-vuedotjs",{"label":111,"icon":112},"Nuxt","i-simple-icons-nuxtdotjs",{"label":114,"icon":115},"React","i-simple-icons-react",{"label":117,"icon":118},"Node.js","i-simple-icons-nodedotjs",{"label":120,"icon":121},"Go","i-simple-icons-go",{"label":123,"icon":124},"Python","i-simple-icons-python",{"label":126,"icon":127},"PostgreSQL","i-simple-icons-postgresql",{"label":129,"icon":130},"Redis","i-simple-icons-redis",{"label":132,"icon":133},"Kafka","i-simple-icons-apachekafka",{"label":135,"icon":136},"Docker","i-simple-icons-docker",{"label":138,"icon":139},"Kubernetes","i-simple-icons-kubernetes",{"label":141,"icon":142},"Terraform","i-simple-icons-terraform",{"label":144,"icon":145},"AWS","i-simple-icons-amazonwebservices",{"label":147,"icon":148},"Google Cloud","i-simple-icons-googlecloud",{"label":150,"icon":151},"GitHub Actions","i-simple-icons-githubactions",{},true,"\u002F",{"title":156,"description":157},"Rong Yuthean - Software Engineer","Welcome to my portfolio! I'm Rong Yuthean, a software engineer who builds reliable, scalable web applications and backend systems, from API design to production deployment.","index",[160,168,176],{"quote":161,"author":162},"Rong rebuilt our transaction pipeline from the ground up. The new event-driven architecture cut our p95 API latency by 60% and we haven't had a reconciliation incident since. On top of that, the code is clean, well-tested, and easy for the rest of the team to extend.",{"name":163,"description":164,"avatar":165},"Sarah Chen","Engineering Manager at Bloom Finance",{"src":166,"srcset":167},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x",{"quote":169,"author":170},"Rong was the engineer who made our launch possible. She designed our streaming backend, set up CI\u002FCD and observability from day one, and mentored our junior developers along the way. Her pull requests are a masterclass in thoughtful, readable code.",{"name":171,"description":172,"avatar":173},"Michael Rodriguez","CTO & Co-founder of Wavelength Music",{"src":174,"srcset":175},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x",{"quote":177,"author":178},"Rong took a slow, fragile data-ingestion system and turned it into a reliable, horizontally scalable service. She approaches every problem with strong fundamentals and pragmatic trade-offs, which is exactly what we needed as we scaled to millions of daily events.",{"name":179,"description":180,"avatar":181},"Dr. Aisha Johnson","VP of Engineering at GreenTech Solutions",{"src":182,"srcset":183},"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1573497019940-1c28c88b4f3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=40&h=40&q=80","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1573497019940-1c28c88b4f3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=80&h=80&q=80 2x","34u0Rpn28O_ck_XQbwMShBqvH4_3fuqIQgSxSLAa28U",{"data":186,"body":187},{},{"type":188,"children":189},"root",[190],{"type":191,"tag":192,"props":193,"children":194},"element","p",{},[195],{"type":196,"value":197},"text","I build end-to-end software: full-stack web applications, REST and GraphQL APIs, backend services, and internal developer tools. I also help with system design and architecture reviews, performance optimization, cloud infrastructure and CI\u002FCD setup, and modernizing legacy codebases.",{"data":199,"body":200},{},{"type":188,"children":201},[202],{"type":191,"tag":192,"props":203,"children":204},{},[205],{"type":196,"value":206},"I start by understanding the problem and requirements, then write a short technical design covering architecture, data models, and trade-offs. From there I work in small, reviewable increments with automated tests, continuous integration, and regular demos, followed by monitoring and iteration once the system is in production.",{"data":208,"body":209},{},{"type":188,"children":210},[211],{"type":191,"tag":192,"props":212,"children":213},{},[214],{"type":196,"value":215},"I mostly work with TypeScript, Vue\u002FNuxt, React, Node.js, Go, and Python, backed by PostgreSQL, Redis, and message queues. For infrastructure I use Docker, Kubernetes, Terraform, and AWS\u002FGCP, with GitHub Actions for CI\u002FCD. That said, I pick the tools that best fit the problem and the team.",{"data":217,"body":218},{},{"type":188,"children":219},[220],{"type":191,"tag":192,"props":221,"children":222},{},[223],{"type":196,"value":224},"Absolutely! I enjoy helping startups go from idea to a production-ready MVP, choosing a pragmatic architecture that can ship quickly today and scale tomorrow.",[226,408,459],{"id":227,"title":14,"author":228,"body":231,"color":398,"date":399,"description":400,"extension":401,"icon":402,"image":35,"layout":403,"meta":404,"minRead":405,"navigation":153,"path":15,"seo":406,"stem":16,"__hash__":407},"blog\u002Fblog\u002Ffrom-idea-to-production.md",{"name":95,"avatar":229},{"src":230,"alt":95},"\u002Fprofile.jpg",{"type":232,"value":233,"toc":383},"minimark",[234,237,240,245,248,253,256,262,265,269,272,285,289,292,295,299,302,317,320,324,327,331,334,338,349,353,380],[192,235,236],{},"Shipping good software isn't about following a rigid formula. It's about having a flexible process that adapts to each project while keeping quality high. After refining my approach across dozens of projects, I've landed on a workflow that consistently delivers reliable results without slowing teams down.",[192,238,239],{},"In this article, I'll walk through my end-to-end process, from understanding requirements to running code in production, using my work on the EcoTrack ingestion service as a case study.",[241,242,244],"h2",{"id":243},"phase-1-understanding-the-problem","Phase 1: Understanding the Problem",[192,246,247],{},"Every successful system starts with a clear understanding of the problem. For EcoTrack, the challenge was ingesting millions of sustainability events per day from mobile clients, without losing data and while keeping the API responsive.",[249,250,252],"h3",{"id":251},"gathering-requirements","Gathering Requirements",[192,254,255],{},"I started by talking to product, mobile, and data teams to understand the real constraints: expected traffic, peak loads, acceptable latency, and how fresh the data needed to be for downstream reports.",[257,258,259],"blockquote",{},[192,260,261],{},"\"We don't need real-time dashboards, but we can never lose an event.\" — Data team lead",[192,263,264],{},"That single sentence shaped the entire architecture.",[249,266,268],{"id":267},"defining-success","Defining Success",[192,270,271],{},"Before writing any code, we agreed on measurable goals:",[273,274,275,279,282],"ul",{},[276,277,278],"li",{},"p95 API latency under 100 ms at peak load",[276,280,281],{},"Zero data loss, with at-least-once delivery",[276,283,284],{},"New engineers able to ship a change in their first week",[241,286,288],{"id":287},"phase-2-technical-design","Phase 2: Technical Design",[192,290,291],{},"I wrote a short design document covering the architecture, data model, API contracts, failure modes, and alternatives we considered. The final design separated a thin, stateless API layer from asynchronous workers connected by a durable queue.",[192,293,294],{},"Sharing the design early surfaced issues that would have been expensive to fix later, like a missing idempotency key on the event endpoint.",[241,296,298],{"id":297},"phase-3-building-in-small-increments","Phase 3: Building in Small Increments",[192,300,301],{},"Instead of one big launch, I broke the work into small, independently deployable pieces:",[303,304,305,308,311,314],"ol",{},[276,306,307],{},"A walking skeleton: endpoint, queue, worker, and database, end to end",[276,309,310],{},"Validation, idempotency, and retries",[276,312,313],{},"Batching and backpressure for throughput",[276,315,316],{},"Dashboards, alerts, and runbooks",[192,318,319],{},"Every pull request was small, reviewed, and covered by unit and integration tests running in CI.",[241,321,323],{"id":322},"phase-4-testing-under-real-conditions","Phase 4: Testing Under Real Conditions",[192,325,326],{},"Unit tests catch logic bugs, but distributed systems fail in more interesting ways. I added load tests that replayed production-like traffic and chaos tests that killed workers mid-batch to verify we never dropped events.",[241,328,330],{"id":329},"phase-5-release-observability","Phase 5: Release & Observability",[192,332,333],{},"We rolled out behind a feature flag, starting with 1% of traffic and gradually increasing while watching latency, error rates, and queue depth. Structured logs, metrics, and distributed tracing made it easy to understand exactly what the system was doing.",[241,335,337],{"id":336},"results","Results",[273,339,340,343,346],{},[276,341,342],{},"p95 latency dropped from 450 ms to 80 ms",[276,344,345],{},"Zero lost events since launch",[276,347,348],{},"Infrastructure costs fell by 35% thanks to batching",[241,350,352],{"id":351},"key-takeaways","Key Takeaways",[273,354,355,362,368,374],{},[276,356,357,361],{},[358,359,360],"strong",{},"Clarify constraints first."," The right architecture falls out of the real requirements.",[276,363,364,367],{},[358,365,366],{},"Write it down."," A two-page design doc saves weeks of rework.",[276,369,370,373],{},[358,371,372],{},"Ship small."," Small changes are easier to review, test, and roll back.",[276,375,376,379],{},[358,377,378],{},"Observe everything."," You can't fix what you can't see.",[192,381,382],{},"Great engineering is less about clever code and more about a disciplined process that makes reliable outcomes the default.",{"title":384,"searchDepth":385,"depth":385,"links":386},"",2,[387,392,393,394,395,396,397],{"id":243,"depth":385,"text":244,"children":388},[389,391],{"id":251,"depth":390,"text":252},3,{"id":267,"depth":390,"text":268},{"id":287,"depth":385,"text":288},{"id":297,"depth":385,"text":298},{"id":322,"depth":385,"text":323},{"id":329,"depth":385,"text":330},{"id":336,"depth":385,"text":337},{"id":351,"depth":385,"text":352},"#10b981","2025-04-23","A detailed breakdown of how I take a feature from requirements to a reliable production release, with practical tips for engineers at every stage.","md","i-lucide-rocket","list",{},8,{"title":14,"description":400},"drh2O89XpebvLvGHI5XivRQWWWyi0zO6dyW1jhhW4CE",{"id":409,"title":18,"author":410,"body":412,"color":49,"date":451,"description":452,"extension":401,"icon":453,"image":35,"layout":454,"meta":455,"minRead":456,"navigation":153,"path":19,"seo":457,"stem":20,"__hash__":458},"blog\u002Fblog\u002Fweb-performance-is-a-feature.md",{"name":95,"avatar":411},{"src":230,"alt":95},{"type":232,"value":413,"toc":449},[414,417,420,423,426,429,446],[192,415,416],{},"Performance is often treated as a nice-to-have, something to fix \"later\". After a series of experiments on the Wavelength music web app, I've seen first-hand how much speed directly impacts user behavior.",[192,418,419],{},"When we first launched, our homepage took over four seconds to become interactive on mid-range mobile devices. Our engagement metrics were underwhelming, so I proposed treating performance as a product feature with its own goals and dashboards.",[192,421,422],{},"We started by collecting real-user metrics (Core Web Vitals) instead of relying only on lab tests on fast laptops. Then we tackled the biggest wins: code-splitting large routes, server-side rendering critical pages, lazy-loading images, and caching API responses at the edge.",[192,424,425],{},"The results were striking: cutting Largest Contentful Paint from 4.1 s to 1.6 s increased session starts by 34%. Even more interesting, users on slower networks saw the biggest gains, showing that performance work is also accessibility work.",[192,427,428],{},"I've since adopted a simple framework for performance:",[303,430,431,434,437,440,443],{},[276,432,433],{},"Measure real users, not just your own machine",[276,435,436],{},"Set performance budgets and enforce them in CI",[276,438,439],{},"Fix the biggest bottleneck first, then measure again",[276,441,442],{},"Make performance visible to the whole team with dashboards",[276,444,445],{},"Treat regressions like bugs, not nice-to-haves",[192,447,448],{},"The most valuable lesson I've learned is that fast software feels better, and users notice even when they can't explain why.",{"title":384,"searchDepth":385,"depth":385,"links":450},[],"2025-03-15","How measuring and optimizing real-user performance metrics directly improved engagement, conversion, and the overall user experience.","i-lucide-gauge","dashboard",{},5,{"title":18,"description":452},"oM3OxgJSz0maKN3YGiPgh6D4cO_KqPBp30cN24nHoCQ",{"id":460,"title":10,"author":461,"body":463,"color":502,"date":503,"description":504,"extension":401,"icon":505,"image":35,"layout":506,"meta":507,"minRead":508,"navigation":153,"path":11,"seo":509,"stem":12,"__hash__":510},"blog\u002Fblog\u002Fbuilding-a-reusable-component-library.md",{"name":95,"avatar":462},{"src":230,"alt":95},{"type":232,"value":464,"toc":500},[465,468,471,474,477,491,494,497],[192,466,467],{},"After years of copying the same components between projects, I finally built a proper shared component library. The process was challenging but incredibly rewarding, and I want to share my approach for other engineers considering the same journey.",[192,469,470],{},"I started by auditing five of our applications, looking for duplicated components and patterns. The results were eye-opening: seven slightly different button implementations, three date pickers, and inconsistent handling of loading and error states.",[192,472,473],{},"Rather than designing everything upfront, I built the library iteratively alongside a real product. Each component was extracted only once it had proven itself in production code.",[192,475,476],{},"The core of the library includes:",[273,478,479,482,485,488],{},[276,480,481],{},"Strongly typed components with TypeScript props and emitted events",[276,483,484],{},"Design tokens exposed as CSS variables for theming",[276,486,487],{},"Accessibility built in, with keyboard navigation and ARIA attributes tested automatically",[276,489,490],{},"Visual regression tests and auto-generated documentation",[192,492,493],{},"The biggest challenge wasn't technical but organizational: getting teams to trust and adopt a shared dependency. Semantic versioning, clear changelogs, and codemods for breaking changes made upgrades painless.",[192,495,496],{},"The payoff has been enormous: new features ship roughly 40% faster, UI bugs have dropped significantly, and every app now looks and behaves consistently.",[192,498,499],{},"If you're considering building your own library, start small with your most-used components, test them in real products, and automate everything you can. A good component library should feel like a trusted teammate, not a set of restrictions.",{"title":384,"searchDepth":385,"depth":385,"links":501},[],"#8b5cf6","2025-03-05","A practical guide to creating a shared, type-safe component library, from initial audit to publishing, and the lessons learned along the way.","i-lucide-blocks","grid",{},6,{"title":10,"description":504},"IXFwShXjMdisclgIXRJ0eIYjlbaTcoMEMnrlitGpKmA",1793207676402]