<?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: Huy Pham</title>
    <description>The latest articles on Forem by Huy Pham (@quochuydev).</description>
    <link>https://forem.com/quochuydev</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%2F754331%2Fcde2edf0-0cfb-4cf8-9b29-b885b1639cff.jpg</url>
      <title>Forem: Huy Pham</title>
      <link>https://forem.com/quochuydev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/quochuydev"/>
    <language>en</language>
    <item>
      <title>How I Stopped Rebuilding Auth Every Project and Wrote the Keycloak Playbook I Wish I Had</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Fri, 24 Apr 2026 10:44:57 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-stopped-rebuilding-auth-every-project-and-wrote-the-keycloak-playbook-i-wish-i-had-2coo</link>
      <guid>https://forem.com/quochuydev/how-i-stopped-rebuilding-auth-every-project-and-wrote-the-keycloak-playbook-i-wish-i-had-2coo</guid>
      <description>&lt;p&gt;Every new product I've shipped starts the same way: "We just need login, right?" Two weeks later we're knee-deep in password resets, refresh tokens, org invites, and role checks sprinkled across five services. I got tired of rediscovering the same traps, so I wrote down the exact Keycloak setup I now copy into every multi-tenant app — gateway, frontends, account app, and all.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Identity is three hard problems pretending to be one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; — login, MFA, email/SMS verification, forgot-password, social providers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization&lt;/strong&gt; — which role can do what, baked into tokens so services don't need to call a DB on every request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenancy&lt;/strong&gt; — organizations, invites, role scoping per org, sysadmin vs org-owner vs end user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams either roll their own (and leak tokens) or drop in Keycloak and then spend a month figuring out realms, clients, JWKS caching, and how the gateway should verify tokens. The docs tell you &lt;em&gt;what&lt;/em&gt; exists, not &lt;em&gt;how to wire it into a real product&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Keycloak Playbook
&lt;/h2&gt;

&lt;p&gt;A hands-on playbook that walks through a realistic architecture — a Node.js gateway, three Next.js frontends, and a shared account app — all delegating to Keycloak via OIDC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser → Account App (login UI) → Keycloak (OIDC + PKCE)
       → Gateway (verifies JWT via JWKS) → internal services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No copy-pasting snippets from five Stack Overflow answers. One consistent model from realm setup to JWT verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keycloak runs in Docker&lt;/strong&gt; — &lt;code&gt;docker-compose up&lt;/code&gt; boots Keycloak 26 + Postgres with health checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One realm, four clients&lt;/strong&gt; — gateway, sysadmin, admin, app, account — each with the right flow and scopes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Account App owns login&lt;/strong&gt; — every frontend redirects here, so SSO "just works" across apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway verifies tokens&lt;/strong&gt; — JWKS cached, roles checked, trusted headers (&lt;code&gt;X-User-Id&lt;/code&gt;, &lt;code&gt;X-Org-Id&lt;/code&gt;) forwarded downstream&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result: raw tokens never leak past the gateway, and services stay blissfully unaware of Keycloak.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/keycloak-playbook
&lt;span class="nb"&gt;cd &lt;/span&gt;keycloak-playbook &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keycloak 26&lt;/strong&gt; at &lt;code&gt;http://localhost:8080&lt;/code&gt; — admin console ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postgres 16&lt;/strong&gt; — persistent realm/user data via named volume&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt; — so dependent services wait until Keycloak is actually ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs site&lt;/strong&gt; — &lt;code&gt;cd docs &amp;amp;&amp;amp; pnpm dev&lt;/code&gt; to browse the full playbook locally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Covers&lt;/th&gt;
&lt;th&gt;Who It's For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Realm, clients, roles, groups, orgs, SMTP, SMS SPI&lt;/td&gt;
&lt;td&gt;DevOps / first-time Keycloak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APIs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/token&lt;/code&gt;, refresh, logout, introspect, admin APIs (curl + sample JSON)&lt;/td&gt;
&lt;td&gt;Anyone wiring HTTP clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway&lt;/td&gt;
&lt;td&gt;JWT verify, JWKS caching, role checks, service-to-service&lt;/td&gt;
&lt;td&gt;Node.js backend devs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;td&gt;auth.js config, silent refresh, RBAC on pages &amp;amp; actions&lt;/td&gt;
&lt;td&gt;Frontend devs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account App&lt;/td&gt;
&lt;td&gt;Custom login/register/profile UI on top of Keycloak&lt;/td&gt;
&lt;td&gt;Full-stack / UX&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Standards, not magic&lt;/strong&gt; — OIDC + OAuth 2.1 means you can swap libraries without rewriting auth logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One realm, many apps&lt;/strong&gt; — users log in once at the Account App and get SSO everywhere else&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusted headers over raw tokens&lt;/strong&gt; — downstream services don't touch JWTs, so blast radius stays small&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy-pasteable&lt;/strong&gt; — every section has real curl commands and real JSON responses, not hand-waving&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're about to bolt Keycloak onto a new project and dreading the realm-config rabbit hole:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/keycloak-playbook
&lt;span class="nb"&gt;cd &lt;/span&gt;keycloak-playbook &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:8080&lt;/code&gt;, log in with &lt;code&gt;admin / admin&lt;/code&gt;, and follow the Setup section of the docs site to build your first realm.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/keycloak-playbook" rel="noopener noreferrer"&gt;github.com/quochuydev/keycloak-playbook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://keycloak.quochuy.dev" rel="noopener noreferrer"&gt;keycloak.quochuy.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What's the most painful part of Keycloak you've hit in production — JWKS rotation, org invites, custom themes? I'd love to hear what I should add to the playbook next.&lt;/p&gt;

</description>
      <category>keycloak</category>
      <category>authentication</category>
    </item>
    <item>
      <title>How I Built a Chrome Extension That Launches Gemini Prompts Straight From a URL</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Fri, 24 Apr 2026 08:07:24 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-chrome-extension-that-launches-gemini-prompts-straight-from-a-url-4c36</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-chrome-extension-that-launches-gemini-prompts-straight-from-a-url-4c36</guid>
      <description>&lt;p&gt;I kept opening Gemini, waiting for the page to load, clicking the input box, pasting my prompt, and hitting enter—maybe twenty times a day. Multiply that by a team and it's death by a thousand clicks. So I built a tiny Chrome extension that turns the whole dance into a single URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you use Gemini regularly, you've probably felt this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every prompt starts with: open tab → wait → click input → paste → press enter&lt;/li&gt;
