<?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>Forem: sijiaoh</title>
    <description>The latest articles on Forem by sijiaoh (@sijiaoh).</description>
    <link>https://forem.com/sijiaoh</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%2F3705843%2F32cb13ad-5c1e-4d87-8c74-e5c7f9673a4e.jpg</url>
      <title>Forem: sijiaoh</title>
      <link>https://forem.com/sijiaoh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sijiaoh"/>
    <language>en</language>
    <item>
      <title>Why I Started Avoiding Frontend Development</title>
      <dc:creator>sijiaoh</dc:creator>
      <pubDate>Sat, 17 Jan 2026 10:46:04 +0000</pubDate>
      <link>https://forem.com/sijiaoh/why-i-started-avoiding-frontend-development-2bd2</link>
      <guid>https://forem.com/sijiaoh/why-i-started-avoiding-frontend-development-2bd2</guid>
      <description>&lt;h2&gt;
  
  
  The jQuery Era
&lt;/h2&gt;

&lt;p&gt;This story starts back in college. I took a web development class and got my first taste of building for the web. It was still the golden age of jQuery. HTML, CSS, and JavaScript in three separate files, linked together through classes. I hated it.&lt;/p&gt;

&lt;p&gt;It was just tedious.&lt;/p&gt;

&lt;p&gt;The instructor talked about the benefits of "separation of concerns," and I couldn't come up with a clever counterargument, so I let it go. But I wasn't convinced at all. I understood the philosophy of separating structure, style, and behavior. But jumping between three files just to change how a button looks—is that really "good design"? I didn't think so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meeting Vue.js
&lt;/h2&gt;

&lt;p&gt;In my second year as a professional developer, I started doing frontend work seriously. It was Vue.js (v2).&lt;/p&gt;

&lt;p&gt;I thought it was fantastic. Not because of reactivity or the virtual DOM or anything like that. It was the fact that HTML, CSS, and JavaScript lived in a single file. That alone made me happy.&lt;/p&gt;

&lt;p&gt;I knew it. We never needed to split things into three files.&lt;/p&gt;

&lt;p&gt;I liked Scoped CSS too. That massive, deeply nested, fundamentally unmaintainable mess (or so I firmly believe) known as global CSS—I could finally leave it behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving to React
&lt;/h2&gt;

&lt;p&gt;It didn't take long to learn that Vue, as great as it was, wasn't the global market leader.&lt;/p&gt;

&lt;p&gt;React was.&lt;/p&gt;

&lt;p&gt;JSX, the newly introduced Function Components, Hooks—these new concepts intimidated me a bit, but I figured I'd give it a shot and see what the fuss was about.&lt;/p&gt;

&lt;p&gt;It was fantastic. A sense of unity I'd never experienced before.&lt;/p&gt;

&lt;p&gt;The rule that Hooks must be called in the same order every time made me think, "How is this design even allowed?" But the elegance of building small, focused components and reusing them everywhere genuinely moved me. CSS-in-JS had its critics, but I personally liked it.&lt;/p&gt;

&lt;p&gt;At the end of the day, I just want everything about a component to live in one file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Redux Cloud
&lt;/h2&gt;

&lt;p&gt;The winds shifted when Redux entered the picture.&lt;/p&gt;

&lt;p&gt;Absurdly long, incomprehensible boilerplate. Countless restrictions I can barely remember now. I struggled through it all, thinking, "This is not the development experience I signed up for."&lt;/p&gt;

&lt;p&gt;But Redux was the standard back then. Everywhere I went, it was "we use Redux." That's when I started hating frontend development again. When job hunting, I began avoiding frontend roles and prioritizing backend work. It started around this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pain Eased, But
&lt;/h2&gt;

&lt;p&gt;When useContext came along, the pain eased a bit. The era of Redux dominance was coming to an end.&lt;/p&gt;

&lt;p&gt;But I still couldn't bring myself to like frontend.&lt;/p&gt;

&lt;p&gt;The boilerplate was disappearing. That wasn't the problem. Data and logic were merging with components—components that should be nothing more than a View layer for display. That bothered me.&lt;/p&gt;

&lt;p&gt;Sure, most pages just render whatever the backend returns, so it's not a big deal. But that's exactly why, when you build complex features on top of that foundation, it's so easy to end up writing data management and business logic directly inside components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind CSS: A Ray of Light
&lt;/h2&gt;

&lt;p&gt;When Tailwind CSS came out, I was genuinely excited.&lt;/p&gt;

&lt;p&gt;CSS, Sass, PostCSS, Vue Scoped CSS, CSS-in-JS. After all that wandering, I thought, "Finally, the right answer." Yes, classes tend to get long. But compared to CSS finally being manageable, that's not a problem at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Still Avoid Frontend
&lt;/h2&gt;

&lt;p&gt;Even now, I tend to avoid frontend work.&lt;/p&gt;

&lt;p&gt;The reason is simple: there are too many traps.&lt;/p&gt;

