<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Quan Nguyen</title>
        <link>https://qu8n.com</link>
        <description>Quan Nguyen's RSS Feed</description>
        <lastBuildDate>Mon, 09 Feb 2026 13:34:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved 2026, Quan Nguyen</copyright>
        <atom:link href="https://qu8n.com/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Software engineers can no longer neglect their soft skills]]></title>
            <link>https://qu8n.com/posts/most-important-software-engineering-skill-2026</link>
            <guid isPermaLink="false">https://qu8n.com/posts/most-important-software-engineering-skill-2026</guid>
            <pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The bottleneck has shifted from implementation to specification.]]></description>
            <content:encoded><![CDATA[<p>import { EditSection } from &#39;@/components/edit-section&#39;;
import { HNComments } from &#39;@/components/hn-comments&#39;;</p>
<p>Starting in 2026, communication has become the most important skill for software engineers.</p>
<p>It&#39;s not writing code, system designs, or having estoric knowledge of a programming language (i.e., Rust).</p>
<p>AI coding agents have gotten <a href="https://x.com/bcherny/status/2004897269674639461">very, very good</a>. A year ago, I&#39;d reach out to Cursor hesitantly for MVPs or quick fixes. Today, I use Claude Code for almost all non-trivial programming tasks and have spent $500+ on it just last December.</p>
<p>AI talks online revolve much around the hard skils. Initially it was prompt tricks to accomplish X, then the best MCPs for Y, and so on. But with Opus 4.5, using vanilla Claude Code gets you 80% there. Even in the age of AI, the 80/20 rule still applies. So, what should engineers focus on?</p>
<p>One thing with coding agents is that the better the spec, the more in line they will be with the technical and business requirements. But getting a good spec is hard.</p>
<p>In real life, tickets rarely contain all the requirements. To do so, you might need to:</p>
<ul>
<li>Ask questions that reveal assumptions people didn&#39;t know they had</li>
<li>Facilite trade-off discussions</li>
<li>Push back on scope without burning bridges</li>
<li>Make calls on things nobody thought to specify</li>
</ul>
<p>Doing these things well used to be optional for individual contributors. Certain teams would enable engineers to thrive being an average communicator but excellent coder. Now, the non-coding parts are becoming a non-negotiable.</p>
<p>Software engineers are problem solvers. We believe that every problem has a solution, a &quot;best practice&quot;. But working with people is messy.</p>
<p><del>Un</del>fortunately, we won&#39;t be able to AI our way into better communication skills. Good communication requires empathy, and we can all use a little more of that in today&#39;s landscape.</p>
<EditSection>
  Edit: This post got some attention on [Hacker News](https://news.ycombinator.com/item?id=46667572). Some comments thought my $500+ spend on coding agents was an indicator of vibe coding or that AI wrote this post.

<p>  <a href="https://medium.com/@addyosmani/vibe-coding-is-not-the-same-as-ai-assisted-engineering-3f81088d5b98">AI-assisted development</a> isn&#39;t vibe coding. AI is just a tool, and a good craftsman should know his tools. I say that as an AI hype skeptic. <a href="https://mitchellh.com/writing/non-trivial-vibing">Here</a> is another good example of AI code assistance in production.</p>
<p>  I did not write this post with AI, although it did help me find a couple of typos. I started blogging very recently. If my writing reads like AI, then my writing is average, and I have a lot to learn! More to come.</p>
  <HNComments storyId={46667572} />
</EditSection>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running Claude Code from my phone]]></title>
            <link>https://qu8n.com/posts/running-claude-code-from-my-phone</link>
            <guid isPermaLink="false">https://qu8n.com/posts/running-claude-code-from-my-phone</guid>
            <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[A guide to controlling Claude Code running on your laptop from your phone over SSH using Termius, Tailscale, and tmux.]]></description>
            <content:encoded><![CDATA[<p>import { Info } from &#39;lucide-react&#39;;
import { YacineTweet } from &#39;./yacine-tweet.tsx&#39;;</p>
<img alt="hero" src={__img0} placeholder="blur" />

<h2>Introduction</h2>
<p>When I run Claude Code on a larger task, I often end up waiting on it while wanting to step away: coffee, a meeting, or a walk. I didn’t want to keep checking my laptop just to see whether it needed input or had finished.</p>
<p>Over the past month, I’ve been using a simple setup that lets me:</p>
<ul>
<li>keep Claude Code running on my Mac,</li>
<li>attach to the same session from my phone,</li>
<li>and get notified when it needs attention.</li>
</ul>
<YacineTweet />

<p>Mine is a simple workflow with SSH, tmux, and a couple of notification hooks, but it’s been reliable enough that I now use it almost daily.</p>
<p>This post documents my personal setup. If you’re on different devices or platforms, most of the ideas still apply.</p>
<h2>Prerequisites</h2>
<p>At a high level, the idea is:</p>
<ul>
<li>Claude Code runs on my Mac.</li>
<li>tmux keeps the session alive.</li>
<li>my phone SSHs in over Tailscale.</li>
<li>Claude Code hooks send notifications when it stops or needs input.</li>
</ul>
<p>Install the following tools on your Mac and/or iPhone:</p>
<table>
<thead>
<tr>
<th>Tool to install</th>
<th>Mac</th>
<th>iPhone</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://claude.com/product/claude-code">Claude Code</a></td>
<td>✅</td>
<td></td>
<td>Anthropic’s AI coding assistant</td>
</tr>
<tr>
<td><a href="https://github.com/tmux/tmux/wiki">tmux</a></td>
<td>✅</td>
<td></td>
<td>Access the same Claude Code session on your Mac and iPhone</td>
</tr>
<tr>
<td><a href="https://tailscale.com/download">Tailscale</a></td>
<td>✅</td>
<td>✅</td>
<td>Secure the SSH connection between your Mac and iPhone</td>
</tr>
<tr>
<td><a href="https://termius.com">Termius</a></td>
<td></td>
<td>✅</td>
<td>SSH client for your iPhone to connect to your Mac</td>
</tr>
<tr>
<td><a href="https://github.com/julienXX/terminal-notifier#download">terminal-notifier</a></td>
<td>✅</td>
<td></td>
<td>Get notifications on your Mac on Claude Code events</td>
</tr>
<tr>
<td><a href="https://ntfy.sh/">ntfy</a></td>
<td></td>
<td>✅</td>
<td>Get push notifications on your iPhone on Claude Code events</td>
</tr>
</tbody></table>
<p>I chose this combination of tools based on my familiarity with them (like tmux), cost (Termius and ntfy have generous free tiers), and ease of use (Tailscale).</p>
<p>I also wanted to (1) share the same Claude Code sessions between devices and (2) get notified on both devices when Claude Code needs my attention.</p>
<h2>Enable Remote Login on your Mac</h2>
<p><em>This step allows your Mac to accept SSH connections from other devices, enabling your iPhone to connect to it remotely.</em></p>
<ol>
<li>On your Mac, choose Apple menu , then click System Settings.</li>
<li>Click General ⚙️ in the sidebar, then click Sharing. (You may need to scroll down.)</li>
<li>Click <Info className="inline h-4 w-4" /> next to Remote Login.</li>
<li>Turn on Remote Login.</li>
<li>Turn on &quot;Allow full disk access for remote users&quot;.</li>
</ol>
<h2>Set up Tailscale</h2>
<p><em>Tailscale creates a VPN between your devices, protecting the SSH connection between your Mac and iPhone.</em></p>
<ol>
<li>Sign in with the same Tailscale account on both your Mac and iPhone.</li>
<li>Turn on Tailscale on both devices.</li>
<li>On your Mac, click on the Tailscale menu bar icon.</li>
<li>Note your Mac&#39;s Tailscale IP address (it will look like <code>100.x.x.x</code>). You&#39;ll use this IP address in the next step.</li>
</ol>
<h2>Set up Termius</h2>
<p><em>Termius is an SSH client that lets your iPhone connect to your Mac&#39;s terminal, allowing you to control Claude Code remotely.</em></p>
<h3>Generate a Termius SSH key</h3>
<ol>
<li>On your iPhone, open Termius.</li>
<li>Go to the &quot;Keychain&quot;, and tap the add button (+), then &quot;Generate Key&quot;.</li>
<li>Tap &quot;Save&quot; to create the key with default settings.</li>
<li>Tap on the newly created key, then export icon, and then &quot;Copy Public Key&quot;. We&#39;ll use this in the next step.</li>
</ol>
<h3>Add the Termius key to Mac</h3>
<ol>
<li><p>Return to your Mac and create the <code>~/.ssh/authorized_keys</code> file if it doesn&#39;t exist:</p>
<pre><code class="language-bash"> mkdir -p ~/.ssh &amp;&amp; touch ~/.ssh/authorized_keys
</code></pre>
</li>
<li><p>Ensure proper permissions:</p>
<pre><code class="language-bash"> chmod 700 ~/.ssh &amp;&amp; chmod 600 ~/.ssh/authorized_keys
</code></pre>
</li>
<li><p>Append the copied public key from Termius to the end of the <code>authorized_keys</code> file:</p>
<pre><code class="language-bash">echo &quot;REPLACE_THIS_WITH_YOUR_TERMIUS_PUBLIC_KEY&quot; &gt;&gt; ~/.ssh/authorized_keys
</code></pre>
<Callout>
  Your Termius public key should look something like "

<p>  <code>ssh-ed25519 AAAA... Generated By Termius</code></p>
<p>  &quot;.</p>
</Callout></li>
</ol>
<h3>Add your Mac as a Host in Termius</h3>
<ol>
<li>Return to Termius on your iPhone.</li>
<li>Go to &quot;Hosts&quot;, and tap the add button (+), then &quot;New Host&quot;.</li>
<li>Enter the following details and leave other fields as default:<ul>
<li>&quot;Label&quot;: Any custom identifier for your Mac (e.g., &quot;My Personal Mac&quot;).</li>
<li>&quot;IP or Hostname&quot;: Enter the Mac&#39;s Tailscale IP noted earlier (e.g., <code>100.123.45.67</code>).</li>
<li>&quot;Username&quot;: Your Mac login username.</li>
<li>&quot;SSH.id, Key, Certificate, FIDO2&quot;: Select the SSH key generated earlier.</li>
</ul>
</li>
<li>Tap &quot;Save&quot;, then &quot;Connect&quot;.</li>
</ol>
<h2>Share the same Claude Code session</h2>
<p><em>tmux lets us access the same terminal session from both the Mac and iPhone. You can start a Claude Code session on your Mac, then seamlessly switch to your iPhone to continue from exactly where you left off and vice versa.</em></p>
<p>Before connecting from your iPhone, create a tmux session on your Mac:</p>
<pre><code class="language-bash">tmux new -s session_name
</code></pre>
<p>Next, navigate to your code directory and start Claude Code:</p>
<pre><code class="language-bash">claude
</code></pre>
<p>You can now work normally on your Mac. The tmux session persists in the background even if you close the terminal window.</p>
<p>Next, switch back to Termius on your iPhone and run:</p>
<pre><code class="language-bash">tmux attach -t session_name
</code></pre>
<p>You&#39;ll see the exact same session that&#39;s running on your Mac, with all history and state intact.</p>
<p>Both devices can now view and control the same Claude Code session simultaneously. Any commands you type on your iPhone will appear on your Mac in real-time, and vice versa.</p>
<Callout title="Tip" type="info">
  New to `tmux`? Here are some handy commands:

<ul>
<li>Create a new session: <code>tmux new -s session_name</code></li>
<li>Attach to a session: <code>tmux attach -t session_name</code></li>
<li>Detach from session: <code>Ctrl + b</code>, then <code>d</code></li>
<li>Create a new window (tab) within a session: <code>Ctrl + b</code>, then <code>c</code></li>
<li>List sessions: <code>tmux ls</code></li>
<li>Kill session: <code>tmux kill-session -t session_name</code></li>
<li>See more in this <a href="https://tmuxcheatsheet.com/">cheat sheet</a></Callout></li>
</ul>
<h2>Set up notifications</h2>
<p><em>Get notified on both your Mac and iPhone when Claude Code completes tasks or needs your attention.</em></p>
<h3>Subscribe to a topic in ntfy</h3>
<p><em>ntfy is a simple push notification service that works via HTTP. We&#39;ll use it to send notifications from Claude Code running on your Mac to your iPhone.</em></p>
<ol>
<li>On your iPhone, open the ntfy app.</li>
<li>Tap the &quot;+&quot; button to add a new subscription.</li>
<li>Enter a unique topic name (e.g., <code>my-topic</code>) and tap &quot;Subscribe&quot;. If you use ntfy without sign-up, the topic is essentially a password, so pick something that&#39;s not easily guessable. If you purchase ntfy Pro, you can reserve topic names instead.</li>
</ol>
<h3>Configure Claude Code hooks</h3>
<p><em>With <a href="https://code.claude.com/docs/en/hooks-guide">Claude Code hooks</a>, we can trigger custom commands when certain events occur. We&#39;ll set up hooks to send notifications when Claude Code needs input and when it finishes working.</em></p>
<ol>
<li>Add the following to your global Claude Code settings:</li>
</ol>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;Notification&quot;: [
      {
        &quot;matcher&quot;: &quot;&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;terminal-notifier -title \&quot;🔔 Claude Code\&quot; -message \&quot;I need your input\&quot; -sound default -activate &#39;com.googlecode.iterm2&#39; &amp;&amp; curl -d \&quot;🔔 Claude Code: I need your input\&quot; ntfy.sh/my-topic&quot;
          }
        ]
      }
    ],
    &quot;Stop&quot;: [
      {
        &quot;matcher&quot;: &quot;&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;terminal-notifier -title \&quot;✅ Claude Code\&quot; -message \&quot;I&#39;m done!\&quot; -sound default -activate &#39;com.googlecode.iterm2&#39; &amp;&amp; curl -d \&quot;✅ Claude Code: I&#39;m done!\&quot; ntfy.sh/my-topic&quot;
          }
        ]
      }
    ]
  },
}
</code></pre>
<ol start="2">
<li>Replace <code>my-topic</code> in the <code>curl</code> commands with the topic name you subscribed to in ntfy.</li>
<li>I use <a href="https://iterm2.com/">iTerm2</a> as my terminal app. If you use a different one, replace <code>&#39;com.googlecode.iterm2&#39;</code> with the appropriate bundle identifier obtained from running <code>osascript -e &#39;id of app &quot;Insert app name&quot;&#39;</code>.</li>
<li>The <code>command</code> does two things: (1) send a notification to your Mac using <code>terminal-notifier</code>, and (2) send a push notification to your iPhone using <code>curl</code> to post to your subscribed ntfy topic. If you only want to be notified on one device, you can remove the other part of the command.</li>
<li>When you&#39;re done, save the settings file and restart Claude Code to apply the new settings.</li>
</ol>
<h2>Reflections</h2>
<p>The biggest win isn’t coding from my phone. It’s not feeling glued to my desk while Claude works. I can walk away then engage when there’s something to do.</p>
<p>But this setup isn&#39;t perfect:</p>
<ul>
<li>Typing on the phone feels clunky for anything more than a quick response, although I suspect I could get faster with practice (see <a href="https://www.reddit.com/r/programming/comments/1hay1z3/developer_wrote_25k_lines_of_neovim_plugin_code/">this NeoVim plugin author</a> who wrote 25K+ lines of code on his phone).</li>
<li>I&#39;m usually in front of my laptop, so the phone notifications are often more distracting than helpful. I ended up disabling the ntfy notifications for now. What would be nice is more granular control over when and how I&#39;m notified.</li>
</ul>
]]></content:encoded>
        </item>
    </channel>
</rss>