&lt;li&gt;You can't share a "runnable" prompt with a teammate—only the raw text&lt;/li&gt;
&lt;li&gt;Launcher tools (Raycast, Alfred, PopClip) can open URLs, but Gemini doesn't accept prompts via URL&lt;/li&gt;
&lt;li&gt;Bookmarks are useless for anything beyond a home page&lt;/li&gt;
&lt;li&gt;Repetitive prompts (daily standup summaries, translation, code review) have no shortcut&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The friction is small, but it adds up. And it kills the instinct to "just ask Gemini real quick."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Gemini URL Launcher
&lt;/h2&gt;

&lt;p&gt;What if a URL could carry the prompt, and Gemini would just run it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://gemini.google.com/app?q=Summarize%20today%27s%20standup%20notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open that link, and the extension types the prompt into Gemini and submits it for you. That's the whole idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You craft a URL&lt;/strong&gt; with &lt;code&gt;?q=&amp;lt;your prompt&amp;gt;&lt;/code&gt; pointing at &lt;code&gt;gemini.google.com/app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The extension watches&lt;/strong&gt; that domain for the &lt;code&gt;q&lt;/code&gt; parameter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A content script fills the input&lt;/strong&gt; and submits the prompt automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini responds&lt;/strong&gt; as if you typed it yourself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No API keys. No server. No data leaves your browser—the extension only runs on &lt;code&gt;gemini.google.com&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/gemini-url-launcher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then load it as an unpacked extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;chrome://extensions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Toggle &lt;strong&gt;Developer mode&lt;/strong&gt; (top-right)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Load unpacked&lt;/strong&gt; and pick the cloned folder&lt;/li&gt;
&lt;li&gt;Pin it from the puzzle-piece icon so you know it's active&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Works on Chrome, Edge, Brave, Arc, and Opera—anything Chromium-based.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to Use It
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;How to Set It Up&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser bookmark&lt;/td&gt;
&lt;td&gt;Save the Gemini URL with your prompt as a bookmark&lt;/td&gt;
&lt;td&gt;One-click "explain this error" prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raycast / Alfred&lt;/td&gt;
&lt;td&gt;Create a quicklink or web search with &lt;code&gt;{query}&lt;/code&gt; in the URL&lt;/td&gt;
&lt;td&gt;Type prompt in launcher → hits Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PopClip&lt;/td&gt;
&lt;td&gt;Add a URL action that sends selected text as the prompt&lt;/td&gt;
&lt;td&gt;Select text anywhere → send to Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shell alias&lt;/td&gt;
&lt;td&gt;&lt;code&gt;open "https://gemini.google.com/app?q=$*"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gemini "refactor this regex"&lt;/code&gt; from the CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scripts / automation&lt;/td&gt;
&lt;td&gt;Generate URLs from templates and open them programmatically&lt;/td&gt;
&lt;td&gt;Daily digest, code review, translation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;URLs are universal&lt;/strong&gt; - Every tool, OS, and script knows how to open one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero config&lt;/strong&gt; - No auth, no API, no server; it's just a content script&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private by design&lt;/strong&gt; - The extension collects nothing and only touches Gemini's domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable&lt;/strong&gt; - Drop it into any workflow you already have&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  One Caveat
&lt;/h2&gt;

&lt;p&gt;Gemini occasionally changes its page layout, which can break the selector the extension relies on. If it stops working, pull the latest version—fixes usually land fast because the content script is tiny.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you've ever wished Gemini had a command palette, this is basically that—just using URLs as the interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/gemini-url-launcher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load it, then try bookmarking a prompt you run often. You'll feel the difference after about three uses.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/gemini-url-launcher" rel="noopener noreferrer"&gt;github.com/quochuydev/gemini-url-launcher&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What's the prompt you'd wire to a single keystroke if you could? Drop it in the comments—I'm collecting ideas for a shared "Gemini shortcut pack."&lt;/p&gt;

</description>
      <category>chrome</category>
      <category>ai</category>
      <category>productivity</category>
      <category>extensions</category>
    </item>
    <item>
      <title>I Built a SaaS Boilerplate So You Never Start From Scratch Again</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Tue, 31 Mar 2026 09:04:30 +0000</pubDate>
      <link>https://forem.com/quochuydev/i-built-a-saas-boilerplate-so-you-never-start-from-scratch-again-311e</link>
      <guid>https://forem.com/quochuydev/i-built-a-saas-boilerplate-so-you-never-start-from-scratch-again-311e</guid>
      <description>&lt;p&gt;Every time I started a new SaaS project, I spent the first two weeks wiring up the same things: authentication, payments, API keys, docs. I got tired of rebuilding infrastructure instead of building the actual product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you've ever launched a SaaS, you know the drill:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up authentication with OAuth providers takes days of configuration and edge-case handling&lt;/li&gt;