&lt;p&gt;Are they using Redux? Are they using something other than Tailwind for CSS? In complex features, is the logic tightly coupled with the view? Is the codebase stuck in an eternal transition period where all of the above coexist? Most of the time, you don't find out until you're already on the project. And more importantly, I'm the type of person who feels real pain when I encounter these problems.&lt;/p&gt;

&lt;p&gt;Of course, you could say "just fix it." But the key decision-makers might not agree with my views, and there might not be time allocated for refactoring.&lt;/p&gt;

&lt;p&gt;Backend, on the other hand, still feels relatively civilized.&lt;/p&gt;

&lt;p&gt;There are traps there too—over-engineered layered architecture, raw SQL everywhere, DDD enthusiasts, homegrown framework advocates. By the way, when it comes to DDD, I agree with the domain modeling philosophy in the first half of the book, but I don't agree with the technical implementation patterns in the second half.&lt;/p&gt;

&lt;p&gt;But backend traps are easier to spot in advance. Frontend traps require careful probing to uncover, while backend issues are relatively easy to assess. On top of that, Rails—my main battlefield—tends to be less accident-prone.&lt;/p&gt;

&lt;p&gt;So honestly, I haven't had the courage to join a team focused primarily on frontend. If I'm going to do it, I need at least a full-stack environment where I can touch the backend too. That's been my honest take for years now.&lt;/p&gt;

&lt;p&gt;That said, I do think the AI era might change things.&lt;/p&gt;




&lt;p&gt;Shameless plug: I'm building &lt;a href="https://dev.to/sijiaoh/my-phone-claude-code-and-me-373g"&gt;Pockode—code with Claude Code on your home PC from your phone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Original text: &lt;a href="https://sijiaoh.com/en/posts/why-i-avoid-frontend/" rel="noopener noreferrer"&gt;https://sijiaoh.com/en/posts/why-i-avoid-frontend/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>In the AI Era, a Single Branch Isn't Enough — git worktree Pockode</title>
      <dc:creator>sijiaoh</dc:creator>
      <pubDate>Sat, 17 Jan 2026 10:31:38 +0000</pubDate>
      <link>https://forem.com/sijiaoh/in-the-ai-era-a-single-branch-isnt-enough-git-worktree-x-pockode-12dn</link>
      <guid>https://forem.com/sijiaoh/in-the-ai-era-a-single-branch-isnt-enough-git-worktree-x-pockode-12dn</guid>
      <description>&lt;p&gt;In my last post, I wrote about &lt;a href="https://dev.to/en/posts/phone-claude-code-and-me/"&gt;building Pockode to control Claude Code on my home PC from my phone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After using it for a while, the next pain point became clear: parallel work.&lt;/p&gt;

&lt;p&gt;When you're using Claude Code, the waiting time starts to feel like a waste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pockode's worktree switching feature
&lt;/h2&gt;

&lt;p&gt;So I added git worktree management to Pockode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpudn3v2wdw7cauc590jd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpudn3v2wdw7cauc590jd.gif" alt=" " width="300" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few taps in the sidebar, and you can create and switch worktrees.&lt;/p&gt;

&lt;p&gt;Pockode was designed mobile-first, but I use it on my PC all the time too.&lt;/p&gt;

&lt;p&gt;By focusing on making switching "as easy as possible" on mobile, it ended up being the smoothest workflow on desktop as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  More and more tasks I want to run simultaneously
&lt;/h2&gt;

&lt;p&gt;While Claude Code is working on one feature, other things keep popping into my head:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to push forward on another feature&lt;/li&gt;
&lt;li&gt;I want to investigate a bug&lt;/li&gt;
&lt;li&gt;I want to clear out the PR review backlog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Back when I was writing code by hand, I'd just do things one at a time. But with Claude Code, the urge to "have it do multiple things at once" comes naturally.&lt;/p&gt;

&lt;p&gt;The question is: how do you manage parallel work?&lt;/p&gt;

&lt;h2&gt;
  
  
  Running in parallel in the same directory leads to collisions
&lt;/h2&gt;

&lt;p&gt;If you run multiple Claude Code instances sharing the same working directory, things will go wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files being generated get overwritten by another task&lt;/li&gt;
&lt;li&gt;Changes from one task break the assumptions of another&lt;/li&gt;
&lt;li&gt;State keeps shifting, and you lose track of what's actually done&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can make it work if you're careful, but if parallel work is the norm, you have t&lt;/p&gt;

&lt;p&gt;Original text: &lt;a href="https://sijiaoh.com/en/posts/pockode-git-worktree-parallel-workflow/" rel="noopener noreferrer"&gt;https://sijiaoh.com/en/posts/pockode-git-worktree-parallel-workflow/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>Coding on Your Phone? Actually, Yes.</title>
      <dc:creator>sijiaoh</dc:creator>
      <pubDate>Sun, 11 Jan 2026 21:54:57 +0000</pubDate>
      <link>https://forem.com/sijiaoh/my-phone-claude-code-and-me-373g</link>
      <guid>https://forem.com/sijiaoh/my-phone-claude-code-and-me-373g</guid>
      <description>&lt;p&gt;I want to write code on my phone.&lt;/p&gt;

&lt;p&gt;On the train, during a walk, waiting in line. Moments when I can't open my laptop, but my mind drifts to code—that function, that bug, that feature. But typing symbols on a phone is miserable. It's just not practical.&lt;/p&gt;

&lt;p&gt;That's what I used to think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovering Coding Agents
&lt;/h2&gt;

&lt;p&gt;Everything changed when I started using coding agents seriously.&lt;/p&gt;

&lt;p&gt;Natural language becomes code. Say "refactor this function" and it's refactored. Say "add tests" and tests appear. It can run commands too.&lt;/p&gt;

&lt;p&gt;Then it hit me: if I can code with natural language, why not on my phone?&lt;/p&gt;

&lt;h2&gt;
  
  
  So I Built Pockode
&lt;/h2&gt;

&lt;p&gt;At first, I considered setting up a dev environment in the cloud. But the setup was tedious, the performance mediocre. And honestly, I just wanted to use my familiar home setup.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://pockode.com" rel="noopener noreferrer"&gt;Pockode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It lets you control Claude Code on your home PC from your phone. If you have Claude Code installed, one command spins it up. Scan a QR code and you're in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sijiaoh/pockode" rel="noopener noreferrer"&gt;Pockode is open source&lt;/a&gt;. You can disable the official relay and self-host. Your code and runtime stay entirely under your control.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6h853o8as2vmg69vay5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6h853o8as2vmg69vay5.jpg" alt=" " width="420" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I Stopped Opening Neovim
&lt;/h2&gt;

&lt;p&gt;When I first started building Pockode, I still needed Neovim—at least to check git diffs.&lt;/p&gt;

&lt;p&gt;One day, I added git diff and file browsing to Pockode. I was debugging while using Pockode to continue development, and before I knew it—Pockode was all I needed.&lt;/p&gt;

&lt;p&gt;Now I only open Neovim when I want to dig deep into the codebase with full-text search.&lt;/p&gt;

&lt;p&gt;I once fixed a bug while taking a walk. Gave instructions to the AI on my phone, had it generate code and run tests. By the time I got home, the feature was done.&lt;/p&gt;

&lt;h2&gt;
  
  
  99% of the Code Was Written by AI
&lt;/h2&gt;

&lt;p&gt;99% of Pockode's code was generated by Claude Code. But I wasn't just delegating blindly—I discussed the design, reviewed the output, and corrected course when needed. Iterate, refine, repeat.&lt;/p&gt;

&lt;p&gt;My Go experience barely goes beyond tutorials. I hadn't touched React in ages. Yet I shipped something that works. Go is readable enough that even with fuzzy syntax knowledge, I can tell if the logic is right. The AI suggests the right libraries, proposes approaches I wouldn't have thought of.&lt;/p&gt;

&lt;p&gt;If I'd been coding alone, I probably would've abandoned it halfway. AI kept me going.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pitfalls of AI (and How to Deal with Them)
&lt;/h2&gt;

&lt;p&gt;AI isn't perfect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It goes off the rails.&lt;/strong&gt; Gets stuck in local optimization, loses sight of the original goal. Keeps iterating on a flawed premise. When you notice it, stop it. Explicitly redirect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It patches instead of fixes.&lt;/strong&gt; Sometimes it slaps on a band-aid instead of solving the root cause. Patches pile up, and suddenly simple functionality is buried in convoluted code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It writes meaningless code.&lt;/strong&gt; This one's insidious. Variables defined but never used. Branches that never execute. Harmless since it doesn't affect behavior. But in the next session, the AI tries to make sense of it: "This variable must exist for a reason." And that's where new misunderstandings begin.&lt;/p&gt;

&lt;p&gt;To catch these mistakes, you need to understand the big picture. You can't fully hand things off. But as long as you stay aware, AI is absolutely usable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Working Away from Your Desk
&lt;/h2&gt;

&lt;p&gt;Coding agents have an annoying problem: permission prompts.&lt;/p&gt;

&lt;p&gt;Writing files, running commands—each one pops up a confirmation. Want to step away and let it run? Sorry, it's stuck waiting for approval. But auto-approving everything feels risky.&lt;/p&gt;

&lt;p&gt;With Pockode, you can check permission requests from anywhere and approve with a tap. No more waiting.&lt;/p&gt;

&lt;p&gt;I used to hate stepping away when I was in the zone. Didn't want to break the flow. Now it's different. Walking around, on the train—I can check on the agent's progress and intervene when needed.&lt;/p&gt;

&lt;p&gt;Code from anywhere. That's the life I wanted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pockode.com" rel="noopener noreferrer"&gt;Pockode&lt;/a&gt;—give it a try if you're interested.&lt;/p&gt;

&lt;p&gt;Original text: &lt;a href="https://sijiaoh.com/en/posts/phone-claude-code-and-me/" rel="noopener noreferrer"&gt;https://sijiaoh.com/en/posts/phone-claude-code-and-me/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