&lt;li&gt;Integrating payment processing means wrestling with webhooks, credit systems, and billing dashboards&lt;/li&gt;
&lt;li&gt;Building API key management with usage tracking and audit logs from scratch is tedious&lt;/li&gt;
&lt;li&gt;Writing documentation infrastructure and blog systems before writing a single line of product code&lt;/li&gt;
&lt;li&gt;Handling SEO, legal pages, and landing page scaffolding every. single. time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: what-is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;what-is&lt;/strong&gt; is a production-ready SaaS boilerplate built on Next.js 16, React 19, and TypeScript. Clone it, swap in your business logic, and ship.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/what-is.git
&lt;span class="nb"&gt;cd &lt;/span&gt;what-is/web &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get auth, payments, API keys, docs, blog, and a landing page — all wired up and ready to customize.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone and configure&lt;/strong&gt; — Set up your environment variables for Clerk (auth), PayPal (payments), and your database (Neon PostgreSQL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace the service logic&lt;/strong&gt; — The default app is an AI-powered definition lookup. Swap the &lt;code&gt;/api&lt;/code&gt; endpoint and playground with your own product logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customize pricing&lt;/strong&gt; — Edit credit packages in &lt;code&gt;src/lib/paypal.ts&lt;/code&gt; to match your pricing model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy to Vercel&lt;/strong&gt; — Follow the included 7-step deployment guide and you're live&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From clone to production in under an hour instead of under a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/what-is.git
&lt;span class="nb"&gt;cd &lt;/span&gt;what-is/web
npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env
npm run db:push
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This scaffolds a full SaaS application with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; — Google OAuth via Clerk with database sync&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments&lt;/strong&gt; — PayPal checkout with a credit-based billing system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API key management&lt;/strong&gt; — Generate, revoke, and track usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; — MDX-powered docs via Fumadocs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog&lt;/strong&gt; — Category-filtered blog with individual post pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard&lt;/strong&gt; — API keys, usage analytics, and billing in one place&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Included
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Implementation&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;Clerk + Google OAuth&lt;/td&gt;
&lt;td&gt;Database-synced user accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payments&lt;/td&gt;
&lt;td&gt;PayPal checkout&lt;/td&gt;
&lt;td&gt;Credit packages: $1/1cr, $5/6cr, $20/30cr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Keys&lt;/td&gt;
&lt;td&gt;Custom system&lt;/td&gt;
&lt;td&gt;Generate, revoke, audit logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docs&lt;/td&gt;
&lt;td&gt;Fumadocs + MDX&lt;/td&gt;
&lt;td&gt;Full documentation site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blog&lt;/td&gt;
&lt;td&gt;MDX + categories&lt;/td&gt;
&lt;td&gt;Filterable, SEO-optimized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;Protected routes&lt;/td&gt;
&lt;td&gt;API keys, usage stats, billing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Landing Page&lt;/td&gt;
&lt;td&gt;Pre-built&lt;/td&gt;
&lt;td&gt;Hero, features, stats sections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legal&lt;/td&gt;
&lt;td&gt;Templates&lt;/td&gt;
&lt;td&gt;Privacy policy, terms of service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;OpenGraph, structured data, sitemap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Next.js 16 / React 19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS v4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;PostgreSQL (Neon) + Drizzle ORM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;Clerk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payments&lt;/td&gt;
&lt;td&gt;PayPal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM&lt;/td&gt;
&lt;td&gt;OpenAI-compatible APIs (DeepSeek, Groq, OpenAI)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Skip the boilerplate tax&lt;/strong&gt; — Authentication, payments, and API management are solved problems. Stop re-solving them and focus on what makes your product unique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern stack, no compromises&lt;/strong&gt; — Next.js 16, React 19, TypeScript, and Tailwind v4 mean you're building on the latest foundations, not fighting legacy patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PayPal-friendly&lt;/strong&gt; — Unlike Stripe-dependent boilerplates, this works with PayPal personal accounts — perfect for indie hackers and solo founders who want to start accepting payments immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT licensed&lt;/strong&gt; — Fork it, modify it, ship it commercially. No strings attached.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/what-is.git
&lt;span class="nb"&gt;cd &lt;/span&gt;what-is/web &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start by visiting &lt;code&gt;http://localhost:3000/playground&lt;/code&gt; to see the default AI definition service in action. Then replace it with your own logic and you've got a SaaS.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/what-is" rel="noopener noreferrer"&gt;quochuydev/what-is&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://what-is.cappuai.com" rel="noopener noreferrer"&gt;what-is.cappuai.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What's the first feature you'd build on top of this boilerplate? Drop it in the comments — I'm curious what people would ship with it.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I made a cat and let it run around on my laptop.</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Mon, 30 Mar 2026 15:07:19 +0000</pubDate>
      <link>https://forem.com/quochuydev/i-made-a-cat-and-let-it-run-around-on-my-laptop-mfn</link>
      <guid>https://forem.com/quochuydev/i-made-a-cat-and-let-it-run-around-on-my-laptop-mfn</guid>
      <description>&lt;p&gt;The result of today's work.&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%2F5u05asbeuio3an5gib8v.png" 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%2F5u05asbeuio3an5gib8v.png" alt=" " width="610" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download and give me feedback (by creating issue here):&lt;br&gt;
&lt;a href="https://github.com/quochuydev/cat/tree/main?tab=readme-ov-file#installation" rel="noopener noreferrer"&gt;https://github.com/quochuydev/cat/tree/main?tab=readme-ov-file#installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The source code is public, no any personal information (in machine) send to server or external.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>cat</category>
    </item>
    <item>
      <title>How I Built a Traceable API Gateway with NATS and Chain of Thought Flows</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Thu, 15 Jan 2026 11:14:42 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-traceable-api-gateway-with-nats-and-chain-of-thought-flows-364i</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-traceable-api-gateway-with-nats-and-chain-of-thought-flows-364i</guid>
      <description>&lt;p&gt;Ever debugged a production issue where a request passed through 5 services and you had no idea what went wrong where? I got tired of logging everything manually and losing context across async boundaries, so I built an API gateway that traces every operation automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;In distributed systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests bounce between services, logs scatter everywhere&lt;/li&gt;
&lt;li&gt;Business logic gets buried in boilerplate&lt;/li&gt;
&lt;li&gt;Validation happens inconsistently across endpoints&lt;/li&gt;
&lt;li&gt;When things fail, you're grep-ing through logs hoping to find the chain&lt;/li&gt;
&lt;li&gt;Adding tracing to existing code means refactoring everything&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Flow-Based Architecture
&lt;/h2&gt;

&lt;p&gt;What if every API operation was a traceable flow with built-in validation?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Fastify → NATS Request → Flow → NATS Reply → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each flow has automatic tracing. You see exactly what happened, step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define a Flow&lt;/strong&gt; - Wrap your business logic in a flow function with input/trace/ok callbacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NATS Handles Messaging&lt;/strong&gt; - Flows communicate via NATS subjects, decoupling services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Tracing&lt;/strong&gt; - Every flow step is logged with context, no manual instrumentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema Validation&lt;/strong&gt; - Inputs are validated before your code runs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No scattered console.logs. No lost context. Every operation is auditable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/nats-flow-gateway.git
&lt;span class="nb"&gt;cd &lt;/span&gt;nats-flow-gateway
docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.dev.yaml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;server &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run db:generate &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run db:migrate &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run seed
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fastify server with NATS integration&lt;/li&gt;
&lt;li&gt;PostgreSQL database with Drizzle ORM&lt;/li&gt;
&lt;li&gt;Health check, auth, and admin flows ready to extend&lt;/li&gt;
&lt;li&gt;Docker infrastructure for local development&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directory&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;flows/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Business logic organized by domain (auth, admin, customer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;middleware/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Request/response processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resources/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API endpoint handlers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;schemas/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Input validation definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;types/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TypeScript type safety&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  API Endpoints
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/healthcheck&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;Service health verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/admin/login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;Authentication with email/password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/admin/list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;Admin operations (requires bearer token)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Chain of Thought Tracing&lt;/strong&gt; - Every flow logs its reasoning, making debugging trivial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NATS Decoupling&lt;/strong&gt; - Services communicate without tight coupling, scale independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation at the Edge&lt;/strong&gt; - Bad data never reaches your business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript Throughout&lt;/strong&gt; - Full type safety from request to response&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're building microservices and want built-in traceability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/nats-flow-gateway.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spin it up, hit the health check endpoint, and check the logs—you'll see the flow trace immediately.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/nats-flow-gateway" rel="noopener noreferrer"&gt;quochuydev/nats-flow-gateway&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;How do you handle tracing in your distributed systems? I'd love to hear what patterns have worked for you.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>nats</category>
      <category>microservices</category>
      <category>node</category>
    </item>
    <item>
      <title>How I Built a WooCommerce Payment Gateway for Vietnamese Banks</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Wed, 14 Jan 2026 04:25:38 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-woocommerce-payment-gateway-for-vietnamese-banks-241k</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-woocommerce-payment-gateway-for-vietnamese-banks-241k</guid>
      <description>&lt;p&gt;Running an e-commerce store in Vietnam? You've probably hit the wall: international payment gateways don't support local banks, and customers abandon carts when they can't pay with their preferred method. I built a plugin that brings QR Code and Internet Banking to WooCommerce.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;For Vietnamese e-commerce stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers prefer paying via local bank transfers and QR codes&lt;/li&gt;
&lt;li&gt;International gateways (Stripe, PayPal) have limited Vietnam support&lt;/li&gt;
&lt;li&gt;Manual bank transfer verification is error-prone and time-consuming&lt;/li&gt;
&lt;li&gt;Building a payment integration from scratch requires deep API knowledge&lt;/li&gt;
&lt;li&gt;No ready-to-use WooCommerce plugin for Ngan Luong existed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: WooCommerce Ngan Luong Gateway
&lt;/h2&gt;

&lt;p&gt;A WordPress plugin that integrates Ngan Luong payment processing directly into WooCommerce checkout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Customers see familiar payment options at checkout&lt;/span&gt;
&lt;span class="c1"&gt;// QR Code, Internet Banking, ATM cards - all Vietnamese banks supported&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your customers pay with what they know. You get instant payment notifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the plugin&lt;/strong&gt; - Upload to WordPress, activate in WooCommerce&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure API credentials&lt;/strong&gt; - Enter your Ngan Luong merchant account details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customers checkout&lt;/strong&gt; - They see QR Code and Internet Banking options&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Receive payments&lt;/strong&gt; - Orders update automatically when payment confirms&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No redirect to external sites. The checkout stays on your domain with Seamless Checkout integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download the plugin&lt;/span&gt;
wget https://github.com/quochuydev/woocommerce-nganluong-gateway-plugin/raw/main/nganluong-gateway.zip

&lt;span class="c"&gt;# Or clone and zip&lt;/span&gt;
git clone https://github.com/quochuydev/woocommerce-nganluong-gateway-plugin.git
&lt;span class="nb"&gt;cd &lt;/span&gt;woocommerce-nganluong-gateway-plugin
zip &lt;span class="nt"&gt;-r&lt;/span&gt; nganluong-gateway.zip nganluong-gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in WordPress:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Plugins &amp;gt; Add New &amp;gt; Upload Plugin&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;nganluong-gateway.zip&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Activate and configure in &lt;strong&gt;WooCommerce &amp;gt; Settings &amp;gt; Payments&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported Payment Methods
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;QR Code&lt;/td&gt;
&lt;td&gt;Mobile banking scan-to-pay&lt;/td&gt;
&lt;td&gt;Quick mobile payments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet Banking&lt;/td&gt;
&lt;td&gt;Direct bank login payment&lt;/td&gt;
&lt;td&gt;Desktop customers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ATM Cards&lt;/td&gt;
&lt;td&gt;Domestic debit cards&lt;/td&gt;
&lt;td&gt;Non-credit card users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E-wallets&lt;/td&gt;
&lt;td&gt;Vietnamese digital wallets&lt;/td&gt;
&lt;td&gt;Tech-savvy customers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Seamless Checkout&lt;/strong&gt; - Customers stay on your site, no jarring redirects to third-party domains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local bank coverage&lt;/strong&gt; - Supports major Vietnamese banks that international gateways ignore&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic order updates&lt;/strong&gt; - Payment confirmation triggers WooCommerce order status changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT Licensed&lt;/strong&gt; - Free to use, modify, and distribute for your projects&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before installing, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://www.nganluong.vn/vn/about/index.html" rel="noopener noreferrer"&gt;Ngan Luong merchant account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;API credentials from the &lt;a href="https://www.nganluong.vn/vn/integrate/seamless.html" rel="noopener noreferrer"&gt;integration portal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WooCommerce installed on your WordPress site&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're running a WooCommerce store targeting Vietnamese customers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/woocommerce-nganluong-gateway-plugin.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upload the plugin and configure your Ngan Luong credentials. Your customers will thank you for the familiar payment experience.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/woocommerce-nganluong-gateway-plugin" rel="noopener noreferrer"&gt;quochuydev/woocommerce-nganluong-gateway-plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ngan Luong Docs&lt;/strong&gt;: &lt;a href="https://www.nganluong.vn/vn/integrate/seamless.html" rel="noopener noreferrer"&gt;nganluong.vn/integrate/seamless&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What payment challenges have you faced with Vietnamese e-commerce? I'd love to hear how others are handling local payment integrations.&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>php</category>
      <category>nganluong</category>
      <category>plugin</category>
    </item>
    <item>
      <title>How I Built a Real-Time Hand Tracking Platform That Runs Entirely in the Browser</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Tue, 13 Jan 2026 06:50:14 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-real-time-hand-tracking-platform-that-runs-entirely-in-the-browser-en1</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-real-time-hand-tracking-platform-that-runs-entirely-in-the-browser-en1</guid>
      <description>&lt;p&gt;You know that moment when you're demoing gesture controls and the client asks "So we need to install what exactly?" I got tired of explaining native apps and Python dependencies, so I built a computer vision platform that works right in the browser—no installs required.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Building gesture-controlled interfaces usually means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing Python, OpenCV, and a dozen dependencies&lt;/li&gt;
&lt;li&gt;Asking users to trust a native app download&lt;/li&gt;
&lt;li&gt;Wrestling with webcam permissions across different OSes&lt;/li&gt;
&lt;li&gt;Spinning up servers just to process hand movements&lt;/li&gt;
&lt;li&gt;Watching latency kill the "real-time" experience&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: VisionPipe
&lt;/h2&gt;

&lt;p&gt;What if hand tracking just worked in a browser tab?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Detect pinch gesture - thumb tip (4) to index tip (8)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thumbTip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;indexTip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thumbTip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;indexTip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's real code from the branch-opening sample—mapping a pinch gesture to control 3D animations. MediaPipe handles detection, Three.js renders the visuals.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browser loads MediaPipe&lt;/strong&gt; - No install, just a CDN import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webcam feeds landmarks&lt;/strong&gt; - 21 hand points tracked in real-time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript maps gestures&lt;/strong&gt; - Translate finger positions into actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three.js renders output&lt;/strong&gt; - Smooth 3D visualization at 60fps&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire pipeline runs client-side. Your webcam feed never leaves your device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;p&gt;Built with Next.js 16, React 19, and TypeScript. The platform includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clerk&lt;/strong&gt; for authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe&lt;/strong&gt; for payments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drizzle ORM&lt;/strong&gt; with PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fumadocs&lt;/strong&gt; for documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MediaPipe&lt;/strong&gt; for hand detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three.js&lt;/strong&gt; for 3D visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Browser (zero install):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visit the Playground → Select effect → Grant camera → Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Playground is always free and unlimited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud API:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://visionpipe3d.quochuy.dev/api/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns a shareable playground URL with a JWT token valid for 24 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Playground&lt;/th&gt;
&lt;th&gt;Cloud API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hand Landmark Detection&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time Tracking&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Via sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline Support&lt;/td&gt;
&lt;td&gt;Yes (after load)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processing Location&lt;/td&gt;
&lt;td&gt;Client-side&lt;/td&gt;
&lt;td&gt;Server-side&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate Limit&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;100 req/min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy&lt;/td&gt;
&lt;td&gt;Data stays local&lt;/td&gt;
&lt;td&gt;Processed &amp;amp; discarded&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Supported formats:&lt;/strong&gt; JPEG, PNG, WebP, GIF (up to 10MB)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser support:&lt;/strong&gt; Chrome 80+, Firefox 75+, Safari 14+, Edge 80+&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing (Cloud API)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Credits&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Per Credit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;$0.010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Growth&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;td&gt;$40&lt;/td&gt;
&lt;td&gt;$0.008&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scale&lt;/td&gt;
&lt;td&gt;20,000&lt;/td&gt;
&lt;td&gt;$150&lt;/td&gt;
&lt;td&gt;$0.0075&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;1 credit = 1 API call. Credits never expire. No monthly subscriptions—pay only for what you use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise?&lt;/strong&gt; Custom volume pricing, private endpoints, 99.9% SLA, and dedicated support available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero friction&lt;/strong&gt; - Open a URL, grant camera, start detecting. No Python, no installs, no "works on my machine"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy by default&lt;/strong&gt; - Playground processes locally. Cloud API discards images immediately after processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production ready&lt;/strong&gt; - TLS 1.3 encryption, SHA-256 key hashing, GDPR compliant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works everywhere&lt;/strong&gt; - Any modern browser with WebGL support. Any device with a webcam&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sample Projects
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Branch Opening Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An interactive visualization where pinch gestures control branch animations. The sample shows how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize the HandTracker from the VisionPipe SDK&lt;/li&gt;
&lt;li&gt;Calculate distances between landmarks (thumb tip at position 4, index tip at position 8)&lt;/li&gt;
&lt;li&gt;Map physical movements to animation parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the &lt;a href="https://visionpipe3d.quochuy.dev/docs/samples/branch-opening" rel="noopener noreferrer"&gt;samples documentation&lt;/a&gt; for the full walkthrough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Head to the &lt;a href="https://visionpipe3d.quochuy.dev/playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; and wave your hand. That's the entire onboarding.&lt;/p&gt;

&lt;p&gt;For the Cloud API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Sign in and get your API key from the Cloud Console&lt;/span&gt;
&lt;span class="c"&gt;# 2. Create a session&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://visionpipe3d.quochuy.dev/api/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer vp_live_YOUR_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes a &lt;code&gt;playgroundUrl&lt;/code&gt; you can embed or share.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/visionpipe3d" rel="noopener noreferrer"&gt;quochuydev/visionpipe3d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://visionpipe3d.quochuy.dev/docs" rel="noopener noreferrer"&gt;visionpipe3d.quochuy.dev/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Playground&lt;/strong&gt;: &lt;a href="https://visionpipe3d.quochuy.dev/playground" rel="noopener noreferrer"&gt;visionpipe3d.quochuy.dev/playground&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What gesture-based interfaces have you built or wanted to build? I'm curious what use cases people are exploring beyond the typical "air guitar" demos.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>mediapipe</category>
      <category>threejs</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Built a Zero-Dependency Technical Research Blog with Just HTML, CSS, and Markdown</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Tue, 13 Jan 2026 06:00:35 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-zero-dependency-technical-research-blog-with-just-html-css-and-markdown-kc2</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-zero-dependency-technical-research-blog-with-just-html-css-and-markdown-kc2</guid>
      <description>&lt;p&gt;Ever find yourself drowning in bookmarks, scattered notes, and half-finished documentation about technologies you're researching? I did too—until I built something simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Technical notes scattered across Notion, Google Docs, and random markdown files&lt;/li&gt;
&lt;li&gt;No central place to organize research on new technologies and platforms&lt;/li&gt;
&lt;li&gt;Setting up a blog feels like overkill—why do I need a database for markdown?&lt;/li&gt;
&lt;li&gt;Want to share knowledge but don't want to maintain complex infrastructure&lt;/li&gt;
&lt;li&gt;Diagrams and code examples should just work without plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Tech Research
&lt;/h2&gt;

&lt;p&gt;A static blog that turns a folder of markdown files into a searchable knowledge base—deployed free on GitHub Pages with zero dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add an article, run the script, push. Done.&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# My Research"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; researching/new-topic.md
./update-manifest.sh
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your research is live in seconds, not hours.&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%2Fwqueq5mflq1pfpjo76cg.png" 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%2Fwqueq5mflq1pfpjo76cg.png" alt=" " width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write in Markdown&lt;/strong&gt; - Create &lt;code&gt;.md&lt;/code&gt; files in the &lt;code&gt;researching/&lt;/code&gt; directory with GitHub-flavored syntax&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the Manifest Script&lt;/strong&gt; - &lt;code&gt;./update-manifest.sh&lt;/code&gt; scans your articles and builds the index&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push to GitHub&lt;/strong&gt; - GitHub Actions automatically deploys to GitHub Pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse and Search&lt;/strong&gt; - The SPA loads your manifest and renders articles on demand&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No build step. No Node.js. No framework churn.&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%2Fhgepbpjig4ffkm5btrl4.png" 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%2Fhgepbpjig4ffkm5btrl4.png" alt=" " width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/tech-research.git
&lt;span class="nb"&gt;cd &lt;/span&gt;tech-research
python &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8000  &lt;span class="c"&gt;# or: npx serve .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;index.html&lt;/code&gt; - The single-page application that renders everything&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;researching/&lt;/code&gt; - Drop your markdown articles here&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update-manifest.sh&lt;/code&gt; - Regenerates the article index&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;manifest.json&lt;/code&gt; - Searchable registry of all your content&lt;/li&gt;
&lt;/ul&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%2Fpf4jznsf76pbpc67s8wf.png" 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%2Fpf4jznsf76pbpc67s8wf.png" alt=" " width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics You Can Research
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blockchain&lt;/td&gt;
&lt;td&gt;Bitcoin, Solana, BSC&lt;/td&gt;
&lt;td&gt;Crypto research and earning ideas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Tools&lt;/td&gt;
&lt;td&gt;Claude Code, Moondream&lt;/td&gt;
&lt;td&gt;Evaluating AI platforms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevOps&lt;/td&gt;
&lt;td&gt;Dokploy, OAuth2-proxy, Zitadel&lt;/td&gt;
&lt;td&gt;Self-hosting infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;C4 Model, ADRs&lt;/td&gt;
&lt;td&gt;System design documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automation&lt;/td&gt;
&lt;td&gt;n8n, LiveKit&lt;/td&gt;
&lt;td&gt;Workflow and real-time tools&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero Dependencies&lt;/strong&gt; - Pure HTML/CSS/JS means nothing breaks when packages update&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mermaid Diagrams Built-in&lt;/strong&gt; - Architecture diagrams render without extra tooling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Pages = Free Hosting&lt;/strong&gt; - Push and forget, GitHub handles SSL and CDN&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown First&lt;/strong&gt; - Write naturally, let the SPA handle rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Controlled Knowledge&lt;/strong&gt; - Your research history lives in git commits&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Fork the repo and start documenting your own tech research:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/tech-research.git
&lt;span class="nb"&gt;cd &lt;/span&gt;tech-research
&lt;span class="c"&gt;# Create your first article&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"---
title: My First Research
category: Learning
---

# Topic Overview

Your research goes here..."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; researching/my-topic-overview.md
./update-manifest.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;index.html&lt;/code&gt; in your browser—your article is already there.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://quochuydev.github.io/tech-research/" rel="noopener noreferrer"&gt;https://quochuydev.github.io/tech-research/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;What's the most disorganized part of your technical learning process? I'd love to hear what topics you'd document first.&lt;/p&gt;

</description>
      <category>news</category>
      <category>research</category>
      <category>technical</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>I Built a Tool That Turns Any OpenAPI Spec Into n8n Workflow Nodes in Seconds</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Fri, 09 Jan 2026 10:18:02 +0000</pubDate>
      <link>https://forem.com/quochuydev/i-built-a-tool-that-turns-any-openapi-spec-into-n8n-workflow-nodes-in-seconds-5ecl</link>
      <guid>https://forem.com/quochuydev/i-built-a-tool-that-turns-any-openapi-spec-into-n8n-workflow-nodes-in-seconds-5ecl</guid>
      <description>&lt;p&gt;You know that feeling when you find an API with 50+ endpoints and need to wire them into your n8n workflow? Yeah, I spent way too many hours manually configuring HTTP Request nodes. So I built something to fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you use n8n for automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every API endpoint means a new HTTP Request node to configure manually&lt;/li&gt;
&lt;li&gt;Copy-pasting URLs, headers, and parameters is tedious and error-prone&lt;/li&gt;
&lt;li&gt;Complex APIs with dozens of endpoints? That's hours of clicking&lt;/li&gt;
&lt;li&gt;OpenAPI specs have all the info you need, but n8n can't read them directly&lt;/li&gt;
&lt;li&gt;One typo in the endpoint path and your workflow breaks silently&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: OpenAPI to n8n Converter
&lt;/h2&gt;

&lt;p&gt;What if you could paste an OpenAPI spec and get ready-to-use n8n nodes?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Paste your OpenAPI/Swagger spec (URL, JSON, or YAML)
2. Select the endpoints you need
3. Copy → Paste into n8n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Minutes of manual work compressed into seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Provide your spec&lt;/strong&gt; - Paste a URL, upload a file, or paste raw JSON/YAML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse &amp;amp; Convert&lt;/strong&gt; - The tool reads your OpenAPI 3.x or Swagger 2.0 spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cherry-pick endpoints&lt;/strong&gt; - Select only the endpoints you actually need&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy to n8n&lt;/strong&gt; - One click copies the node config, paste it into your workflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No installation. No signup. Just open the browser and convert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://n8n-openapi.vercel.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interface gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL fetching&lt;/strong&gt; - Point to any public OpenAPI spec URL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File upload&lt;/strong&gt; - Drop your local spec files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct paste&lt;/strong&gt; - Copy-paste spec content directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Popular APIs&lt;/strong&gt; - Pre-configured examples (GitHub, Stripe, Slack, Discord, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Features at a Glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Multi-format support&lt;/td&gt;
&lt;td&gt;OpenAPI 3.x &amp;amp; Swagger 2.0, JSON &amp;amp; YAML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selective conversion&lt;/td&gt;
&lt;td&gt;Pick specific endpoints, skip the rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Base URL override&lt;/td&gt;
&lt;td&gt;Point to staging, production, or localhost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser persistence&lt;/td&gt;
&lt;td&gt;Your conversions are saved automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-tab workflow&lt;/td&gt;
&lt;td&gt;Manage multiple API conversions at once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One-click copy&lt;/td&gt;
&lt;td&gt;Clipboard-ready n8n node configurations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero friction&lt;/strong&gt; - Browser-based, no install, no account required&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec as source of truth&lt;/strong&gt; - OpenAPI already documents everything; this just transforms it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective imports&lt;/strong&gt; - Don't bloat your workflow with endpoints you won't use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time savings&lt;/strong&gt; - What took 30 minutes of clicking now takes 30 seconds&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Head to the converter and try it with one of the pre-loaded APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://n8n-openapi.vercel.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try converting the GitHub or Stripe API spec first—they're already in the Popular APIs section.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/n8n-openapi" rel="noopener noreferrer"&gt;quochuydev/n8n-openapi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://n8n-openapi.vercel.app" rel="noopener noreferrer"&gt;n8n-openapi.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;How do you currently handle integrating complex APIs into n8n? Would love to hear if there are endpoints or specs that break the converter—PRs welcome!&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Built a Custom Login UI for ZITADEL That Actually Looks Good</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Tue, 06 Jan 2026 03:39:49 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-custom-login-ui-for-zitadel-that-actually-looks-good-4nne</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-custom-login-ui-for-zitadel-that-actually-looks-good-4nne</guid>
      <description>&lt;p&gt;Ever tried customizing ZITADEL's default login page and realized you're stuck with their hosted UI? I needed full control over the login experience—branding, flows, languages—so I built a drop-in replacement using Next.js that speaks OIDC natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;ZITADEL is great for identity management, but the default login UI has limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customization options are restricted to themes and basic branding&lt;/li&gt;
&lt;li&gt;No control over the actual login flow UX&lt;/li&gt;
&lt;li&gt;Adding custom pages (passkeys, TOTP setup) requires workarounds&lt;/li&gt;
&lt;li&gt;Multi-language support needs external tooling&lt;/li&gt;
&lt;li&gt;Self-hosted instances still look like hosted ZITADEL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Custom Login UI
&lt;/h2&gt;

&lt;p&gt;A Next.js app that replaces ZITADEL's login interface entirely. Same OIDC flows, your design.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Your app redirects to your login UI, not ZITADEL's&lt;/span&gt;
OIDC Authorization → Your Custom UI → ZITADEL API → Token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full control over every screen: login, register, password reset, TOTP, passkeys.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;OIDC-compliant&lt;/strong&gt; - Implements standard authorization flows, works with any OIDC client&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service user auth&lt;/strong&gt; - Talks to ZITADEL's API using service account tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;i18n built-in&lt;/strong&gt; - Multi-language support via next-translate out of the box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern stack&lt;/strong&gt; - Next.js 14 App Router, TypeScript, Tailwind CSS, React Hook Form + Zod&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your existing apps just point to this UI instead of ZITADEL's hosted login.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/zitadel-login-ui.git
&lt;span class="nb"&gt;cd &lt;/span&gt;zitadel-login-ui
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
yarn &lt;span class="nb"&gt;install
&lt;/span&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Login page&lt;/strong&gt; - Username/password authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registration&lt;/strong&gt; - New user signup flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password reset&lt;/strong&gt; - Self-service password recovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TOTP setup&lt;/strong&gt; - Two-factor authentication with QR codes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passkeys&lt;/strong&gt; - WebAuthn/FIDO2 passwordless login&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication Routes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User authentication&lt;/td&gt;
&lt;td&gt;Username/password, remember me&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/register&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New account creation&lt;/td&gt;
&lt;td&gt;Form validation, email verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/password&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Password management&lt;/td&gt;
&lt;td&gt;Reset flow, change password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/totp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2FA setup&lt;/td&gt;
&lt;td&gt;QR code generation, backup codes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/passkeys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Passwordless auth&lt;/td&gt;
&lt;td&gt;WebAuthn registration and login&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/account&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User profile&lt;/td&gt;
&lt;td&gt;Manage account settings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Environment Configuration
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APP_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your login UI URL (e.g., &lt;code&gt;http://localhost:3333&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ZITADEL_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your ZITADEL instance URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ZITADEL_SERVICE_USER_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Service user ID from ZITADEL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ZITADEL_SERVICE_USER_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API token for service user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RESEND_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Optional: for email delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Setting Up ZITADEL Service User
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;https://YOUR_ZITADEL/ui/console/instance/members&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a service user with &lt;code&gt;IAM_OWNER&lt;/code&gt; role&lt;/li&gt;
&lt;li&gt;Generate a personal access token&lt;/li&gt;
&lt;li&gt;Add the user ID and token to your &lt;code&gt;.env&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Full design control&lt;/strong&gt; - Every pixel is yours, not ZITADEL's theme system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard OIDC&lt;/strong&gt; - Any app expecting OIDC works without changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production-ready stack&lt;/strong&gt; - Next.js 14, TypeScript, Tailwind—battle-tested&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;i18n from day one&lt;/strong&gt; - Add languages by dropping translation files in &lt;code&gt;/locales&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern auth methods&lt;/strong&gt; - Passkeys and TOTP built in, not bolted on&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Live demo: &lt;a href="https://zitadel-login-ui-v2.vercel.app" rel="noopener noreferrer"&gt;zitadel-login-ui-v2.vercel.app&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/zitadel-login-ui.git
&lt;span class="nb"&gt;cd &lt;/span&gt;zitadel-login-ui
yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with the login page, then explore the TOTP and passkey flows to see the full auth experience.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/zitadel-login-ui" rel="noopener noreferrer"&gt;quochuydev/zitadel-login-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://zitadel-login-ui-v2.vercel.app" rel="noopener noreferrer"&gt;zitadel-login-ui-v2.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Are you using ZITADEL's default UI or did you build something custom? I'd love to hear how others handle login customization.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>zitadel</category>
      <category>oidc</category>
      <category>oauth</category>
    </item>
    <item>
      <title>How I Built a One-Command Observability Stack for Dokploy</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Tue, 06 Jan 2026 03:26:55 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-one-command-observability-stack-for-dokploy-4ak0</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-one-command-observability-stack-for-dokploy-4ak0</guid>
      <description>&lt;p&gt;Ever deployed an app to production and then realized you have zero visibility into what's happening? No logs, no traces, no idea why users are complaining. I got tired of stitching together monitoring tools from scratch every time, so I built a complete observability stack that just works with Dokploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Setting up proper observability is painful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grafana, Tempo, Loki, and collectors each need separate configuration&lt;/li&gt;
&lt;li&gt;Getting them to talk to each other requires networking magic&lt;/li&gt;
&lt;li&gt;OpenTelemetry setup has a steep learning curve&lt;/li&gt;
&lt;li&gt;Most tutorials assume you have infinite time to debug YAML&lt;/li&gt;
&lt;li&gt;Dokploy's Docker network adds another layer of complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Dokploy Grafana Compose
&lt;/h2&gt;

&lt;p&gt;A pre-configured monitoring stack that deploys alongside your Dokploy apps. Four services, one &lt;code&gt;docker-compose up&lt;/code&gt;, done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# All four services on dokploy-network, pre-wired&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;alloy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="c1"&gt;# Collects traces, logs, metrics&lt;/span&gt;
  &lt;span class="na"&gt;tempo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="c1"&gt;# Stores traces&lt;/span&gt;
  &lt;span class="na"&gt;loki&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="c1"&gt;# Stores logs&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Visualizes everything&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your apps send telemetry to Alloy, and everything flows to the right place automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Alloy receives data&lt;/strong&gt; - OTLP receiver on port 4317/4318 accepts traces, logs, and metrics from your apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data routes automatically&lt;/strong&gt; - Traces go to Tempo, logs go to Loki, metrics go to Prometheus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana correlates everything&lt;/strong&gt; - See a slow request? Jump from trace to related logs instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faro captures frontend&lt;/strong&gt; - Browser-side Real User Monitoring included on port 12347&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No configuration files to edit. Just deploy and instrument your apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/dokploy-grafana-compose.git
&lt;span class="nb"&gt;cd &lt;/span&gt;dokploy-grafana-compose
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This deploys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grafana Alloy v1.11.3&lt;/strong&gt; - Unified telemetry collector with OTLP and Faro receivers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tempo v2.9.0&lt;/strong&gt; - Distributed tracing backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loki v3.5.8&lt;/strong&gt; - Log aggregation system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana v12.2.1&lt;/strong&gt; - Pre-provisioned dashboards for traces and logs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stack Components
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alloy&lt;/td&gt;
&lt;td&gt;Data Collection&lt;/td&gt;
&lt;td&gt;Receives OTLP (4317/4318) and Faro (12347) telemetry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tempo&lt;/td&gt;
&lt;td&gt;Trace Storage&lt;/td&gt;
&lt;td&gt;Stores distributed traces, enables TraceQL queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loki&lt;/td&gt;
&lt;td&gt;Log Storage&lt;/td&gt;
&lt;td&gt;Aggregates logs, enables LogQL queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;Visualization&lt;/td&gt;
&lt;td&gt;Correlates traces + logs + metrics in one UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Instrumenting Your App
&lt;/h2&gt;

&lt;p&gt;The repo includes a Node.js example. Key dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node &lt;span class="se"&gt;\&lt;/span&gt;
  @opentelemetry/exporter-trace-otlp-http @opentelemetry/exporter-logs-otlp-http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then initialize the SDK pointing to Alloy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;traceExporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OTLPTraceExporter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://alloy:4318/v1/traces&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logExporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OTLPLogExporter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://alloy:4318/v1/logs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the example: &lt;code&gt;(cd examples/node &amp;amp;&amp;amp; pnpm start)&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero configuration&lt;/strong&gt; - All services pre-wired on &lt;code&gt;dokploy-network&lt;/code&gt;, just deploy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production versions&lt;/strong&gt; - Uses stable releases of Grafana ecosystem tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-restart&lt;/strong&gt; - All containers use &lt;code&gt;unless-stopped&lt;/code&gt; restart policy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard protocols&lt;/strong&gt; - OTLP means any OpenTelemetry-compatible app works&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend monitoring included&lt;/strong&gt; - Faro receiver captures browser telemetry out of the box&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're running Dokploy and want observability without the setup headache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/quochuydev/dokploy-grafana-compose.git
&lt;span class="nb"&gt;cd &lt;/span&gt;dokploy-grafana-compose
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Grafana at &lt;code&gt;http://localhost:3000&lt;/code&gt; and run the Node.js example to see traces flowing in.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/dokploy-grafana-compose" rel="noopener noreferrer"&gt;quochuydev/dokploy-grafana-compose&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://grafana.com/docs/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt; | &lt;a href="https://opentelemetry.io/docs/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt; | &lt;a href="https://dokploy.com/" rel="noopener noreferrer"&gt;Dokploy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;How do you handle observability in your Dokploy deployments? Would love to hear what stacks others are using.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>monitoring</category>
      <category>grafana</category>
      <category>docker</category>
    </item>
    <item>
      <title>How I Built a Plan-Based Development Workflow for Claude Code</title>
      <dc:creator>Huy Pham</dc:creator>
      <pubDate>Thu, 01 Jan 2026 02:45:29 +0000</pubDate>
      <link>https://forem.com/quochuydev/how-i-built-a-plan-based-development-workflow-for-claude-code-3iel</link>
      <guid>https://forem.com/quochuydev/how-i-built-a-plan-based-development-workflow-for-claude-code-3iel</guid>
      <description>&lt;p&gt;Ever started a feature, gotten halfway through, then realized you forgot a critical dependency? Or had Claude Code build something, only to realize the tasks were done in the wrong order? I got tired of managing complex features in my head, so I built a plugin that brings structured planning directly into Claude Code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;When building features with AI assistance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You explain the feature, Claude starts coding, but forgets earlier context&lt;/li&gt;
&lt;li&gt;Multi-step tasks get jumbled—tests written before the code they test&lt;/li&gt;
&lt;li&gt;You lose track of what's done vs. what's pending&lt;/li&gt;
&lt;li&gt;Dependencies between tasks aren't respected (middleware before routes, etc.)&lt;/li&gt;
&lt;li&gt;Context switching kills momentum—you forget where you left off&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Plan-Mode
&lt;/h2&gt;

&lt;p&gt;What if you could define your entire feature as a dependency graph, and have Claude execute it step-by-step?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You:    /plan JWT Authentication
Claude: Creates .claude/plans/jwt-authentication.md with 6 tasks
You:    /plan-execute jwt-authentication
Claude: Executes next available task respecting dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Structured planning meets AI execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a plan&lt;/strong&gt; - &lt;code&gt;/plan &amp;lt;feature&amp;gt;&lt;/code&gt; generates a YAML-based plan with tasks and dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track progress&lt;/strong&gt; - &lt;code&gt;/plan&lt;/code&gt; shows all plans with completion metrics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute systematically&lt;/strong&gt; - &lt;code&gt;/plan-execute &amp;lt;name&amp;gt;&lt;/code&gt; runs the next available task&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual control&lt;/strong&gt; - &lt;code&gt;/plan-update &amp;lt;name&amp;gt; [id] [status]&lt;/code&gt; lets you adjust as needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Plans live in your repo at &lt;code&gt;.claude/plans/&lt;/code&gt;, versioned with your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add quochuydev/cc-plan-mode
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;plan-mode@cc-plan-mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt; command - View and create structured plans&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan-execute&lt;/code&gt; command - Run tasks sequentially with dependency awareness&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan-update&lt;/code&gt; command - Manually adjust task status&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/plan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all plans with progress&lt;/td&gt;
&lt;td&gt;Shows completion % per plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/plan &amp;lt;desc&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create new plan&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/plan user authentication&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/plan-execute &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Execute next task&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/plan-execute auth-system&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/plan-update &amp;lt;name&amp;gt; [id] [status]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update task status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/plan-update auth-system 3 completed&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Plan Format
&lt;/h2&gt;

&lt;p&gt;Plans use YAML frontmatter for clean structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jwt-authentication&lt;/span&gt;
&lt;span class="na"&gt;overview&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add JWT-based authentication to the API&lt;/span&gt;
&lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install jsonwebtoken and bcrypt dependencies&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pending&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create User model with password hashing&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pending&lt;/span&gt;
    &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Implement auth middleware&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pending&lt;/span&gt;
    &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dependency awareness&lt;/strong&gt; - Tasks execute in the right order, always&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent state&lt;/strong&gt; - Plans survive across sessions, stored in your repo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear visibility&lt;/strong&gt; - See exactly what's done, what's next, what's blocked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-native execution&lt;/strong&gt; - Claude understands context from the plan file&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you're building multi-step features with Claude Code and want more structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add quochuydev/cc-plan-mode
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;plan-mode@cc-plan-mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;/plan my-feature&lt;/code&gt; and watch it break down your feature into manageable, ordered tasks.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/quochuydev/cc-plan-mode" rel="noopener noreferrer"&gt;quochuydev/cc-plan-mode&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;How do you currently manage complex, multi-step features when working with AI assistants? I'd love to hear what workflows have worked for your team.&lt;/p&gt;

</description>
      <category>claudeai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>workflow</category>
    </item>
  </channel>
</rss>
