<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Digital Craft Workshop</title>
    <description>The latest articles on DEV Community by Digital Craft Workshop (@danielrusnok).</description>
    <link>https://dev.to/danielrusnok</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F277448%2Fdf127f3b-f0f6-45fe-b25e-1608deb963fe.png</url>
      <title>DEV Community: Digital Craft Workshop</title>
      <link>https://dev.to/danielrusnok</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danielrusnok"/>
    <language>en</language>
    <item>
      <title>How I Wired Persistent Memory Into Every Claude Code Session</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Fri, 24 Jul 2026 15:06:27 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-i-wired-persistent-memory-into-every-claude-code-session-4b1h</link>
      <guid>https://dev.to/danielrusnok/how-i-wired-persistent-memory-into-every-claude-code-session-4b1h</guid>
      <description>&lt;p&gt;&lt;em&gt;Not&amp;nbsp;a&amp;nbsp;member?&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/membership" rel="noopener noreferrer"&gt;Use&amp;nbsp;this&amp;nbsp;link.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A&amp;nbsp;memory&amp;nbsp;you&amp;nbsp;have&amp;nbsp;to&amp;nbsp;remember&amp;nbsp;to&amp;nbsp;use&amp;nbsp;is&amp;nbsp;not&amp;nbsp;memory.&amp;nbsp;It&amp;nbsp;is&amp;nbsp;a&amp;nbsp;database&amp;nbsp;with&amp;nbsp;a&amp;nbsp;search&amp;nbsp;bar.&lt;/p&gt;

&lt;p&gt;That&amp;nbsp;was&amp;nbsp;the&amp;nbsp;gap.&amp;nbsp;After&amp;nbsp;eight&amp;nbsp;hours&amp;nbsp;of&amp;nbsp;a&amp;nbsp;day&amp;nbsp;job,&amp;nbsp;on&amp;nbsp;the&amp;nbsp;evening&amp;nbsp;shift&amp;nbsp;where&amp;nbsp;I&amp;nbsp;do&amp;nbsp;my&amp;nbsp;own&amp;nbsp;building,&amp;nbsp;I&amp;nbsp;never&amp;nbsp;remembered&amp;nbsp;the&amp;nbsp;search&amp;nbsp;bar&amp;nbsp;was&amp;nbsp;there.&amp;nbsp;I&amp;nbsp;gave&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;that&amp;nbsp;memory&amp;nbsp;last&amp;nbsp;month:&amp;nbsp;a&amp;nbsp;&lt;code&gt;mem0_search&lt;/code&gt;&amp;nbsp;tool.&amp;nbsp;Then&amp;nbsp;I&amp;nbsp;spent&amp;nbsp;a&amp;nbsp;month&amp;nbsp;barely&amp;nbsp;using&amp;nbsp;it,&amp;nbsp;because&amp;nbsp;using&amp;nbsp;it&amp;nbsp;meant&amp;nbsp;remembering&amp;nbsp;it&amp;nbsp;existed.&lt;/p&gt;

&lt;p&gt;So&amp;nbsp;I&amp;nbsp;spent&amp;nbsp;one&amp;nbsp;evening&amp;nbsp;wiring&amp;nbsp;it&amp;nbsp;into&amp;nbsp;the&amp;nbsp;session&amp;nbsp;lifecycle&amp;nbsp;itself.&amp;nbsp;Now&amp;nbsp;recall&amp;nbsp;happens&amp;nbsp;when&amp;nbsp;a&amp;nbsp;session&amp;nbsp;opens&amp;nbsp;and&amp;nbsp;capture&amp;nbsp;happens&amp;nbsp;when&amp;nbsp;it&amp;nbsp;closes&amp;nbsp;—&amp;nbsp;both&amp;nbsp;without&amp;nbsp;me.&amp;nbsp;Claude&amp;nbsp;walks&amp;nbsp;into&amp;nbsp;every&amp;nbsp;session&amp;nbsp;already&amp;nbsp;knowing&amp;nbsp;what&amp;nbsp;we&amp;nbsp;decided&amp;nbsp;last&amp;nbsp;week,&amp;nbsp;and&amp;nbsp;closes&amp;nbsp;it&amp;nbsp;having&amp;nbsp;written&amp;nbsp;down&amp;nbsp;what&amp;nbsp;we&amp;nbsp;decided&amp;nbsp;today.&lt;/p&gt;

&lt;p&gt;I&amp;nbsp;have&amp;nbsp;not&amp;nbsp;typed&amp;nbsp;"search&amp;nbsp;your&amp;nbsp;memory"&amp;nbsp;in&amp;nbsp;a&amp;nbsp;month.&lt;/p&gt;

&lt;p&gt;Three&amp;nbsp;hooks&amp;nbsp;do&amp;nbsp;it.&amp;nbsp;Here&amp;nbsp;is&amp;nbsp;the&amp;nbsp;wiring.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt;&amp;nbsp;A&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;shell-command&amp;nbsp;hook&amp;nbsp;cannot&amp;nbsp;call&amp;nbsp;an&amp;nbsp;MCP&amp;nbsp;tool.&amp;nbsp;It&amp;nbsp;can&amp;nbsp;only&amp;nbsp;inject&amp;nbsp;text.&amp;nbsp;So&amp;nbsp;my&amp;nbsp;SessionStart&amp;nbsp;hook&amp;nbsp;does&amp;nbsp;not&amp;nbsp;&lt;em&gt;do&lt;/em&gt;&amp;nbsp;the&amp;nbsp;recall&amp;nbsp;—&amp;nbsp;it&amp;nbsp;injects&amp;nbsp;an&amp;nbsp;instruction&amp;nbsp;telling&amp;nbsp;Claude&amp;nbsp;to&amp;nbsp;do&amp;nbsp;it,&amp;nbsp;with&amp;nbsp;the&amp;nbsp;tools&amp;nbsp;Claude&amp;nbsp;already&amp;nbsp;has.&amp;nbsp;SessionEnd&amp;nbsp;spawns&amp;nbsp;a&amp;nbsp;detached&amp;nbsp;Python&amp;nbsp;process&amp;nbsp;that&amp;nbsp;extracts&amp;nbsp;the&amp;nbsp;session's&amp;nbsp;decisions&amp;nbsp;with&amp;nbsp;Gemini&amp;nbsp;and&amp;nbsp;writes&amp;nbsp;them&amp;nbsp;to&amp;nbsp;Pinecone,&amp;nbsp;after&amp;nbsp;my&amp;nbsp;terminal&amp;nbsp;is&amp;nbsp;already&amp;nbsp;closed.&amp;nbsp;Three&amp;nbsp;scripts,&amp;nbsp;around&amp;nbsp;250&amp;nbsp;lines,&amp;nbsp;zero&amp;nbsp;ongoing&amp;nbsp;effort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The&amp;nbsp;realization:&amp;nbsp;hooks&amp;nbsp;inject,&amp;nbsp;they&amp;nbsp;don't&amp;nbsp;execute
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;first&amp;nbsp;thing&amp;nbsp;I&amp;nbsp;got&amp;nbsp;wrong&amp;nbsp;was&amp;nbsp;assuming&amp;nbsp;a&amp;nbsp;hook&amp;nbsp;could&amp;nbsp;run&amp;nbsp;&lt;code&gt;mem0_search&lt;/code&gt;&amp;nbsp;itself&amp;nbsp;and&amp;nbsp;paste&amp;nbsp;the&amp;nbsp;result&amp;nbsp;into&amp;nbsp;context.&lt;/p&gt;

&lt;p&gt;It&amp;nbsp;can't&amp;nbsp;—&amp;nbsp;not&amp;nbsp;the&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;hook&amp;nbsp;I&amp;nbsp;am&amp;nbsp;using.&amp;nbsp;A&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;is&amp;nbsp;a&amp;nbsp;shell&amp;nbsp;command,&amp;nbsp;which&amp;nbsp;is&amp;nbsp;what&amp;nbsp;all&amp;nbsp;three&amp;nbsp;of&amp;nbsp;mine&amp;nbsp;are,&amp;nbsp;cannot&amp;nbsp;call&amp;nbsp;an&amp;nbsp;MCP&amp;nbsp;tool.&amp;nbsp;It&amp;nbsp;has&amp;nbsp;no&amp;nbsp;MCP&amp;nbsp;client.&amp;nbsp;The&amp;nbsp;only&amp;nbsp;thing&amp;nbsp;it&amp;nbsp;can&amp;nbsp;hand&amp;nbsp;back&amp;nbsp;is&amp;nbsp;text:&amp;nbsp;a&amp;nbsp;small&amp;nbsp;JSON&amp;nbsp;object&amp;nbsp;with&amp;nbsp;an&amp;nbsp;&lt;code&gt;additionalContext&lt;/code&gt;&amp;nbsp;field.&lt;/p&gt;

&lt;p&gt;(Newer&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;does&amp;nbsp;have&amp;nbsp;an&amp;nbsp;&lt;code&gt;mcp_tool&lt;/code&gt;&amp;nbsp;hook&amp;nbsp;type&amp;nbsp;that&amp;nbsp;calls&amp;nbsp;a&amp;nbsp;tool&amp;nbsp;directly.&amp;nbsp;But&amp;nbsp;a&amp;nbsp;blind,&amp;nbsp;unconditional&amp;nbsp;tool&amp;nbsp;call&amp;nbsp;is&amp;nbsp;not&amp;nbsp;what&amp;nbsp;I&amp;nbsp;want&amp;nbsp;here&amp;nbsp;—&amp;nbsp;I&amp;nbsp;want&amp;nbsp;Claude&amp;nbsp;to&amp;nbsp;decide&amp;nbsp;whether&amp;nbsp;and&amp;nbsp;how&amp;nbsp;to&amp;nbsp;recall,&amp;nbsp;with&amp;nbsp;judgment.&amp;nbsp;A&amp;nbsp;command&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;injects&amp;nbsp;an&amp;nbsp;instruction&amp;nbsp;gives&amp;nbsp;me&amp;nbsp;exactly&amp;nbsp;that.)&lt;/p&gt;

&lt;p&gt;That&amp;nbsp;sounds&amp;nbsp;like&amp;nbsp;a&amp;nbsp;wall.&amp;nbsp;It&amp;nbsp;is&amp;nbsp;actually&amp;nbsp;the&amp;nbsp;design.&lt;/p&gt;

&lt;p&gt;A&amp;nbsp;shell-command&amp;nbsp;hook&amp;nbsp;does&amp;nbsp;not&amp;nbsp;perform&amp;nbsp;the&amp;nbsp;recall.&amp;nbsp;It&amp;nbsp;writes&amp;nbsp;a&amp;nbsp;prompt.&amp;nbsp;It&amp;nbsp;injects&amp;nbsp;an&amp;nbsp;instruction&amp;nbsp;—&amp;nbsp;"before&amp;nbsp;you&amp;nbsp;answer,&amp;nbsp;search&amp;nbsp;your&amp;nbsp;memory&amp;nbsp;for&amp;nbsp;X"&amp;nbsp;—&amp;nbsp;and&amp;nbsp;Claude,&amp;nbsp;seeing&amp;nbsp;that&amp;nbsp;instruction&amp;nbsp;sitting&amp;nbsp;in&amp;nbsp;context,&amp;nbsp;runs&amp;nbsp;the&amp;nbsp;search&amp;nbsp;with&amp;nbsp;the&amp;nbsp;&lt;code&gt;mem0_search&lt;/code&gt;&amp;nbsp;tool&amp;nbsp;it&amp;nbsp;already&amp;nbsp;has.&amp;nbsp;&lt;strong&gt;The&amp;nbsp;hook&amp;nbsp;is&amp;nbsp;a&amp;nbsp;prompt-writer.&amp;nbsp;Claude&amp;nbsp;is&amp;nbsp;still&amp;nbsp;the&amp;nbsp;one&amp;nbsp;doing&amp;nbsp;the&amp;nbsp;work,&amp;nbsp;with&amp;nbsp;full&amp;nbsp;judgment&amp;nbsp;about&amp;nbsp;how&amp;nbsp;to&amp;nbsp;do&amp;nbsp;it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;that&amp;nbsp;clicked,&amp;nbsp;all&amp;nbsp;three&amp;nbsp;hooks&amp;nbsp;got&amp;nbsp;simple.&amp;nbsp;Two&amp;nbsp;of&amp;nbsp;them&amp;nbsp;write&amp;nbsp;recall&amp;nbsp;instructions.&amp;nbsp;One&amp;nbsp;of&amp;nbsp;them&amp;nbsp;captures.&amp;nbsp;None&amp;nbsp;of&amp;nbsp;them&amp;nbsp;touch&amp;nbsp;mem0&amp;nbsp;directly&amp;nbsp;except&amp;nbsp;the&amp;nbsp;last&amp;nbsp;—&amp;nbsp;and&amp;nbsp;even&amp;nbsp;that&amp;nbsp;one&amp;nbsp;runs&amp;nbsp;outside&amp;nbsp;the&amp;nbsp;session&amp;nbsp;entirely.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fizf4izaiipuyiubio5j0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fizf4izaiipuyiubio5j0.jpg" alt="A hook that runs a command hands Claude a static fact; a hook that injects an instruction hands Claude a task" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hook&amp;nbsp;1:&amp;nbsp;recall&amp;nbsp;the&amp;nbsp;moment&amp;nbsp;a&amp;nbsp;session&amp;nbsp;opens
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;SessionStart&lt;/code&gt;&amp;nbsp;fires&amp;nbsp;when&amp;nbsp;I&amp;nbsp;open&amp;nbsp;Claude&amp;nbsp;Code.&amp;nbsp;My&amp;nbsp;hook&amp;nbsp;here&amp;nbsp;is&amp;nbsp;a&amp;nbsp;bash&amp;nbsp;script&amp;nbsp;that&amp;nbsp;does&amp;nbsp;one&amp;nbsp;cheap&amp;nbsp;thing:&amp;nbsp;look&amp;nbsp;at&amp;nbsp;the&amp;nbsp;current&amp;nbsp;directory,&amp;nbsp;and&amp;nbsp;if&amp;nbsp;it&amp;nbsp;is&amp;nbsp;one&amp;nbsp;of&amp;nbsp;my&amp;nbsp;projects,&amp;nbsp;inject&amp;nbsp;a&amp;nbsp;recall&amp;nbsp;instruction&amp;nbsp;scoped&amp;nbsp;to&amp;nbsp;that&amp;nbsp;project.&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="nv"&gt;BASENAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# ...match BASENAME against my known project slugs, set $SLUG...&lt;/span&gt;

&lt;span class="nv"&gt;MSG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[session-context] cwd is project '&lt;/span&gt;&lt;span class="nv"&gt;$SLUG&lt;/span&gt;&lt;span class="s2"&gt;'. Before answering the
first prompt, call mem0_search with query=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$SLUG&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; for past
decisions, preferences, and in-flight work."&lt;/span&gt;

jq &lt;span class="nt"&gt;-nc&lt;/span&gt; &lt;span class="nt"&gt;--arg&lt;/span&gt; msg &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MSG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'{hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: $msg}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That&amp;nbsp;is&amp;nbsp;the&amp;nbsp;whole&amp;nbsp;mechanism.&amp;nbsp;The&amp;nbsp;JSON&amp;nbsp;goes&amp;nbsp;back&amp;nbsp;to&amp;nbsp;Claude&amp;nbsp;Code,&amp;nbsp;the&amp;nbsp;&lt;code&gt;additionalContext&lt;/code&gt;&amp;nbsp;string&amp;nbsp;lands&amp;nbsp;in&amp;nbsp;the&amp;nbsp;session&amp;nbsp;as&amp;nbsp;if&amp;nbsp;it&amp;nbsp;had&amp;nbsp;always&amp;nbsp;been&amp;nbsp;there,&amp;nbsp;and&amp;nbsp;because&amp;nbsp;the&amp;nbsp;instruction&amp;nbsp;is&amp;nbsp;explicit&amp;nbsp;and&amp;nbsp;imperative,&amp;nbsp;Claude&amp;nbsp;runs&amp;nbsp;the&amp;nbsp;search&amp;nbsp;before&amp;nbsp;it&amp;nbsp;answers&amp;nbsp;my&amp;nbsp;first&amp;nbsp;message.&amp;nbsp;By&amp;nbsp;the&amp;nbsp;time&amp;nbsp;I&amp;nbsp;have&amp;nbsp;typed&amp;nbsp;anything,&amp;nbsp;the&amp;nbsp;recall&amp;nbsp;results&amp;nbsp;are&amp;nbsp;already&amp;nbsp;in&amp;nbsp;context.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;scoping&amp;nbsp;is&amp;nbsp;deterministic&amp;nbsp;on&amp;nbsp;purpose.&amp;nbsp;The&amp;nbsp;script&amp;nbsp;matches&amp;nbsp;the&amp;nbsp;folder&amp;nbsp;name&amp;nbsp;against&amp;nbsp;a&amp;nbsp;hard-coded&amp;nbsp;list&amp;nbsp;of&amp;nbsp;my&amp;nbsp;project&amp;nbsp;slugs&amp;nbsp;—&amp;nbsp;no&amp;nbsp;LLM&amp;nbsp;call&amp;nbsp;inside&amp;nbsp;the&amp;nbsp;hook,&amp;nbsp;no&amp;nbsp;latency,&amp;nbsp;no&amp;nbsp;cost.&amp;nbsp;In&amp;nbsp;a&amp;nbsp;project&amp;nbsp;folder&amp;nbsp;it&amp;nbsp;recalls&amp;nbsp;that&amp;nbsp;project.&amp;nbsp;In&amp;nbsp;a&amp;nbsp;random&amp;nbsp;folder&amp;nbsp;it&amp;nbsp;falls&amp;nbsp;back&amp;nbsp;to&amp;nbsp;a&amp;nbsp;generic&amp;nbsp;recall&amp;nbsp;keyed&amp;nbsp;on&amp;nbsp;the&amp;nbsp;folder&amp;nbsp;name.&amp;nbsp;I&amp;nbsp;gave&amp;nbsp;the&amp;nbsp;hook&amp;nbsp;a&amp;nbsp;five-second&amp;nbsp;timeout,&amp;nbsp;and&amp;nbsp;it&amp;nbsp;never&amp;nbsp;comes&amp;nbsp;close&amp;nbsp;to&amp;nbsp;it.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;payoff&amp;nbsp;shows&amp;nbsp;up&amp;nbsp;as&amp;nbsp;a&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;friction&amp;nbsp;quietly&amp;nbsp;disappearing.&amp;nbsp;I&amp;nbsp;no&amp;nbsp;longer&amp;nbsp;re-explain&amp;nbsp;decisions&amp;nbsp;I&amp;nbsp;already&amp;nbsp;made&amp;nbsp;—&amp;nbsp;which&amp;nbsp;database&amp;nbsp;a&amp;nbsp;project&amp;nbsp;uses,&amp;nbsp;why&amp;nbsp;an&amp;nbsp;endpoint&amp;nbsp;is&amp;nbsp;shaped&amp;nbsp;the&amp;nbsp;way&amp;nbsp;it&amp;nbsp;is,&amp;nbsp;the&amp;nbsp;API&amp;nbsp;quirk&amp;nbsp;that&amp;nbsp;cost&amp;nbsp;me&amp;nbsp;an&amp;nbsp;evening&amp;nbsp;last&amp;nbsp;month.&amp;nbsp;The&amp;nbsp;recall&amp;nbsp;puts&amp;nbsp;those&amp;nbsp;back&amp;nbsp;in&amp;nbsp;front&amp;nbsp;of&amp;nbsp;Claude&amp;nbsp;before&amp;nbsp;its&amp;nbsp;first&amp;nbsp;answer,&amp;nbsp;so&amp;nbsp;it&amp;nbsp;builds&amp;nbsp;on&amp;nbsp;them&amp;nbsp;instead&amp;nbsp;of&amp;nbsp;slowly&amp;nbsp;reinventing&amp;nbsp;them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note: if you'd rather have this whole setup broken into a few short, copy-paste steps in your inbox, I turned it into &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series. Back to the hooks.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hook&amp;nbsp;2:&amp;nbsp;catch&amp;nbsp;the&amp;nbsp;project&amp;nbsp;I&amp;nbsp;name&amp;nbsp;mid-conversation
&lt;/h2&gt;

&lt;p&gt;SessionStart&amp;nbsp;covers&amp;nbsp;where&amp;nbsp;I&amp;nbsp;am&amp;nbsp;sitting.&amp;nbsp;But&amp;nbsp;half&amp;nbsp;my&amp;nbsp;prompts&amp;nbsp;mention&amp;nbsp;a&amp;nbsp;&lt;em&gt;different&lt;/em&gt;&amp;nbsp;project&amp;nbsp;than&amp;nbsp;the&amp;nbsp;folder&amp;nbsp;I&amp;nbsp;am&amp;nbsp;in&amp;nbsp;—&amp;nbsp;"wait,&amp;nbsp;how&amp;nbsp;did&amp;nbsp;I&amp;nbsp;handle&amp;nbsp;inbound&amp;nbsp;email&amp;nbsp;in&amp;nbsp;subhook?"&lt;/p&gt;

&lt;p&gt;So&amp;nbsp;the&amp;nbsp;second&amp;nbsp;hook&amp;nbsp;runs&amp;nbsp;on&amp;nbsp;&lt;code&gt;UserPromptSubmit&lt;/code&gt;,&amp;nbsp;before&amp;nbsp;each&amp;nbsp;message&amp;nbsp;reaches&amp;nbsp;Claude.&amp;nbsp;It&amp;nbsp;reads&amp;nbsp;the&amp;nbsp;prompt&amp;nbsp;text,&amp;nbsp;lowercases&amp;nbsp;it,&amp;nbsp;and&amp;nbsp;scans&amp;nbsp;for&amp;nbsp;any&amp;nbsp;known&amp;nbsp;project&amp;nbsp;slug&amp;nbsp;as&amp;nbsp;a&amp;nbsp;whole&amp;nbsp;word.&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="k"&gt;for &lt;/span&gt;s &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$HUB_SLUGS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  if &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PROMPT_LC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qE&lt;/span&gt; &lt;span class="s2"&gt;"(^|[^a-z0-9])&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="s2"&gt;([^a-z0-9]|&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;MATCHED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MATCHED&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The&amp;nbsp;whole-word&amp;nbsp;boundary&amp;nbsp;in&amp;nbsp;that&amp;nbsp;regex&amp;nbsp;is&amp;nbsp;load-bearing.&amp;nbsp;Without&amp;nbsp;it,&amp;nbsp;a&amp;nbsp;short&amp;nbsp;slug&amp;nbsp;matches&amp;nbsp;inside&amp;nbsp;longer&amp;nbsp;unrelated&amp;nbsp;words&amp;nbsp;and&amp;nbsp;ordinary&amp;nbsp;prompts&amp;nbsp;trigger&amp;nbsp;recalls&amp;nbsp;all&amp;nbsp;day.&amp;nbsp;With&amp;nbsp;it,&amp;nbsp;only&amp;nbsp;a&amp;nbsp;real&amp;nbsp;mention&amp;nbsp;counts.&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;a&amp;nbsp;slug&amp;nbsp;matches,&amp;nbsp;the&amp;nbsp;hook&amp;nbsp;injects&amp;nbsp;the&amp;nbsp;same&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;recall&amp;nbsp;instruction&amp;nbsp;—&amp;nbsp;pull&amp;nbsp;context&amp;nbsp;for&amp;nbsp;&lt;em&gt;that&lt;/em&gt;&amp;nbsp;project&amp;nbsp;before&amp;nbsp;answering.&amp;nbsp;If&amp;nbsp;nothing&amp;nbsp;matches,&amp;nbsp;the&amp;nbsp;hook&amp;nbsp;exits&amp;nbsp;silently&amp;nbsp;and&amp;nbsp;adds&amp;nbsp;nothing&amp;nbsp;at&amp;nbsp;all.&amp;nbsp;Most&amp;nbsp;prompts&amp;nbsp;hit&amp;nbsp;the&amp;nbsp;silent&amp;nbsp;path.&lt;/p&gt;

&lt;p&gt;This&amp;nbsp;is&amp;nbsp;the&amp;nbsp;part&amp;nbsp;I&amp;nbsp;notice&amp;nbsp;most&amp;nbsp;in&amp;nbsp;daily&amp;nbsp;use.&amp;nbsp;I&amp;nbsp;name&amp;nbsp;a&amp;nbsp;project&amp;nbsp;and&amp;nbsp;Claude&amp;nbsp;already&amp;nbsp;has&amp;nbsp;its&amp;nbsp;history&amp;nbsp;before&amp;nbsp;it&amp;nbsp;responds,&amp;nbsp;even&amp;nbsp;when&amp;nbsp;that&amp;nbsp;repo&amp;nbsp;is&amp;nbsp;three&amp;nbsp;directories&amp;nbsp;away&amp;nbsp;from&amp;nbsp;where&amp;nbsp;I&amp;nbsp;am&amp;nbsp;actually&amp;nbsp;working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hook&amp;nbsp;3:&amp;nbsp;capture&amp;nbsp;without&amp;nbsp;making&amp;nbsp;me&amp;nbsp;wait
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;first&amp;nbsp;two&amp;nbsp;hooks&amp;nbsp;are&amp;nbsp;reads.&amp;nbsp;Reads&amp;nbsp;are&amp;nbsp;easy&amp;nbsp;—&amp;nbsp;they&amp;nbsp;are&amp;nbsp;fast,&amp;nbsp;and&amp;nbsp;a&amp;nbsp;few&amp;nbsp;hundred&amp;nbsp;milliseconds&amp;nbsp;at&amp;nbsp;session&amp;nbsp;start&amp;nbsp;is&amp;nbsp;invisible.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;third&amp;nbsp;hook&amp;nbsp;is&amp;nbsp;the&amp;nbsp;write,&amp;nbsp;and&amp;nbsp;writes&amp;nbsp;are&amp;nbsp;where&amp;nbsp;this&amp;nbsp;got&amp;nbsp;ugly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SessionEnd&lt;/code&gt;&amp;nbsp;fires&amp;nbsp;when&amp;nbsp;I&amp;nbsp;close&amp;nbsp;a&amp;nbsp;session.&amp;nbsp;The&amp;nbsp;work&amp;nbsp;it&amp;nbsp;wants&amp;nbsp;to&amp;nbsp;do&amp;nbsp;is&amp;nbsp;not&amp;nbsp;fast:&amp;nbsp;read&amp;nbsp;the&amp;nbsp;whole&amp;nbsp;transcript,&amp;nbsp;send&amp;nbsp;it&amp;nbsp;to&amp;nbsp;an&amp;nbsp;LLM&amp;nbsp;to&amp;nbsp;extract&amp;nbsp;what&amp;nbsp;actually&amp;nbsp;mattered,&amp;nbsp;dedupe&amp;nbsp;each&amp;nbsp;item&amp;nbsp;against&amp;nbsp;the&amp;nbsp;vector&amp;nbsp;store,&amp;nbsp;write&amp;nbsp;the&amp;nbsp;survivors.&amp;nbsp;That&amp;nbsp;is&amp;nbsp;several&amp;nbsp;seconds&amp;nbsp;of&amp;nbsp;work.&amp;nbsp;If&amp;nbsp;the&amp;nbsp;hook&amp;nbsp;does&amp;nbsp;it&amp;nbsp;inline,&amp;nbsp;my&amp;nbsp;terminal&amp;nbsp;hangs&amp;nbsp;for&amp;nbsp;several&amp;nbsp;seconds&amp;nbsp;every&amp;nbsp;single&amp;nbsp;time&amp;nbsp;I&amp;nbsp;close&amp;nbsp;it.&amp;nbsp;Not&amp;nbsp;acceptable.&lt;/p&gt;

&lt;p&gt;So&amp;nbsp;the&amp;nbsp;SessionEnd&amp;nbsp;hook&amp;nbsp;does&amp;nbsp;almost&amp;nbsp;nothing&amp;nbsp;itself.&amp;nbsp;It&amp;nbsp;spawns&amp;nbsp;a&amp;nbsp;detached&amp;nbsp;background&amp;nbsp;process&amp;nbsp;and&amp;nbsp;returns&amp;nbsp;immediately:&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="o"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PYTHON_BIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SCRIPT_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TRANSCRIPT_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOOK_EVENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &amp;lt;/dev/null &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;&amp;amp;1 &amp;amp;
  &lt;span class="nb"&gt;disown&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The&amp;nbsp;extraction&amp;nbsp;runs&amp;nbsp;after&amp;nbsp;my&amp;nbsp;terminal&amp;nbsp;is&amp;nbsp;already&amp;nbsp;gone.&amp;nbsp;I&amp;nbsp;find&amp;nbsp;out&amp;nbsp;whether&amp;nbsp;it&amp;nbsp;worked&amp;nbsp;by&amp;nbsp;reading&amp;nbsp;a&amp;nbsp;log&amp;nbsp;file&amp;nbsp;later,&amp;nbsp;never&amp;nbsp;by&amp;nbsp;waiting&amp;nbsp;on&amp;nbsp;it.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vmonkav1hr57d9xewea.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vmonkav1hr57d9xewea.jpg" alt="SessionEnd spawns a detached process that reads the transcript, extracts with Gemini, dedupes, and writes to Pinecone" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three&amp;nbsp;things&amp;nbsp;bit&amp;nbsp;me&amp;nbsp;here.&amp;nbsp;They&amp;nbsp;are&amp;nbsp;the&amp;nbsp;reason&amp;nbsp;this&amp;nbsp;section&amp;nbsp;is&amp;nbsp;the&amp;nbsp;longest&amp;nbsp;one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel&amp;nbsp;runs.&lt;/strong&gt;&amp;nbsp;At&amp;nbsp;the&amp;nbsp;end&amp;nbsp;of&amp;nbsp;an&amp;nbsp;evening&amp;nbsp;I&amp;nbsp;close&amp;nbsp;three&amp;nbsp;or&amp;nbsp;four&amp;nbsp;sessions&amp;nbsp;in&amp;nbsp;a&amp;nbsp;burst.&amp;nbsp;Without&amp;nbsp;a&amp;nbsp;lock,&amp;nbsp;that&amp;nbsp;is&amp;nbsp;three&amp;nbsp;or&amp;nbsp;four&amp;nbsp;extractors&amp;nbsp;hammering&amp;nbsp;the&amp;nbsp;vector&amp;nbsp;store&amp;nbsp;at&amp;nbsp;once.&lt;/p&gt;

&lt;p&gt;(My&amp;nbsp;last&amp;nbsp;memory&amp;nbsp;article&amp;nbsp;had&amp;nbsp;a&amp;nbsp;footnote&amp;nbsp;about&amp;nbsp;a&amp;nbsp;"helpful"&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;once&amp;nbsp;spawned&amp;nbsp;seven&amp;nbsp;parallel&amp;nbsp;Claude&amp;nbsp;instances.&amp;nbsp;I&amp;nbsp;have&amp;nbsp;held&amp;nbsp;a&amp;nbsp;grudge&amp;nbsp;against&amp;nbsp;unguarded&amp;nbsp;hooks&amp;nbsp;ever&amp;nbsp;since.)&amp;nbsp;The&amp;nbsp;fix&amp;nbsp;is&amp;nbsp;two&amp;nbsp;locks:&amp;nbsp;a&amp;nbsp;global&amp;nbsp;one&amp;nbsp;created&amp;nbsp;with&amp;nbsp;&lt;code&gt;mkdir&lt;/code&gt;&amp;nbsp;—&amp;nbsp;atomic&amp;nbsp;because&amp;nbsp;the&amp;nbsp;filesystem&amp;nbsp;either&amp;nbsp;creates&amp;nbsp;the&amp;nbsp;directory&amp;nbsp;or&amp;nbsp;fails,&amp;nbsp;with&amp;nbsp;no&amp;nbsp;gap&amp;nbsp;between&amp;nbsp;the&amp;nbsp;check&amp;nbsp;and&amp;nbsp;the&amp;nbsp;create,&amp;nbsp;unlike&amp;nbsp;testing&amp;nbsp;for&amp;nbsp;a&amp;nbsp;lockfile&amp;nbsp;and&amp;nbsp;then&amp;nbsp;writing&amp;nbsp;it&amp;nbsp;—&amp;nbsp;plus&amp;nbsp;a&amp;nbsp;per-session&amp;nbsp;lock&amp;nbsp;with&amp;nbsp;a&amp;nbsp;120-second&amp;nbsp;cooldown&amp;nbsp;so&amp;nbsp;one&amp;nbsp;session&amp;nbsp;cannot&amp;nbsp;double-fire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inherited&amp;nbsp;environment.&lt;/strong&gt;&amp;nbsp;The&amp;nbsp;extractor&amp;nbsp;is&amp;nbsp;a&amp;nbsp;plain&amp;nbsp;Python&amp;nbsp;script,&amp;nbsp;but&amp;nbsp;spawned&amp;nbsp;from&amp;nbsp;inside&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;it&amp;nbsp;inherits&amp;nbsp;Claude&amp;nbsp;Code's&amp;nbsp;entire&amp;nbsp;environment&amp;nbsp;—&amp;nbsp;&lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;,&amp;nbsp;an&amp;nbsp;OAuth&amp;nbsp;token,&amp;nbsp;a&amp;nbsp;dozen&amp;nbsp;&lt;code&gt;CLAUDE_CODE_*&lt;/code&gt;&amp;nbsp;variables.&amp;nbsp;That&amp;nbsp;environment&amp;nbsp;makes&amp;nbsp;the&amp;nbsp;subprocess&amp;nbsp;behave&amp;nbsp;as&amp;nbsp;if&amp;nbsp;it&amp;nbsp;is&amp;nbsp;still&amp;nbsp;running&amp;nbsp;inside&amp;nbsp;Claude.&amp;nbsp;The&amp;nbsp;fix&amp;nbsp;is&amp;nbsp;one&amp;nbsp;&lt;code&gt;unset&lt;/code&gt;&amp;nbsp;block&amp;nbsp;before&amp;nbsp;the&amp;nbsp;Python&amp;nbsp;runs,&amp;nbsp;clearing&amp;nbsp;every&amp;nbsp;inherited&amp;nbsp;Claude&amp;nbsp;variable.&amp;nbsp;This&amp;nbsp;one&amp;nbsp;cost&amp;nbsp;me&amp;nbsp;a&amp;nbsp;confused&amp;nbsp;hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key&amp;nbsp;source.&lt;/strong&gt;&amp;nbsp;The&amp;nbsp;extractor&amp;nbsp;needs&amp;nbsp;API&amp;nbsp;keys.&amp;nbsp;I&amp;nbsp;could&amp;nbsp;hard-code&amp;nbsp;them&amp;nbsp;into&amp;nbsp;the&amp;nbsp;script.&amp;nbsp;Instead&amp;nbsp;it&amp;nbsp;reads&amp;nbsp;them&amp;nbsp;straight&amp;nbsp;out&amp;nbsp;of&amp;nbsp;&lt;code&gt;~/.claude.json&lt;/code&gt;&amp;nbsp;—&amp;nbsp;the&amp;nbsp;same&amp;nbsp;file&amp;nbsp;the&amp;nbsp;live&amp;nbsp;mem0&amp;nbsp;MCP&amp;nbsp;server&amp;nbsp;already&amp;nbsp;reads&amp;nbsp;its&amp;nbsp;own&amp;nbsp;keys&amp;nbsp;from.&amp;nbsp;One&amp;nbsp;source&amp;nbsp;of&amp;nbsp;truth.&amp;nbsp;When&amp;nbsp;I&amp;nbsp;rotate&amp;nbsp;a&amp;nbsp;key&amp;nbsp;I&amp;nbsp;rotate&amp;nbsp;it&amp;nbsp;in&amp;nbsp;one&amp;nbsp;place,&amp;nbsp;and&amp;nbsp;both&amp;nbsp;the&amp;nbsp;hook&amp;nbsp;and&amp;nbsp;the&amp;nbsp;server&amp;nbsp;pick&amp;nbsp;it&amp;nbsp;up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What&amp;nbsp;the&amp;nbsp;extractor&amp;nbsp;actually&amp;nbsp;keeps
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;background&amp;nbsp;script&amp;nbsp;sends&amp;nbsp;the&amp;nbsp;transcript&amp;nbsp;to&amp;nbsp;Gemini&amp;nbsp;2.5&amp;nbsp;Flash&amp;nbsp;Lite&amp;nbsp;with&amp;nbsp;a&amp;nbsp;tight&amp;nbsp;extraction&amp;nbsp;prompt:&amp;nbsp;keep&amp;nbsp;architectural&amp;nbsp;decisions&amp;nbsp;and&amp;nbsp;their&amp;nbsp;reasoning,&amp;nbsp;keep&amp;nbsp;preferences,&amp;nbsp;keep&amp;nbsp;root&amp;nbsp;causes&amp;nbsp;of&amp;nbsp;bugs,&amp;nbsp;keep&amp;nbsp;project-specific&amp;nbsp;facts.&amp;nbsp;Skip&amp;nbsp;transient&amp;nbsp;state,&amp;nbsp;skip&amp;nbsp;routine&amp;nbsp;procedure.&amp;nbsp;Flash&amp;nbsp;Lite&amp;nbsp;sits&amp;nbsp;on&amp;nbsp;the&amp;nbsp;free&amp;nbsp;tier,&amp;nbsp;so&amp;nbsp;a&amp;nbsp;chatty&amp;nbsp;day&amp;nbsp;of&amp;nbsp;building&amp;nbsp;costs&amp;nbsp;nothing&amp;nbsp;—&amp;nbsp;and&amp;nbsp;transcript&amp;nbsp;extraction&amp;nbsp;is&amp;nbsp;genuinely&amp;nbsp;not&amp;nbsp;a&amp;nbsp;job&amp;nbsp;that&amp;nbsp;needs&amp;nbsp;a&amp;nbsp;frontier&amp;nbsp;model.&amp;nbsp;A&amp;nbsp;small&amp;nbsp;OpenAI&amp;nbsp;model&amp;nbsp;is&amp;nbsp;wired&amp;nbsp;in&amp;nbsp;as&amp;nbsp;a&amp;nbsp;fallback&amp;nbsp;for&amp;nbsp;the&amp;nbsp;days&amp;nbsp;Gemini&amp;nbsp;fails.&lt;/p&gt;

&lt;p&gt;Each&amp;nbsp;surviving&amp;nbsp;item&amp;nbsp;comes&amp;nbsp;back&amp;nbsp;as&amp;nbsp;structured&amp;nbsp;JSON&amp;nbsp;—&amp;nbsp;the&amp;nbsp;fact,&amp;nbsp;a&amp;nbsp;project&amp;nbsp;scope,&amp;nbsp;and&amp;nbsp;a&amp;nbsp;category&amp;nbsp;like&amp;nbsp;&lt;code&gt;decision&lt;/code&gt;&amp;nbsp;or&amp;nbsp;&lt;code&gt;learning&lt;/code&gt;.&amp;nbsp;In&amp;nbsp;practice&amp;nbsp;a&amp;nbsp;memory&amp;nbsp;looks&amp;nbsp;like&amp;nbsp;one&amp;nbsp;short&amp;nbsp;sentence:&amp;nbsp;"subhook&amp;nbsp;uses&amp;nbsp;Postmark&amp;nbsp;inbound&amp;nbsp;for&amp;nbsp;subdomain&amp;nbsp;mail&amp;nbsp;because&amp;nbsp;Cloudflare&amp;nbsp;Email&amp;nbsp;Routing&amp;nbsp;only&amp;nbsp;forwards&amp;nbsp;the&amp;nbsp;apex&amp;nbsp;on&amp;nbsp;the&amp;nbsp;free&amp;nbsp;plan,"&amp;nbsp;tagged&amp;nbsp;&lt;code&gt;{project:&amp;nbsp;subhook,&amp;nbsp;category:&amp;nbsp;decision}&lt;/code&gt;.&amp;nbsp;Before&amp;nbsp;writing&amp;nbsp;anything,&amp;nbsp;the&amp;nbsp;script&amp;nbsp;searches&amp;nbsp;the&amp;nbsp;vector&amp;nbsp;store&amp;nbsp;for&amp;nbsp;that&amp;nbsp;exact&amp;nbsp;text&amp;nbsp;and&amp;nbsp;skips&amp;nbsp;it&amp;nbsp;if&amp;nbsp;something&amp;nbsp;already&amp;nbsp;sits&amp;nbsp;above&amp;nbsp;0.88&amp;nbsp;cosine&amp;nbsp;similarity.&amp;nbsp;&lt;strong&gt;That&amp;nbsp;dedupe&amp;nbsp;is&amp;nbsp;the&amp;nbsp;line&amp;nbsp;between&amp;nbsp;a&amp;nbsp;memory&amp;nbsp;that&amp;nbsp;compounds&amp;nbsp;and&amp;nbsp;a&amp;nbsp;memory&amp;nbsp;that&amp;nbsp;fills&amp;nbsp;up&amp;nbsp;with&amp;nbsp;a&amp;nbsp;hundred&amp;nbsp;near-identical&amp;nbsp;entries.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What&amp;nbsp;survives&amp;nbsp;gets&amp;nbsp;written&amp;nbsp;to&amp;nbsp;Pinecone&amp;nbsp;with&amp;nbsp;&lt;code&gt;infer=False&lt;/code&gt;&amp;nbsp;—&amp;nbsp;store&amp;nbsp;the&amp;nbsp;text&amp;nbsp;verbatim.&amp;nbsp;The&amp;nbsp;extraction&amp;nbsp;already&amp;nbsp;happened,&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Gemini&amp;nbsp;step.&amp;nbsp;I&amp;nbsp;do&amp;nbsp;not&amp;nbsp;want&amp;nbsp;the&amp;nbsp;vector&amp;nbsp;store&amp;nbsp;re-paraphrasing&amp;nbsp;facts&amp;nbsp;I&amp;nbsp;already&amp;nbsp;shaped&amp;nbsp;into&amp;nbsp;the&amp;nbsp;form&amp;nbsp;I&amp;nbsp;wanted&amp;nbsp;them&amp;nbsp;in.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9x4l6kdp5g7v3wzn020.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9x4l6kdp5g7v3wzn020.jpg" alt="Three Claude Code lifecycle hooks: SessionStart and UserPromptSubmit recall memory in, SessionEnd captures it out" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  If&amp;nbsp;you&amp;nbsp;copy&amp;nbsp;one&amp;nbsp;idea&amp;nbsp;from&amp;nbsp;this
&lt;/h2&gt;

&lt;p&gt;Not&amp;nbsp;the&amp;nbsp;project-slug&amp;nbsp;list.&amp;nbsp;Not&amp;nbsp;Pinecone,&amp;nbsp;not&amp;nbsp;Gemini.&amp;nbsp;Those&amp;nbsp;are&amp;nbsp;my&amp;nbsp;plumbing,&amp;nbsp;and&amp;nbsp;yours&amp;nbsp;will&amp;nbsp;be&amp;nbsp;different.&lt;/p&gt;

&lt;p&gt;Copy&amp;nbsp;this:&amp;nbsp;&lt;strong&gt;a&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;injects&amp;nbsp;an&amp;nbsp;instruction&amp;nbsp;beats&amp;nbsp;a&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;runs&amp;nbsp;a&amp;nbsp;command.&lt;/strong&gt;&amp;nbsp;A&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;runs&amp;nbsp;&lt;code&gt;git&amp;nbsp;status&lt;/code&gt;&amp;nbsp;and&amp;nbsp;returns&amp;nbsp;the&amp;nbsp;output&amp;nbsp;hands&amp;nbsp;Claude&amp;nbsp;a&amp;nbsp;fact.&amp;nbsp;A&amp;nbsp;hook&amp;nbsp;that&amp;nbsp;injects&amp;nbsp;"before&amp;nbsp;answering,&amp;nbsp;check&amp;nbsp;X&amp;nbsp;and&amp;nbsp;recall&amp;nbsp;Y"&amp;nbsp;hands&amp;nbsp;Claude&amp;nbsp;a&amp;nbsp;&lt;em&gt;task&lt;/em&gt;&amp;nbsp;—&amp;nbsp;carried&amp;nbsp;out&amp;nbsp;with&amp;nbsp;the&amp;nbsp;full&amp;nbsp;toolset&amp;nbsp;and&amp;nbsp;judgment&amp;nbsp;Claude&amp;nbsp;already&amp;nbsp;has.&amp;nbsp;The&amp;nbsp;first&amp;nbsp;is&amp;nbsp;static.&amp;nbsp;The&amp;nbsp;second&amp;nbsp;is&amp;nbsp;behavior.&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;I&amp;nbsp;started&amp;nbsp;seeing&amp;nbsp;shell-command&amp;nbsp;hooks&amp;nbsp;as&amp;nbsp;a&amp;nbsp;place&amp;nbsp;to&amp;nbsp;write&amp;nbsp;prompts&amp;nbsp;instead&amp;nbsp;of&amp;nbsp;a&amp;nbsp;place&amp;nbsp;to&amp;nbsp;run&amp;nbsp;scripts,&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;wiring&amp;nbsp;stopped&amp;nbsp;looking&amp;nbsp;like&amp;nbsp;a&amp;nbsp;hack&amp;nbsp;and&amp;nbsp;started&amp;nbsp;looking&amp;nbsp;like&amp;nbsp;the&amp;nbsp;obvious&amp;nbsp;shape.&amp;nbsp;Recall&amp;nbsp;on&amp;nbsp;the&amp;nbsp;way&amp;nbsp;in.&amp;nbsp;Capture&amp;nbsp;on&amp;nbsp;the&amp;nbsp;way&amp;nbsp;out.&amp;nbsp;And&amp;nbsp;an&amp;nbsp;evening-tired&amp;nbsp;version&amp;nbsp;of&amp;nbsp;me&amp;nbsp;who&amp;nbsp;never&amp;nbsp;has&amp;nbsp;to&amp;nbsp;think&amp;nbsp;about&amp;nbsp;either&amp;nbsp;one.&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;you&amp;nbsp;want&amp;nbsp;the&amp;nbsp;layer&amp;nbsp;this&amp;nbsp;builds&amp;nbsp;on,&amp;nbsp;the&amp;nbsp;same&amp;nbsp;lifecycle&amp;nbsp;thinking&amp;nbsp;shows&amp;nbsp;up&amp;nbsp;in&amp;nbsp;how&amp;nbsp;I&amp;nbsp;&lt;a href="https://medium.com/generative-ai/how-i-put-a-code-reviewer-in-front-of-every-git-push-to-main-with-a-claude-code-subagent-17408aa3236e?sk=b141e0baa56cea334ad5887116c4f771" rel="noopener noreferrer"&gt;put&amp;nbsp;a&amp;nbsp;code&amp;nbsp;reviewer&amp;nbsp;in&amp;nbsp;front&amp;nbsp;of&amp;nbsp;every&amp;nbsp;git&amp;nbsp;push&amp;nbsp;with&amp;nbsp;a&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;subagent&lt;/a&gt;&amp;nbsp;—&amp;nbsp;another&amp;nbsp;small&amp;nbsp;piece&amp;nbsp;of&amp;nbsp;glue&amp;nbsp;that&amp;nbsp;runs&amp;nbsp;without&amp;nbsp;me&amp;nbsp;thinking&amp;nbsp;about&amp;nbsp;it.&lt;/p&gt;

&lt;h2&gt;
  
  
  External&amp;nbsp;Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://code.claude.com/docs/en/hooks" rel="noopener noreferrer"&gt;Claude&amp;nbsp;Code&amp;nbsp;hooks&amp;nbsp;reference&lt;/a&gt;&amp;nbsp;—&amp;nbsp;official&amp;nbsp;lifecycle&amp;nbsp;event&amp;nbsp;and&amp;nbsp;JSON&amp;nbsp;schema&amp;nbsp;docs&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/mem0ai/mem0" rel="noopener noreferrer"&gt;mem0&amp;nbsp;on&amp;nbsp;GitHub&lt;/a&gt;&amp;nbsp;—&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;layer&amp;nbsp;this&amp;nbsp;builds&amp;nbsp;on&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.pinecone.io/guides/get-started/overview" rel="noopener noreferrer"&gt;Pinecone&amp;nbsp;documentation&lt;/a&gt;&amp;nbsp;—&amp;nbsp;managed&amp;nbsp;vector&amp;nbsp;database&amp;nbsp;getting-started&amp;nbsp;guide&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://ai.google.dev/gemini-api/docs" rel="noopener noreferrer"&gt;Gemini&amp;nbsp;API&amp;nbsp;documentation&lt;/a&gt;&amp;nbsp;—&amp;nbsp;Google's&amp;nbsp;developer&amp;nbsp;docs&amp;nbsp;for&amp;nbsp;Gemini&amp;nbsp;models&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/google-gemini/cookbook" rel="noopener noreferrer"&gt;Gemini&amp;nbsp;cookbook&lt;/a&gt;&amp;nbsp;—&amp;nbsp;examples&amp;nbsp;and&amp;nbsp;guides&amp;nbsp;for&amp;nbsp;the&amp;nbsp;Gemini&amp;nbsp;API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If you want the starter version of this to land in your inbox, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; walks you through it over a few short emails — free. The memory layer this one builds on is the earlier article on &lt;a href="https://generativeai.pub/how-i-added-persistent-semantic-memory-to-claude-code-in-15-minutes-9b91f9399a76" rel="noopener noreferrer"&gt;adding persistent semantic memory to Claude Code&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target&amp;nbsp;publication:&lt;/strong&gt;&amp;nbsp;Generative&amp;nbsp;AI&amp;nbsp;(~50K&amp;nbsp;followers)&amp;nbsp;[PRIMARY&amp;nbsp;for&amp;nbsp;the&amp;nbsp;AI/Claude&amp;nbsp;Code&amp;nbsp;angle]&amp;nbsp;·&amp;nbsp;Level&amp;nbsp;Up&amp;nbsp;Coding&amp;nbsp;(~60K&amp;nbsp;followers)&amp;nbsp;[SECONDARY]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt;&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;·&amp;nbsp;AI&amp;nbsp;·&amp;nbsp;Developer&amp;nbsp;Tools&amp;nbsp;·&amp;nbsp;Programming&amp;nbsp;·&amp;nbsp;Productivity&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build small tools and kits for solo creators. You can find them here: &lt;a href="https://danielrusnok.gumroad.com" rel="noopener noreferrer"&gt;https://danielrusnok.gumroad.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Make Chrome Extension Iframes Transparent on Dark-Mode Sites (CSS color-scheme Fix)</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Wed, 22 Jul 2026 15:15:31 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-to-make-chrome-extension-iframes-transparent-on-dark-mode-sites-css-color-scheme-fix-2b23</link>
      <guid>https://dev.to/danielrusnok/how-to-make-chrome-extension-iframes-transparent-on-dark-mode-sites-css-color-scheme-fix-2b23</guid>
      <description>&lt;p&gt;A customer of ours emailed: "Your Chrome extension shows me a blank white page on our dashboard." I checked. His site uses &lt;code&gt;color-scheme: dark\&lt;/code&gt;. Ours doesn't set it. &lt;strong&gt;Our iframe was painting a solid white rectangle over his entire viewport&lt;/strong&gt; — and I had no idea, because every site I test on is light-themed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5wg88typ5vrkfrvdbki.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5wg88typ5vrkfrvdbki.jpg" alt="Same iframe overlay rendered on a color-scheme light host (invisible) versus a color-scheme dark host (opaque white rectangle)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
Same iframe, same transparent body — only the host's color-scheme differs.



&lt;h2&gt;
  
  
  The white rectangle nobody sees
&lt;/h2&gt;

&lt;p&gt;Drop an iframe into a customer's page. Set &lt;code&gt;background: transparent\&lt;/code&gt; on its &lt;code&gt;&amp;lt;body&amp;gt;\&lt;/code&gt;, its &lt;code&gt;&amp;lt;html&amp;gt;\&lt;/code&gt;, even &lt;code&gt;#root\&lt;/code&gt;. Check DevTools — every layer reports &lt;code&gt;background-color: rgba(0, 0, 0, 0)\&lt;/code&gt;. The iframe should be see-through.&lt;/p&gt;

&lt;p&gt;On most sites, it is.&lt;/p&gt;

&lt;p&gt;On any site that sets &lt;code&gt;color-scheme: dark\&lt;/code&gt; on its &lt;code&gt;&amp;lt;html&amp;gt;\&lt;/code&gt; element, &lt;strong&gt;the iframe paints a solid white rectangle over everything underneath&lt;/strong&gt;. Your transparent body is sitting on top of a white backdrop you didn't ask for and can't see in the computed styles panel.&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Chrome does this
&lt;/h2&gt;

&lt;p&gt;The CSS property responsible is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme" rel="noopener noreferrer"&gt;&lt;code&gt;color-scheme\&lt;/code&gt;&lt;/a&gt;. It tells the browser what theme a document expects — &lt;code&gt;light\&lt;/code&gt;, &lt;code&gt;dark\&lt;/code&gt;, or &lt;code&gt;normal\&lt;/code&gt;. The browser uses this to pick the right shade for form controls, scrollbars, and a system color called &lt;strong&gt;Canvas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Canvas\&lt;/code&gt; is the default backdrop the browser paints behind any element with a transparent background. In light mode it's white. In dark mode it's near-black.&lt;/p&gt;

&lt;p&gt;The spec detail that matters: &lt;strong&gt;&lt;code&gt;color-scheme\&lt;/code&gt; does not propagate across iframe document boundaries&lt;/strong&gt;. Every iframe document defaults to &lt;code&gt;color-scheme: normal\&lt;/code&gt; (which resolves to light) regardless of what the parent page declares.&lt;/p&gt;

&lt;p&gt;The CSS Color Adjustment spec calls this a &lt;strong&gt;color-scheme mismatch&lt;/strong&gt;. The spec requires the user agent to substitute an opaque Canvas color matching the iframe document's resolved color scheme — light, in this case, which means white. Your transparent body is then composited on top of that opaque white backdrop, not on top of the dark parent page.&lt;/p&gt;

&lt;p&gt;In practice, this means the browser inserts an opaque layer between your iframe document and the parent page before any of your own CSS gets a chance to run. There is no DOM node you can inspect for it. The computed background-color on every element in your iframe still reports &lt;code&gt;rgba(0, 0, 0, 0)\&lt;/code&gt;. The Elements panel will not show you a white rectangle, because the white rectangle is not in the DOM — it is the user agent's substitute Canvas, painted by the compositor.&lt;/p&gt;

&lt;p&gt;This is documented in &lt;a href="https://issues.chromium.org/issues/40157837" rel="noopener noreferrer"&gt;Chromium issue 40157837&lt;/a&gt; and the &lt;a href="https://github.com/w3c/csswg-drafts/issues/4772" rel="noopener noreferrer"&gt;CSSWG drafts discussion&lt;/a&gt;. It is intentional, it is spec-compliant, and it has been breaking iframe overlays for years — &lt;a href="https://levelup.gitconnected.com/one-missing-html-tag-is-killing-your-social-media-traffic-dcdf25e2b012" rel="noopener noreferrer"&gt;one missing HTML tag has been killing social media traffic&lt;/a&gt; the same way for just as long. The web is full of these tiny spec gotchas.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnzfqc6y4t2gt4o476tc5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnzfqc6y4t2gt4o476tc5.jpg" alt="Painting order diagram: parent page color-scheme dark, iframe Canvas backdrop opaque white from mismatch, transparent iframe body, final composite shows a white rectangle over the dark parent" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;
Four layers — only the user agent's substitute Canvas is visible to the eye, and only when the parent is dark.



&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-line CSS fix
&lt;/h2&gt;

&lt;p&gt;Tell the iframe element explicitly what color scheme to use, and make sure its body is transparent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;iframe&lt;/span&gt;&lt;span class="nc"&gt;.my-overlay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&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 it. &lt;code&gt;color-scheme: light\&lt;/code&gt; on the iframe &lt;strong&gt;element&lt;/strong&gt; in the parent document tells Chrome "the iframe wants light scheme, same as you would assume by default." No mismatch, no Canvas backdrop. &lt;code&gt;background: transparent\&lt;/code&gt; makes sure the element itself doesn't paint either.&lt;/p&gt;

&lt;p&gt;If you control the iframe document too, also add this in its CSS so it's transparent even before the inline style is parsed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;!important\&lt;/code&gt; matters because some CSS resets and base layers (including configurations that add a body background) override your plain rule.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Small fixes like this are the kind of thing I collect in &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series you can join in one click.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  The reusable React component
&lt;/h2&gt;

&lt;p&gt;If you have one iframe, do the CSS-only fix. If you have ten — which is what I had across our flow editor — you need a wrapper so nobody can add an iframe and forget the rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;forwardRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IframeHTMLAttributes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SafeIframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;forwardRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLIFrameElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IframeHTMLAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLIFrameElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SafeIframe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;iframe&lt;/span&gt;
                &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transparent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;colorScheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things to notice. The wrapper uses &lt;code&gt;forwardRef\&lt;/code&gt; so callers can still attach refs (you'll need that for &lt;code&gt;getBoundingClientRect()\&lt;/code&gt; and &lt;code&gt;postMessage\&lt;/code&gt; patterns common in overlay UIs). And the default style spread comes &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;...style\&lt;/code&gt;, so any caller-provided style overrides the defaults — including setting &lt;code&gt;colorScheme: 'dark'\&lt;/code&gt; for the rare iframe that actually wants the dark backdrop.&lt;/p&gt;

&lt;p&gt;Then a &lt;code&gt;sed\&lt;/code&gt; pass replaces native iframes with the wrapper:&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="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in &lt;/span&gt;src/components/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.tsx&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="s1"&gt;'s|&amp;lt;iframe|&amp;lt;SafeIframe|g; s|&amp;lt;/iframe&amp;gt;|&amp;lt;/SafeIframe&amp;gt;|g'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the import in each touched file. Done. Every future iframe added to the project is transparent-by-default unless somebody actively opts out.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmkdlfbr6870kjut650q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmkdlfbr6870kjut650q.jpg" alt="Code diff comparing before and after migration: 16 native iframes plus 20 inline color-scheme hot-patches replaced by one SafeIframe wrapper with the defaults baked in" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;
One sed pass plus four imports — sixteen iframes become one wrapper.



&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the iframe document transparent too
&lt;/h2&gt;

&lt;p&gt;The wrapper fixes the iframe element. The CSS above fixes the iframe document. &lt;strong&gt;You want both&lt;/strong&gt;, because each protects against a different failure mode.&lt;/p&gt;

&lt;p&gt;The element-level fix breaks if a caller passes an explicit &lt;code&gt;style={{ colorScheme: 'dark' }}\&lt;/code&gt; override. The document-level fix breaks if the iframe is created somewhere outside your wrapper (a third-party library, a manual &lt;code&gt;document.createElement('iframe')\&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Add the document-level CSS to your iframe app's root stylesheet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your iframe app is React-based and uses Tailwind, put this &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;@tailwind base\&lt;/code&gt; so it overrides preflight defaults.&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this bug is invisible on light-themed sites
&lt;/h2&gt;

&lt;p&gt;If you don't test on a dark-themed host, you will never see this bug. &lt;strong&gt;The white Canvas blends into a light parent page&lt;/strong&gt; — you see what looks like a transparent overlay, but it's actually a white rectangle on top of a white page.&lt;/p&gt;

&lt;p&gt;The bug is identical on light and dark hosts. Only the visibility changes. My dev environment is light. The marketing site is light. Most customer playground apps are light. The bug existed for months, and nobody on the team saw it because the entire test surface looked clean. The customer who reported it ran a security product with a dark dashboard — as soon as the white rectangle had something to contrast against, the "blank page" complaints started. (Same shape as &lt;a href="https://levelup.gitconnected.com/our-next-js-app-crashed-every-24-hours-here-are-the-six-memory-fixes-35245f6548e4" rel="noopener noreferrer"&gt;our Next.js app that crashed every 24 hours&lt;/a&gt; — silent production bug only outsiders ever noticed.)&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  How to test for it before customers do
&lt;/h2&gt;

&lt;p&gt;Add this to your &lt;a href="https://medium.com/p/db51a8d7cc74" rel="noopener noreferrer"&gt;release checklist&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open any of your iframe overlays on a host page that sets &lt;code&gt;color-scheme: dark\&lt;/code&gt; on its &lt;code&gt;&amp;lt;html&amp;gt;\&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; If you don't have such a customer, force it for testing: in DevTools, find the &lt;code&gt;&amp;lt;html&amp;gt;\&lt;/code&gt; of any site you're testing on, add &lt;code&gt;style="color-scheme: dark"\&lt;/code&gt; inline. The bug will appear immediately if it's there.&lt;/li&gt;
&lt;li&gt; Or open Chrome DevTools → Rendering tab → set "Emulate CSS media feature prefers-color-scheme" to &lt;strong&gt;dark&lt;/strong&gt;, then visit any site whose CSS respects the system preference.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your overlay paints a visible rectangle, you have the bug. The fix is the two-line CSS rule above.&lt;/p&gt;

&lt;p&gt;In DevTools the rectangle is solid white, the exact &lt;code&gt;Canvas\&lt;/code&gt; light-mode color — not off-white, not semi-transparent. It appears the instant the iframe element gets a layout box, before any of your iframe document's own CSS runs, so there is no flash-of-transparent-content moment to catch. To verify the fix is working, apply it, hard-reload the host page, and confirm the iframe area composites cleanly against the dark parent background with no white edge anywhere along its bounding box.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46t8iq57u1i90o39cng4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46t8iq57u1i90o39cng4.jpg" alt="DevTools Rendering panel set to emulate prefers-color-scheme: dark, with the host page showing a white iframe rectangle appearing the instant emulation flips to dark" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;
Force-trigger the bug from DevTools — Rendering panel emulates dark scheme on any site.



&lt;p&gt;---&lt;/p&gt;

&lt;h2&gt;
  
  
  What we shipped
&lt;/h2&gt;

&lt;p&gt;In our codebase, the fix touched four files, replaced sixteen native &lt;code&gt;&amp;lt;iframe&amp;gt;\&lt;/code&gt; elements with one &lt;code&gt;SafeIframe\&lt;/code&gt; wrapper component, added one CSS rule to the global stylesheet, and deleted around twenty inline &lt;code&gt;colorScheme: 'light'\&lt;/code&gt; hot-patches that I had been sprinkling around while hunting the bug.&lt;/p&gt;

&lt;p&gt;The wrapper component is fifteen lines. The CSS rule is three lines. The entire fix is &lt;a href="https://levelup.gitconnected.com/stop-rewriting-the-whole-article-section-scoped-edits-for-llm-content-tools-d704ec05c1e5" rel="noopener noreferrer"&gt;shorter than this paragraph&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The bug had no console error, no DevTools warning, no broken selector. I only found it because a customer's screen didn't match mine.&lt;/p&gt;

&lt;p&gt;If you inject UI into customer pages, set up a dark-themed test host. I found mine had been broken on dark customers for months.&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this saved you a dark-mode debugging session, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; is a free email series where I share more fixes like it — one short email at a time.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>chrome</category>
    </item>
    <item>
      <title>How I Put a Code Reviewer in Front of Every git push to Main with a Claude Code Subagent</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Mon, 20 Jul 2026 15:09:48 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-i-put-a-code-reviewer-in-front-of-every-git-push-to-main-with-a-claude-code-subagent-5fgb</link>
      <guid>https://dev.to/danielrusnok/how-i-put-a-code-reviewer-in-front-of-every-git-push-to-main-with-a-claude-code-subagent-5fgb</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbo7uzcfh9w6j4efxcqhh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbo7uzcfh9w6j4efxcqhh.jpg" alt="Pasted image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three Wednesdays ago I shipped a regression to production. The diff looked fine. CI was green. I ran the dev server, clicked through the happy path, pushed, and went to bed.&lt;/p&gt;

&lt;p&gt;The next morning a real user emailed me to say my landing-page signup button did nothing.&lt;/p&gt;

&lt;p&gt;The bug was obvious in hindsight. &lt;strong&gt;The AI had quietly removed an&lt;/strong&gt; &lt;code&gt;await&lt;/code&gt; &lt;strong&gt;from an analytics call, the call threw inside a&lt;/strong&gt; &lt;code&gt;try&lt;/code&gt; &lt;strong&gt;block, and the catch swallowed it along with the rest of the handler.&lt;/strong&gt; Three minutes to revert. Took the rest of the morning to feel okay about it again.&lt;/p&gt;

&lt;p&gt;I'm a solo builder. No senior engineer reads my PRs. Nothing sits between my keyboard and &lt;code&gt;main&lt;/code&gt;. I let Claude Code write most of my code now — which means most of what hits &lt;code&gt;main&lt;/code&gt; was written by something that doesn't know it shouldn't swallow exceptions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sidebar: this story is one piece of how I think about &lt;a href="https://drippery.app/subscribe/a8ff09ab-6665-409f-a8e4-acb87e2f1a12" rel="noopener noreferrer"&gt;AI as a solo founder's tool&lt;/a&gt; — I have a 5-email series on the broader pattern if you want the bigger picture.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I built the second pair of eyes. One Claude Code subagent, one 30-line &lt;code&gt;pre-push&lt;/code&gt; hook, shared across every repo I own. It runs on every push to &lt;code&gt;main&lt;/code&gt;, takes about 20 seconds, and has caught real bugs four times in three weeks.&lt;/p&gt;

&lt;p&gt;Here's how it works.&lt;/p&gt;

&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fold7b76y2ia9avmkbzww.jpg" alt="Subagent checkpoint intercepts a push to main and forks into approve or block paths" width="800" height="450"&gt;The architecture
&lt;/h2&gt;

&lt;p&gt;Three pieces, nothing exotic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A subagent definition&lt;/strong&gt; — a markdown file that tells Claude how to act when invoked as a reviewer. Lives in &lt;code&gt;.claude/agents/code-reviewer.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt; &lt;code&gt;pre-push&lt;/code&gt; &lt;strong&gt;git hook&lt;/strong&gt; — bash script that gathers the diff, fires up a headless Claude Code instance pointed at the subagent, and prints the verdict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt; &lt;code&gt;.shared/&lt;/code&gt; &lt;strong&gt;folder + symlinks&lt;/strong&gt; — both files live once at the top of my &lt;code&gt;foundary-tools/&lt;/code&gt; monorepo and symlink into each child repo's &lt;code&gt;.claude/&lt;/code&gt; and &lt;code&gt;.git/hooks/&lt;/code&gt;. One install script wires everything.&lt;/p&gt;

&lt;p&gt;Three pieces because each one owns a different lifetime. The subagent definition is the slowest-changing — I edit it maybe once a week as I learn what false positives look like. The hook is the contract with git — set it up once, leave it alone. The symlinks are infrastructure — wired during &lt;code&gt;install-hooks.sh&lt;/code&gt; and forgotten. Bundling them into one script would mean re-installing across nine repos every time I tweak a prompt rule. Keeping them separate means the prompt edits live in version control and propagate for free.&lt;/p&gt;

&lt;p&gt;The reviewer only fires on pushes to &lt;code&gt;main&lt;/code&gt;. Feature branches push freely. The cost is one Opus call per release-shaped push — pennies — and the upside is a 20-second sanity check before a regression goes live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The whole thing fits in three files — and the most important one isn't the hook.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The subagent definition
&lt;/h2&gt;

&lt;p&gt;The subagent is a plain markdown file with frontmatter. Claude Code reads the &lt;code&gt;description&lt;/code&gt;, knows when to dispatch to it, and uses the body as the system prompt.&lt;/p&gt;

&lt;p&gt;---&lt;br&gt;
name: code-reviewer&lt;br&gt;
description: "Reviews staged commits before push. Flags"&lt;br&gt;
  regressions, swallowed errors, removed awaits, broken&lt;br&gt;
  invariants, leaked secrets, and missing migrations.&lt;br&gt;
model: opus&lt;/p&gt;

&lt;h2&gt;
  
  
  tools: Read, Grep, Glob, Bash
&lt;/h2&gt;

&lt;p&gt;You are reviewing a diff that is about to land on &lt;code&gt;main\&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Output exactly one of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"APPROVE: "&lt;/li&gt;
&lt;li&gt;"BLOCK: \n"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Block only for things that will break production or leak&lt;br&gt;
secrets. Style nits, naming preferences, and "could be cleaner"&lt;br&gt;
notes do not block. The author is a solo builder shipping&lt;br&gt;
fast; assume they accepted any trade-off that isn't a bug.&lt;/p&gt;

&lt;p&gt;Always check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed &lt;code&gt;await\&lt;/code&gt; on async calls&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;catch\&lt;/code&gt; blocks that swallow without logging&lt;/li&gt;
&lt;li&gt;Hard-coded URLs that look like prod endpoints&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.env\&lt;/code&gt; keys printed to logs&lt;/li&gt;
&lt;li&gt;Schema changes without a matching migration file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log\&lt;/code&gt; of request bodies (usually leaks PII)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The output contract is one line.&lt;/strong&gt; No essay, no "great work, here are some thoughts." Either &lt;code&gt;APPROVE: ...&lt;/code&gt; or &lt;code&gt;BLOCK: ...&lt;/code&gt;. The hook script greps for the prefix and acts on it.&lt;/p&gt;

&lt;p&gt;The subagent commits to a verdict instead of hedging. Without this contract, every review came back as a four-paragraph essay that ended with "but ultimately, this is your call."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The block criteria are narrow.&lt;/strong&gt; I don't want the reviewer to lecture me about my variable names or suggest I add comments. I want it to catch things that will page me in the morning.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;solo builder shipping fast&lt;/code&gt; line in the prompt is load-bearing. Without it, the reviewer was blocking pushes for things like "consider extracting this into a helper" — which is exactly the kind of advice I added the reviewer to ignore.&lt;/p&gt;

&lt;p&gt;If you've ever fought with Claude over &lt;a href="https://medium.com/gitconnected/getting-claude-to-return-strict-json-without-drift-a-system-prompt-template-9ee1b4eed5c4" rel="noopener noreferrer"&gt;getting it to follow a strict output format&lt;/a&gt;, the same lesson applies here: give the model a verdict to commit to, not an essay to write.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pre-push hook
&lt;/h2&gt;

&lt;p&gt;The hook is a bash script at &lt;code&gt;.git/hooks/pre-push&lt;/code&gt;. Git invokes it before talking to the remote and aborts the push if the script exits non-zero.&lt;/p&gt;

&lt;h1&gt;
  
  
  !/usr/bin/env bash
&lt;/h1&gt;

&lt;p&gt;set -euo pipefail&lt;/p&gt;

&lt;p&gt;REMOTE_BRANCH="$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2&amp;gt;/dev/null || echo "")"&lt;br&gt;
[[ "$REMOTE_BRANCH" == */main ]] || exit 0&lt;/p&gt;

&lt;p&gt;DIFF="$(git log --stat origin/main..HEAD; git diff origin/main..HEAD)"&lt;br&gt;
[[ -n "$DIFF" ]] || exit 0&lt;/p&gt;

&lt;p&gt;echo "Running code-reviewer subagent..."&lt;br&gt;
VERDICT="$(echo "$DIFF" | claude \&lt;br&gt;
  --dangerously-skip-permissions \&lt;br&gt;
  --print \&lt;br&gt;
  --agent code-reviewer 2&amp;gt;&amp;amp;1)"&lt;/p&gt;

&lt;p&gt;echo "---"&lt;br&gt;
echo "$VERDICT"&lt;br&gt;
echo "---"&lt;/p&gt;

&lt;p&gt;if [[ "$VERDICT" == BLOCK:* ]]; then&lt;br&gt;
  printf "Override? [y/N] "&lt;br&gt;
  read -r REPLY &amp;lt;/dev/tty&lt;br&gt;
  [[ "$REPLY" =~ ^[Yy]$ ]] || exit 1&lt;br&gt;
fi&lt;/p&gt;

&lt;p&gt;It only runs for pushes whose upstream tracks &lt;code&gt;main&lt;/code&gt;. A push to a feature branch returns early. That's the difference between 20 seconds added to every push and 20 seconds added to releases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note: if you're wiring Claude Code deeper into your own workflow, I put the setup I lean on into a short, free email series — &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — one small lesson at a time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The script ignores git's ref-list stdin and recomputes the diff from &lt;code&gt;origin/main..HEAD&lt;/code&gt;. The combination of &lt;code&gt;git log --stat&lt;/code&gt; and &lt;code&gt;git diff&lt;/code&gt; gives the reviewer commit messages plus the actual hunks — messages help it figure out intent when judging whether a deletion was deliberate.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; is fine here because the subagent has read-only tools (&lt;code&gt;Read&lt;/code&gt;, &lt;code&gt;Grep&lt;/code&gt;, &lt;code&gt;Glob&lt;/code&gt;, &lt;code&gt;Bash&lt;/code&gt;). It can't edit anything or push.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;read -r REPLY &amp;lt;/dev/tty&lt;/code&gt; is the one tricky line. Pre-push hooks get git's ref list on stdin, so you have to redirect from the controlling TTY to read the user. Without this, the prompt prints and immediately accepts an empty answer.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fab9d42i30q4w16wl2a0w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fab9d42i30q4w16wl2a0w.jpg" alt="Terminal output of the pre-push hook printing a BLOCK verdict with an Override prompt" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
**One hook, one repo. The next part is how it became one hook across nine.**



&lt;h2&gt;
  
  
  Sharing one config across every repo
&lt;/h2&gt;

&lt;p&gt;I have nine repositories in &lt;code&gt;~/foundary-tools/&lt;/code&gt;. I'm not going to copy a hook and a subagent definition into each one and then forget which is the canonical version after the third edit.&lt;/p&gt;

&lt;p&gt;The fix is a &lt;code&gt;.shared/&lt;/code&gt; folder at the top of the monorepo.&lt;/p&gt;

&lt;p&gt;foundary-tools/&lt;br&gt;
├── .shared/&lt;br&gt;
│   ├── agents/code-reviewer.md&lt;br&gt;
│   ├── hooks/pre-push&lt;br&gt;
│   └── install-hooks.sh&lt;br&gt;
├── drippery/&lt;br&gt;
├── article-forge/&lt;br&gt;
├── grownote/&lt;br&gt;
└── ...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;install-hooks.sh&lt;/code&gt; walks every direct child directory and creates two symlinks per repo.&lt;/p&gt;

&lt;h1&gt;
  
  
  !/usr/bin/env bash
&lt;/h1&gt;

&lt;p&gt;set -euo pipefail&lt;br&gt;
SHARED="$(cd "$(dirname "$0")" &amp;amp;&amp;amp; pwd)"&lt;/p&gt;

&lt;p&gt;for repo in "$SHARED/.."/*/; do&lt;br&gt;
  [[ -d "$repo/.git" ]] || continue&lt;br&gt;
  mkdir -p "$repo/.claude/agents"&lt;br&gt;
  ln -sf "$SHARED/agents/code-reviewer.md" \&lt;br&gt;
         "$repo/.claude/agents/code-reviewer.md"&lt;br&gt;
  ln -sf "$SHARED/hooks/pre-push" \&lt;br&gt;
         "$repo/.git/hooks/pre-push"&lt;br&gt;
  chmod +x "$repo/.git/hooks/pre-push"&lt;br&gt;
  echo "wired: $(basename "$repo")"&lt;br&gt;
done&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3z4oz6jiwutmy493rk8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3z4oz6jiwutmy493rk8.jpg" alt="Symlink topology — one .shared/ folder fanned out to nine repos" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;
**Run it once. Edit** `code-reviewer.md` **later and every repo picks up the change on the next push.** No copy, no drift.



&lt;p&gt;If you have one repo, the symlink trick is overkill — just put the files directly in &lt;code&gt;.claude/agents/&lt;/code&gt; and &lt;code&gt;.git/hooks/&lt;/code&gt;. The subagent and the hook are the part doing the work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The harder problem isn't sharing the rule. It's making myself willing to obey it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Soft warning, not hard block (and &lt;code&gt;--no-verify&lt;/code&gt; still works)
&lt;/h2&gt;

&lt;p&gt;The first version of the hook used &lt;code&gt;exit 1&lt;/code&gt; on &lt;code&gt;BLOCK:&lt;/code&gt; and forced me to amend or escape-hatch. I rewrote it within a day.&lt;/p&gt;

&lt;p&gt;I push during moments where stopping is expensive — the kid wakes up, the evening ends, the meeting starts in eight minutes. A hard block on a false positive doesn't help anyone; it just teaches me to disable the hook.&lt;/p&gt;

&lt;p&gt;The soft warning works because it changes the default. Default is don't push. Pressing Enter aborts; pressing &lt;code&gt;y&lt;/code&gt; proceeds.&lt;/p&gt;

&lt;p&gt;I read the verdict, decide in two seconds, and either fix or override. Four times in three weeks, the verdict was right and I went back to fix. Roughly ten times the verdict was wrong and I pressed &lt;code&gt;y&lt;/code&gt; and shipped.&lt;/p&gt;

&lt;p&gt;If I had set hard block, I'd have disabled the hook by week two. The override is what keeps the hook installed.&lt;/p&gt;

&lt;p&gt;This is the same lesson I learned with my &lt;a href="https://medium.com/p/db51a8d7cc74" rel="noopener noreferrer"&gt;pre-deploy script that refuses to add a staging environment&lt;/a&gt;: I keep using the tools that make the safe path easy without locking the risky path away.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push --no-verify&lt;/code&gt; bypasses every git hook, including this one. I don't try to "fix" that. If I need to ship a hotfix at 11pm and the reviewer is hallucinating about a deleted file, I want one well-known flag to skip the check, not a fight with my own tooling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The reviewer is a default-on layer. It's not a security gate.&lt;/strong&gt; Security gates belong in CI, where I can't &lt;code&gt;--no-verify&lt;/code&gt; past them. The reviewer's job is to catch the bugs I'd catch myself if I weren't tired.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I deliberately do not ask the reviewer
&lt;/h2&gt;

&lt;p&gt;I tried adding more checks at first. I removed most of them.&lt;/p&gt;

&lt;p&gt;The first version flagged every function over 30 lines for "consider extracting a helper." By the third push it had blocked a 45-line tenant migration that I had no intention of splitting — the SQL was inherently sequential. I deleted that rule the same evening. Same story with "magic numbers" — the reviewer kept flagging timezone offsets and HTTP status codes. Out.&lt;/p&gt;

&lt;p&gt;The reviewer does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Run tests (CI does)&lt;/li&gt;
&lt;li&gt;  Run the type checker (CI does)&lt;/li&gt;
&lt;li&gt;  Check formatting (&lt;code&gt;prettier --check&lt;/code&gt; does)&lt;/li&gt;
&lt;li&gt;  Look for style violations (taste, not bugs)&lt;/li&gt;
&lt;li&gt;  Suggest refactors (different mode of work)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It checks the things a human reviewer would catch in a hurried PR scan — swallowed exceptions, dropped &lt;code&gt;await&lt;/code&gt;s, schema drift, leaked secrets — and stays out of everything else. &lt;strong&gt;That narrow scope is why it runs in 20 seconds and why I trust the verdict enough to act on it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it flags everything I stop reading it.&lt;/p&gt;

&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9b5uqevrs7o64wgr6jvg.jpg" alt="Reviewer scope: swallowed exceptions, dropped awaits, schema drift, leaked secrets vs tests, type checks, formatting, naming" width="800" height="450"&gt;What this gets you
&lt;/h2&gt;

&lt;p&gt;Three weeks in, the receipts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Four real catches (two dropped &lt;code&gt;await&lt;/code&gt;s, one swallowed error, one debug &lt;code&gt;console.log&lt;/code&gt; of a JWT)&lt;/li&gt;
&lt;li&gt;  Roughly ten false positives, all dismissed by pressing &lt;code&gt;y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Zero "I disabled the hook because it was annoying" moments&lt;/li&gt;
&lt;li&gt;  A single canonical config across nine repos&lt;/li&gt;
&lt;li&gt;  About $0.40 in Opus calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The JWT one was the closest to a real incident. I'd added a &lt;code&gt;console.log(req.headers)&lt;/code&gt; while debugging a webhook signature mismatch, forgot to remove it, and went to push. The reviewer flagged the leaked token in five seconds. That alone earned the next year of the reviewer's existence.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.shared/&lt;/code&gt; symlink trick stops mattering when you only have one repo, but the subagent and the hook still work — just live in the repo directly.&lt;/p&gt;

&lt;p&gt;If you're already using Claude Code, the whole setup is one subagent file, one hook script, and an &lt;code&gt;install-hooks.sh&lt;/code&gt; if you have more than one repo. About 30 minutes from cold to first wired push.&lt;/p&gt;

&lt;p&gt;This is the third Claude Code workflow I've shipped this month that ends up being a short script. The other two — &lt;a href="https://medium.com/generative-ai/i-automated-away-an-hour-of-project-setup-with-a-claude-code-skill-1ff025e43814" rel="noopener noreferrer"&gt;a skill that turns an hour of project setup into 90 seconds&lt;/a&gt; and &lt;a href="https://generativeai.pub/how-i-added-persistent-semantic-memory-to-claude-code-in-15-minutes-9b91f9399a76" rel="noopener noreferrer"&gt;a memory layer that survives between sessions&lt;/a&gt; — follow the same pattern. Most of my wins lately are thirty lines of glue around something Claude Code already ships.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this was useful, you might also like &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a short, free email series on getting Claude Code to remember what matters between sessions.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>programming</category>
      <category>git</category>
      <category>ai</category>
    </item>
    <item>
      <title>My Own Content Pipeline Didn’t Have My Own Content. Here’s the Backfill That Fixed It.</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Sat, 18 Jul 2026 15:07:51 +0000</pubDate>
      <link>https://dev.to/danielrusnok/my-own-content-pipeline-didnt-have-my-own-content-heres-the-backfill-that-fixed-it-31ii</link>
      <guid>https://dev.to/danielrusnok/my-own-content-pipeline-didnt-have-my-own-content-heres-the-backfill-that-fixed-it-31ii</guid>
      <description>&lt;h3&gt;
  
  
  My Own Content Pipeline Didn’t Have My Own Content. Here’s the Backfill That Fixed&amp;nbsp;It.
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Three platforms, three different integration battles — and a parser bug that silently ate three of my articles.
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfkeyamzux7jck5oz8lk.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfkeyamzux7jck5oz8lk.png" alt="My Own Content Pipeline Didn’t Have My Own Content. Here’s the Backfill That Fixed It. cover image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three platforms, three different ways to hand you back your own history. | Generated with&amp;nbsp;ChatGPT&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not a member? Use&lt;/em&gt; &lt;a href="https://danielrusnok.medium.com/8f5c3efdeb02?source=friends_link&amp;amp;sk=763d630ebc58dfd77a2307f4f6b766ba" rel="noopener noreferrer"&gt;&lt;em&gt;this link.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;60 articles lived in my analytics dashboard. 0 &lt;strong&gt;of them had actual content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Article Forge&lt;/strong&gt; to manage everything I publish — drafts, &lt;a href="https://levelup.gitconnected.com/stop-rewriting-the-whole-article-section-scoped-edits-for-llm-content-tools-d704ec05c1e5" rel="noopener noreferrer"&gt;section-scoped AI edits&lt;/a&gt;, cross-posting from Medium to dev.to, analytics from all three platforms in one place.&lt;/p&gt;

&lt;p&gt;The whole point is that &lt;em&gt;my content lives in my own tool&lt;/em&gt;. But for months, only the posts I’d drafted inside Article Forge had their body text stored. Everything written before the tool existed was just a row in &lt;code&gt;article_analytics&lt;/code&gt; with a URL and zero context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One evening, I sat down to backfill. I expected one script. I wrote three.&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu3bi37rckp53ay9ov7k.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu3bi37rckp53ay9ov7k.png" alt="Illustration" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Architecture diagram showing Article Forge | Generated with&amp;nbsp;Claude&lt;/p&gt;




&lt;h3&gt;
  
  
  Dev.to — the platform that just&amp;nbsp;works
&lt;/h3&gt;

&lt;p&gt;Dev.to has a clean REST API. &lt;code&gt;/api/articles/me/published&lt;/code&gt; paginates through everything you've ever shipped. &lt;strong&gt;The catch: the list endpoint returns metadata only.&lt;/strong&gt; To get &lt;code&gt;body_markdown&lt;/code&gt;, you fetch each article individually via &lt;code&gt;/api/articles/{id}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The script is twenty lines of “list, then loop and fetch detail.” I wrote a dedupe by &lt;code&gt;publishedUrl&lt;/code&gt; so re-runs are safe, and linked to each new &lt;code&gt;articles&lt;/code&gt; row back to the corresponding &lt;code&gt;article_analytics&lt;/code&gt; row by &lt;code&gt;externalId&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Twenty articles inserted, twenty analytics linked, zero failures.&lt;/strong&gt; Five minutes of actual work.&lt;/p&gt;

&lt;p&gt;This is the version of “content backfill” that fits in a tweet. Then there’s Substack and Medium.&lt;/p&gt;




&lt;h3&gt;
  
  
  Substack — the platform that wants your&amp;nbsp;cookie
&lt;/h3&gt;

&lt;p&gt;Substack doesn’t have a public published-list API for owners. Or rather, it does, but &lt;strong&gt;it’s behind cookie auth&lt;/strong&gt;. The dashboard hits an endpoint called &lt;code&gt;post_management/published&lt;/code&gt; that returns a paginated list of your posts, including drafts. It accepts your &lt;code&gt;substack.sid&lt;/code&gt; cookie as the auth token.&lt;/p&gt;

&lt;p&gt;I already had this plumbing — the analytics sync uses the same endpoint to read view/open counts. The backfill enumeration was free. What was missing was the post body. For that, you call &lt;code&gt;https://{your-subdomain}.substack.com/api/v1/posts/{slug}&lt;/code&gt;, again with the cookie, and you get back full &lt;code&gt;body_html&lt;/code&gt;, cover image, subtitle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ten new articles inserted, nine linked to existing analytics rows, seven skipped because they already existed in the DB.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The auth model is honest. You don’t pretend a cookie is an API key. It is what it is — a session, scoped to your account, that you paste into your tool’s settings page. Once you accept that, the API surface is decent.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkidjdlb11p0ndxu3kt9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkidjdlb11p0ndxu3kt9.png" alt="Illustration" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Side-by-side comparison of three platform integration approaches | Generated with&amp;nbsp;Claude&lt;/p&gt;

&lt;p&gt;If you like reading about the small tools I build for my own workflow, I turned one of them into &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series you can follow along with.&lt;/p&gt;




&lt;h3&gt;
  
  
  Medium — the platform that hands you a zip&amp;nbsp;file
&lt;/h3&gt;

&lt;p&gt;Medium has no API for reading your own historical articles. &lt;strong&gt;You can pull the latest ten from the public RSS feed, and that’s it.&lt;/strong&gt; If you want everything, you go to &lt;em&gt;Settings → Security and apps → Download your information&lt;/em&gt;, wait for an email, click a link, and download a zip of HTML files.&lt;/p&gt;

&lt;p&gt;I downloaded the zip. Eighty-eight HTML files. Three drafts (filenames start with &lt;code&gt;draft_&lt;/code&gt;), about thirty short "responses" (Medium's name for comments — stored as posts in the export), and the rest were real articles.&lt;/p&gt;

&lt;p&gt;I added &lt;code&gt;node-html-parser&lt;/code&gt; as a dependency and wrote a parser. The Medium export structure is consistent — every file is an &lt;code&gt;&amp;lt;article class="h-entry"&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;lt;h1 class="p-name"&amp;gt;&lt;/code&gt; for the title, &lt;code&gt;&amp;lt;section data-field="subtitle"&amp;gt;&lt;/code&gt; for the subtitle, &lt;code&gt;&amp;lt;section data-field="body"&amp;gt;&lt;/code&gt; for the body, and &lt;code&gt;&amp;lt;time class="dt-published"&amp;gt;&lt;/code&gt; for the date.&lt;/p&gt;

&lt;p&gt;Dry-run reported: 53 articles to insert, 29 short responses skipped, &lt;strong&gt;3 unparseable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Three? On a stable, well-formed export format? With a parser I’d just verified worked on the other 53?&lt;/p&gt;




&lt;h3&gt;
  
  
  The silent&amp;nbsp;bug
&lt;/h3&gt;

&lt;p&gt;I opened one of the three files. The HTML was fine. Tag balance was fine. &lt;code&gt;&amp;lt;article class="h-entry"&amp;gt;&lt;/code&gt; was right where I expected it. I dropped into a one-line node REPL:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 0  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1.p-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Zero articles. One title.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The title element is &lt;em&gt;inside&lt;/em&gt; the article element. If the parser found one, it should find the other. Unless the parser thinks the article closed before the title.&lt;/p&gt;

&lt;p&gt;I scanned for what might trip a permissive HTML parser. The three “broken” files all had something in common: code blocks. &lt;strong&gt;Long&lt;/strong&gt; &lt;code&gt;**&amp;lt;pre&amp;gt;**&lt;/code&gt; &lt;strong&gt;blocks containing JavaScript with template literals, comparison operators, JSX-ish snippets&lt;/strong&gt; — all the things that produce raw &lt;code&gt;&amp;lt;&lt;/code&gt; characters inside what should be opaque text.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;node-html-parser&lt;/code&gt; doesn't fully escape &lt;code&gt;&amp;lt;&lt;/code&gt; inside &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;. When it scans, it sees what looks like a tag, applies its auto-closing rules, and &lt;strong&gt;silently decides that the wrapping&lt;/strong&gt; &lt;code&gt;**&amp;lt;article&amp;gt;**&lt;/code&gt; &lt;strong&gt;ended way earlier than it actually did&lt;/strong&gt;. Outer selectors miss. Inner selectors that don't depend on the wrapping element still work.&lt;/p&gt;

&lt;p&gt;The fix is one line. Instead of:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;article.h-entry&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1.p-name&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;Do:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1.p-name&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;&lt;strong&gt;Query from the document root.&lt;/strong&gt; Don’t assume the wrapping element is reliably reachable just because the source HTML is valid.&lt;/p&gt;

&lt;p&gt;Re-ran the script. Three “unparseable” files dropped to zero. One was new content (got inserted), two were already in Article Forge as drafts and matched my title-fallback dedupe.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv7p7s7c52g4qn7jesfcs.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv7p7s7c52g4qn7jesfcs.png" alt="Illustration" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simulated terminal output showing the dry-run results | Generated with&amp;nbsp;Claude&lt;/p&gt;




&lt;h3&gt;
  
  
  The deduplication logic that saved me&amp;nbsp;twice
&lt;/h3&gt;

&lt;p&gt;I mentioned dedupe by &lt;code&gt;publishedUrl&lt;/code&gt; earlier. That's the primary key — if a URL already exists in the &lt;code&gt;articles&lt;/code&gt; table, skip it. Works for dev.to and Substack, where every published post has a stable URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Medium broke this assumption.&lt;/strong&gt; I had eight articles already drafted in Article Forge before the backfill. They had no &lt;code&gt;publishedUrl&lt;/code&gt; yet because they were still drafts. The ZIP export didn't know about my internal drafts, and my internal drafts didn't have Medium URLs.&lt;/p&gt;

&lt;p&gt;The fallback: &lt;strong&gt;normalized title matching&lt;/strong&gt;. Strip punctuation, lowercase, compare. It caught all eight. Not elegant, but it prevented eight duplicate rows that would have confused every downstream query.&lt;/p&gt;

&lt;p&gt;If you’re building any kind of content sync, plan for the case where the same content exists on both sides with no shared identifier. &lt;strong&gt;URL-only dedupe works until it doesn’t.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What the unified data actually&amp;nbsp;unlocked
&lt;/h3&gt;

&lt;p&gt;Eighty-something rows added across three platforms in a few hours. The row count isn’t the point. &lt;strong&gt;Every analytics row now has a corresponding article row with the actual content sitting next to the view count.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The “related articles” feature in my &lt;a href="https://medium.com/gitconnected/getting-claude-to-return-strict-json-without-drift-a-system-prompt-template-9ee1b4eed5c4" rel="noopener noreferrer"&gt;AI-powered optimizer&lt;/a&gt; can finally see my entire archive instead of just the things I drafted in-tool. When I’m writing about background jobs, it knows I already published &lt;a href="https://levelup.gitconnected.com/5-functions-1-route-0-month-my-entire-saas-background-job-architecture-24363b6f45aa" rel="noopener noreferrer"&gt;a deep dive on Inngest&lt;/a&gt; and can suggest an internal link.&lt;/p&gt;

&lt;p&gt;The Medium → dev.to cross-post sync now has the full Medium body to compare against, not a 200-character RSS snippet. &lt;strong&gt;Drift detection between platforms actually works.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the simplest win: I can search my own articles by content, not just by title. “Which article mentioned &lt;code&gt;Promise.allSettled&lt;/code&gt;?" is now a database query, not a manual hunt across three browser tabs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three things I’ll keep&amp;nbsp;doing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. APIs aren’t the only data source.&lt;/strong&gt; A zip of HTML is a perfectly good integration if it’s the only thing the platform offers. Write a parser, handle edge cases, and move on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Dedupe by URL with a title fallback.&lt;/strong&gt; URL-only dedupe missed eight Medium drafts that hadn’t been published yet. A normalized-title fallback caught them all. Two layers of matching cost almost nothing and prevent real problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. When a permissive parser disagrees with the source, look at what’s &lt;em&gt;inside&lt;/em&gt; the elements.&lt;/strong&gt; Code blocks with raw &lt;code&gt;&amp;lt;&lt;/code&gt; will lie to your parser long before the parser admits it's confused.&lt;/p&gt;

&lt;p&gt;The next thing on the list: backfilling Medium’s &lt;code&gt;external_url&lt;/code&gt; mismatch so analytics rows actually link correctly. But that's a different evening.&lt;/p&gt;




&lt;h3&gt;
  
  
  External Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/taoqf/node-html-parser" rel="noopener noreferrer"&gt;node-html-parser&lt;/a&gt; — the fast HTML parser that tripped on raw &amp;lt; in pre blocks (GitHub)&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://developers.forem.com/api/v1" rel="noopener noreferrer"&gt;Forem API v1&lt;/a&gt; — the dev.to REST API used for the cleanest backfill&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://help.medium.com/hc/en-us/articles/115004745787-Export-your-account-data" rel="noopener noreferrer"&gt;Medium data export&lt;/a&gt; — official guide for downloading your information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want more of this in your inbox, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; is a short, free email series where I walk through setups like this one.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Our Next.js App Crashed Every 24 Hours. Here Are the Six Memory Fixes.</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Thu, 16 Jul 2026 15:08:29 +0000</pubDate>
      <link>https://dev.to/danielrusnok/our-nextjs-app-crashed-every-24-hours-here-are-the-six-memory-fixes-2mj1</link>
      <guid>https://dev.to/danielrusnok/our-nextjs-app-crashed-every-24-hours-here-are-the-six-memory-fixes-2mj1</guid>
      <description>&lt;p&gt;I opened the Render dashboard on Monday morning and saw the same thing I had seen every day for a week. &lt;strong&gt;Memory at 100%, service restarting.&lt;/strong&gt; Our Next.js app was eating all 512MB within ~24 hours, then OOM-killing itself.&lt;/p&gt;

&lt;p&gt;I spent a day digging through the codebase with &lt;code&gt;process.memoryUsage()&lt;/code&gt; logs and Render's built-in metrics. I found six separate problems. One of them cut memory usage by more than half in a single deploy.&lt;/p&gt;

&lt;p&gt;Here is every fix, in order of impact.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Next.js 16 (App Router)&lt;/strong&gt; with Drizzle ORM, PostgreSQL, Clerk auth, Stripe payments, Resend for transactional email, and Inngest for background jobs. I covered the &lt;a href="https://levelup.gitconnected.com/5-functions-1-route-0-month-my-entire-saas-background-job-architecture-24363b6f45aa" rel="noopener noreferrer"&gt;full background job setup in a previous post&lt;/a&gt; — five functions, one route, $0/month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hosting:&lt;/strong&gt; Render.com Starter plan — 512MB RAM, $7/month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The symptom:&lt;/strong&gt; no sudden spikes. Just a &lt;strong&gt;steady upward line on the Render memory graph&lt;/strong&gt; that ended in an OOM-kill roughly every 24 hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix That Cut Memory in Half
&lt;/h2&gt;

&lt;p&gt;The Resend email SDK was being created with &lt;code&gt;new Resend(apiKey)&lt;/code&gt; inside 10 different files. API routes, Inngest functions, utility helpers. &lt;strong&gt;Every request spun up a new client with its own HTTP connections, event listeners, and internal buffers.&lt;/strong&gt; None of them got cleaned up between requests.&lt;/p&gt;

&lt;p&gt;This is what it looked like:&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="c1"&gt;// ❌ In 10 different files&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;resend&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;Resend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RESEND_API_KEY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the fix — a lazy singleton in one file:&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="c1"&gt;// ✅ lib/resend.ts&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Resend&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getResend&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Resend&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;instance&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;Resend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RESEND_API_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every handler now calls &lt;code&gt;getResend()&lt;/code&gt;. &lt;strong&gt;One instance for the entire process lifetime.&lt;/strong&gt; I already had this pattern for Stripe and Anthropic — Resend slipped through because it was added later, in a hurry, across multiple files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory dropped from ~93% to ~35% immediately after deploy.&lt;/strong&gt; This single change was responsible for more than half of the total improvement.&lt;/p&gt;




&lt;h2&gt;
  
  
  V8 Knows Your Container Limit. It Still Overallocates.
&lt;/h2&gt;

&lt;p&gt;Node.js 20+ reads cgroup limits and auto-sizes the V8 heap based on your container's available memory. So in theory, it should know about the 512MB limit. &lt;strong&gt;In practice, the auto-detected heap still leaves too little room for everything else&lt;/strong&gt; — non-heap memory, native buffers, connection pools, and the OS itself.&lt;/p&gt;

&lt;p&gt;On my 512MB container, V8's auto-detected heap was larger than what the process could safely use. Memory would climb slowly — not because of a leak, but because &lt;strong&gt;V8 was not running GC aggressively enough for the remaining headroom.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fix is one flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--max-old-space-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;384 server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting it to &lt;strong&gt;~75% of the container limit&lt;/strong&gt; gives V8 a tighter budget. It starts garbage collecting earlier, well before the container runs out.&lt;/p&gt;

&lt;p&gt;One gotcha I hit: I initially set &lt;code&gt;NODE_OPTIONS=--max-old-space-size=384&lt;/code&gt; as a Render environment variable. That applies to the build step too. The TypeScript compiler also runs under Node — and &lt;strong&gt;it crashed at 384MB during the build.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fix: set the flag only in the start command, not as a global env var.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// Render start &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;not an &lt;span class="nb"&gt;env &lt;/span&gt;var&lt;span class="o"&gt;)&lt;/span&gt;
node &lt;span class="nt"&gt;--max-old-space-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;384 .next/standalone/server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the singleton fix brought memory down to ~35%, this flag is what &lt;strong&gt;prevented it from slowly climbing back up.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you would rather get my solo-dev build-and-debug notes broken into a few short, copy-paste steps in your inbox, I put the essentials into &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Four More Leaks I Found
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clerk Admin SDK — Same Bug, Different Package
&lt;/h3&gt;

&lt;p&gt;Same pattern as Resend, smaller scale. &lt;code&gt;createClerkClient()&lt;/code&gt; was called inside request handlers in 3 files instead of being a singleton. &lt;strong&gt;Same lazy-init fix: one&lt;/strong&gt; &lt;code&gt;**getClerkAdmin()**&lt;/code&gt; &lt;strong&gt;function, one file, one instance.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Unbounded In-Memory Rate Limiter
&lt;/h3&gt;

&lt;p&gt;My &lt;code&gt;/api/track&lt;/code&gt; analytics endpoint used a global &lt;code&gt;Map&lt;/code&gt; for rate limiting. Cleanup only kicked in when the map exceeded 1,000 entries. &lt;strong&gt;On a 512MB container, 1,000 entries of IP strings plus timestamps and counters adds up.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fix: hard cap at 500 entries with LRU-style eviction, plus a &lt;code&gt;setInterval&lt;/code&gt; cleanup every 2 minutes.&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;cleanup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;rateLimitMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;rateLimitMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unref&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.unref()&lt;/code&gt; call matters. Without it, &lt;strong&gt;the interval keeps the Node process alive&lt;/strong&gt; and it will not exit cleanly during deploys or restarts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cron Jobs Loading Everything Into Memory
&lt;/h3&gt;

&lt;p&gt;Two Inngest cron functions had memory problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics cleanup&lt;/strong&gt; used Drizzle's &lt;code&gt;.returning({ id })&lt;/code&gt; on a bulk DELETE. This loaded every deleted row ID into an array before returning. On a table with thousands of expired rows, that array gets big. Fixed with &lt;strong&gt;raw SQL that returns only&lt;/strong&gt; &lt;code&gt;**rowCount**&lt;/code&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orphan image cleanup&lt;/strong&gt; listed the entire Cloudflare R2 bucket three separate times — once per context (sequences, emails, subscribers). Fixed to &lt;strong&gt;list the bucket once and filter in memory.&lt;/strong&gt; Three API calls became one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Pool With a Silent Zero-Timeout Default
&lt;/h3&gt;

&lt;p&gt;The PostgreSQL connection pool was created with &lt;code&gt;new Pool({ connectionString })&lt;/code&gt; and nothing else. Most defaults are fine — &lt;code&gt;max: 10&lt;/code&gt;, &lt;code&gt;idleTimeoutMillis: 10_000&lt;/code&gt;. But one default is dangerous: &lt;code&gt;**connectionTimeoutMillis**&lt;/code&gt; &lt;strong&gt;defaults to 0, which means "wait forever."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a connection attempt hangs — slow DNS, unresponsive database, network hiccup — the request sits there holding memory and a pool slot indefinitely. &lt;strong&gt;On a 512MB container, one stuck connection is all it takes to start a cascade.&lt;/strong&gt;&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;pool&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;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;idleTimeoutMillis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;connectionTimeoutMillis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding &lt;code&gt;connectionTimeoutMillis: 5_000&lt;/code&gt; means a stuck attempt fails fast instead of waiting forever. &lt;strong&gt;I would not have found this without reading the node-postgres docs during the debugging session.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline memory&lt;/td&gt;
&lt;td&gt;~93% (475MB)&lt;/td&gt;
&lt;td&gt;~35% (180MB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to OOM&lt;/td&gt;
&lt;td&gt;~24 hours&lt;/td&gt;
&lt;td&gt;Stable (no crash)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory after 24h&lt;/td&gt;
&lt;td&gt;OOM crash&lt;/td&gt;
&lt;td&gt;~45% plateau&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Resend singleton was the biggest single win&lt;/strong&gt; — more than half of the total improvement in one deploy. The &lt;code&gt;--max-old-space-size&lt;/code&gt; flag prevented the slow climb back up by giving V8 a tighter GC budget.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Checklist
&lt;/h2&gt;

&lt;p&gt;If you are running Next.js on a memory-constrained container, check for these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;SDK clients&lt;/strong&gt; (&lt;code&gt;new Client()&lt;/code&gt;) created inside request handlers instead of module-level singletons&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Missing&lt;/strong&gt; &lt;code&gt;**--max-old-space-size**&lt;/code&gt; — even on Node 20+ where cgroup detection works, an explicit cap gives V8 a tighter GC budget&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;**--max-old-space-size**&lt;/code&gt; &lt;strong&gt;set as env var&lt;/strong&gt; instead of start command only (breaks builds)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Unbounded&lt;/strong&gt; &lt;code&gt;**Map**&lt;/code&gt; &lt;strong&gt;/&lt;/strong&gt; &lt;code&gt;**Set**&lt;/code&gt; &lt;strong&gt;/&lt;/strong&gt; &lt;code&gt;**Array**&lt;/code&gt; at module level without eviction or size cap&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;**.returning()**&lt;/code&gt; on bulk DELETE/UPDATE loading all results into memory&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Database pool&lt;/strong&gt; with default &lt;code&gt;connectionTimeoutMillis: 0&lt;/code&gt; — set an explicit timeout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these take &lt;strong&gt;5–10 minutes to fix&lt;/strong&gt; once you know what to look for.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Took Away From This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Most Node.js memory issues on small containers are not traditional memory leaks.&lt;/strong&gt; They are per-request allocations that should be singletons, combined with V8 not running GC aggressively enough for the available headroom.&lt;/p&gt;

&lt;p&gt;Fix those two patterns and you will likely be fine on 512MB. I have been running stable for weeks on Render's cheapest plan — &lt;strong&gt;no crashes, no restarts, memory plateaus at ~45%.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want more of how I build and ship as a solo developer landing in your inbox, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; walks you through the setup over a few short emails — free.&lt;/p&gt;




&lt;h2&gt;
  
  
  External Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://nodejs.org/api/cli.html" rel="noopener noreferrer"&gt;Node.js CLI docs — --max-old-space-size&lt;/a&gt; — the official V8 heap limit flag documentation&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://resend.com/docs/send-with-nodejs" rel="noopener noreferrer"&gt;Resend Node.js SDK&lt;/a&gt; — the email SDK referenced in this article&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://orm.drizzle.team/" rel="noopener noreferrer"&gt;Drizzle ORM&lt;/a&gt; — TypeScript-first SQL ORM used in the stack&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.inngest.com/" rel="noopener noreferrer"&gt;Inngest&lt;/a&gt; — background job platform for the cron functions&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://node-postgres.com/apis/pool" rel="noopener noreferrer"&gt;node-postgres Pool API&lt;/a&gt; — connection pool configuration and defaults&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Daniel Rusnok is a software developer and solo maker building &lt;a href="https://drippery.app" rel="noopener noreferrer"&gt;Drippery&lt;/a&gt; — a dead-simple drip email tool for creators. He writes about TypeScript, Next.js, and the realities of shipping software alone.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I automated away an hour of project setup with a Claude Code skill</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Tue, 14 Jul 2026 15:05:36 +0000</pubDate>
      <link>https://dev.to/danielrusnok/i-automated-away-an-hour-of-project-setup-with-a-claude-code-skill-1j2j</link>
      <guid>https://dev.to/danielrusnok/i-automated-away-an-hour-of-project-setup-with-a-claude-code-skill-1j2j</guid>
      <description>&lt;p&gt;&lt;em&gt;Not&amp;nbsp;a&amp;nbsp;member?&amp;nbsp;Use&amp;nbsp;this&amp;nbsp;link.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every&amp;nbsp;new&amp;nbsp;SaaS&amp;nbsp;project&amp;nbsp;I&amp;nbsp;start&amp;nbsp;used&amp;nbsp;to&amp;nbsp;eat&amp;nbsp;an&amp;nbsp;hour&amp;nbsp;of&amp;nbsp;clicking&amp;nbsp;—&amp;nbsp;GitHub&amp;nbsp;repo,&amp;nbsp;&lt;code&gt;npx&amp;nbsp;create-next-app&lt;/code&gt;,&amp;nbsp;copy-paste&amp;nbsp;the&amp;nbsp;DB&amp;nbsp;config&amp;nbsp;from&amp;nbsp;my&amp;nbsp;last&amp;nbsp;project,&amp;nbsp;walk&amp;nbsp;through&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;dashboard,&amp;nbsp;paste&amp;nbsp;env&amp;nbsp;vars,&amp;nbsp;wait&amp;nbsp;for&amp;nbsp;the&amp;nbsp;first&amp;nbsp;deploy&amp;nbsp;to&amp;nbsp;fail&amp;nbsp;because&amp;nbsp;I&amp;nbsp;forgot&amp;nbsp;&lt;code&gt;node&amp;nbsp;server.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I&amp;nbsp;did&amp;nbsp;this&amp;nbsp;three&amp;nbsp;times&amp;nbsp;in&amp;nbsp;a&amp;nbsp;row&lt;/strong&gt;&amp;nbsp;for&amp;nbsp;three&amp;nbsp;sibling&amp;nbsp;projects.&amp;nbsp;Then&amp;nbsp;I&amp;nbsp;automated&amp;nbsp;the&amp;nbsp;whole&amp;nbsp;thing&amp;nbsp;into&amp;nbsp;a&amp;nbsp;90-second&amp;nbsp;command.&lt;/p&gt;

&lt;h2&gt;
  
  
  The&amp;nbsp;setup&amp;nbsp;tax
&lt;/h2&gt;

&lt;p&gt;I&amp;nbsp;keep&amp;nbsp;a&amp;nbsp;folder&amp;nbsp;called&amp;nbsp;&lt;code&gt;foundary-tools&lt;/code&gt;&amp;nbsp;where&amp;nbsp;each&amp;nbsp;subdirectory&amp;nbsp;is&amp;nbsp;a&amp;nbsp;separate&amp;nbsp;SaaS&amp;nbsp;or&amp;nbsp;internal&amp;nbsp;tool.&amp;nbsp;Three&amp;nbsp;projects&amp;nbsp;in,&amp;nbsp;&lt;strong&gt;every&amp;nbsp;new&amp;nbsp;sibling&amp;nbsp;shares&amp;nbsp;90%&amp;nbsp;of&amp;nbsp;the&amp;nbsp;same&amp;nbsp;scaffolding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same&amp;nbsp;Next.js&amp;nbsp;16&amp;nbsp;+&amp;nbsp;React&amp;nbsp;19&amp;nbsp;skeleton.&amp;nbsp;Same&amp;nbsp;Drizzle&amp;nbsp;+&amp;nbsp;postgres-js&amp;nbsp;setup.&amp;nbsp;Same&amp;nbsp;Tailwind&amp;nbsp;v4&amp;nbsp;config.&amp;nbsp;Same&amp;nbsp;&lt;code&gt;server.js&lt;/code&gt;&amp;nbsp;that&amp;nbsp;&lt;strong&gt;binds&amp;nbsp;IPv4&amp;nbsp;explicitly&amp;nbsp;because&amp;nbsp;Render's&amp;nbsp;port&amp;nbsp;scanner&amp;nbsp;doesn't&amp;nbsp;see&amp;nbsp;IPv6-only&amp;nbsp;processes&lt;/strong&gt;.&amp;nbsp;Same&amp;nbsp;&lt;code&gt;.gitignore&lt;/code&gt;.&amp;nbsp;Same&amp;nbsp;&lt;code&gt;tsconfig.json&lt;/code&gt;.&amp;nbsp;Even&amp;nbsp;the&amp;nbsp;&lt;a href="https://levelup.gitconnected.com/5-functions-1-route-0-month-my-entire-saas-background-job-architecture-24363b6f45aa" rel="noopener noreferrer"&gt;background&amp;nbsp;job&amp;nbsp;architecture&lt;/a&gt;&amp;nbsp;is&amp;nbsp;shared.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The&amp;nbsp;only&amp;nbsp;thing&amp;nbsp;that&amp;nbsp;changes&amp;nbsp;between&amp;nbsp;projects&amp;nbsp;is&amp;nbsp;the&amp;nbsp;domain&amp;nbsp;logic&lt;/strong&gt;&amp;nbsp;—&amp;nbsp;about&amp;nbsp;5%&amp;nbsp;of&amp;nbsp;the&amp;nbsp;initial&amp;nbsp;commit.&lt;/p&gt;

&lt;p&gt;So&amp;nbsp;the&amp;nbsp;other&amp;nbsp;95%&amp;nbsp;was&amp;nbsp;me,&amp;nbsp;manually,&amp;nbsp;every&amp;nbsp;single&amp;nbsp;time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;gh&amp;nbsp;repo&amp;nbsp;create&amp;nbsp;danielrusnok/&amp;lt;name&amp;gt;&amp;nbsp;--private&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Copy&amp;nbsp;a&amp;nbsp;Next.js&amp;nbsp;skeleton&amp;nbsp;from&amp;nbsp;the&amp;nbsp;last&amp;nbsp;project&lt;/li&gt;
&lt;li&gt;  Rename&amp;nbsp;&lt;code&gt;"name"&lt;/code&gt;&amp;nbsp;in&amp;nbsp;&lt;code&gt;package.json&lt;/code&gt;,&amp;nbsp;update&amp;nbsp;&lt;code&gt;CLAUDE.md&lt;/code&gt;,&amp;nbsp;update&amp;nbsp;the&amp;nbsp;metadata&amp;nbsp;in&amp;nbsp;&lt;code&gt;layout.tsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Wire&amp;nbsp;Drizzle&amp;nbsp;against&amp;nbsp;the&amp;nbsp;shared&amp;nbsp;Postgres,&amp;nbsp;pick&amp;nbsp;a&amp;nbsp;unique&amp;nbsp;&lt;code&gt;pgSchema&lt;/code&gt;&amp;nbsp;name&lt;/li&gt;
&lt;li&gt;  Paste&amp;nbsp;the&amp;nbsp;specific&amp;nbsp;&lt;code&gt;server.js&lt;/code&gt;&amp;nbsp;with&amp;nbsp;the&amp;nbsp;&lt;code&gt;0.0.0.0&lt;/code&gt;&amp;nbsp;bind&amp;nbsp;trick&lt;/li&gt;
&lt;li&gt;  Open&amp;nbsp;dashboard.render.com,&amp;nbsp;click&amp;nbsp;New&amp;nbsp;→&amp;nbsp;Web&amp;nbsp;Service,&amp;nbsp;connect&amp;nbsp;repo,&amp;nbsp;fill&amp;nbsp;in&amp;nbsp;build/start&amp;nbsp;commands,&amp;nbsp;paste&amp;nbsp;&lt;code&gt;DATABASE_URL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Commit,&amp;nbsp;push,&amp;nbsp;wait&amp;nbsp;3&amp;nbsp;minutes,&amp;nbsp;watch&amp;nbsp;the&amp;nbsp;first&amp;nbsp;deploy&amp;nbsp;fail&amp;nbsp;because&amp;nbsp;I&amp;nbsp;typed&amp;nbsp;something&amp;nbsp;wrong&lt;/li&gt;
&lt;li&gt;  Fix,&amp;nbsp;push&amp;nbsp;again,&amp;nbsp;wait&amp;nbsp;another&amp;nbsp;3&amp;nbsp;minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;An&amp;nbsp;hour,&amp;nbsp;easily.&lt;/strong&gt;&amp;nbsp;And&amp;nbsp;at&amp;nbsp;least&amp;nbsp;twice&amp;nbsp;I&amp;nbsp;deployed&amp;nbsp;a&amp;nbsp;project&amp;nbsp;that&amp;nbsp;was&amp;nbsp;silently&amp;nbsp;missing&amp;nbsp;an&amp;nbsp;env&amp;nbsp;var&amp;nbsp;because&amp;nbsp;I&amp;nbsp;was&amp;nbsp;tired&amp;nbsp;and&amp;nbsp;skipped&amp;nbsp;a&amp;nbsp;step.&lt;/p&gt;

&lt;h2&gt;
  
  
  How&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;skills&amp;nbsp;work
&lt;/h2&gt;

&lt;p&gt;If&amp;nbsp;you&amp;nbsp;use&amp;nbsp;Claude&amp;nbsp;Code,&amp;nbsp;a&amp;nbsp;"skill"&amp;nbsp;is&amp;nbsp;&lt;strong&gt;a&amp;nbsp;procedural&amp;nbsp;playbook&amp;nbsp;Claude&amp;nbsp;loads&amp;nbsp;from&lt;/strong&gt;&amp;nbsp;&lt;code&gt;**~/.claude/skills/**&lt;/code&gt;.&amp;nbsp;Each&amp;nbsp;skill&amp;nbsp;is&amp;nbsp;a&amp;nbsp;directory&amp;nbsp;with&amp;nbsp;a&amp;nbsp;&lt;code&gt;SKILL.md&lt;/code&gt;&amp;nbsp;—&amp;nbsp;frontmatter&amp;nbsp;describing&amp;nbsp;when&amp;nbsp;to&amp;nbsp;trigger&amp;nbsp;(natural-language&amp;nbsp;phrases),&amp;nbsp;plus&amp;nbsp;step-by-step&amp;nbsp;instructions&amp;nbsp;for&amp;nbsp;Claude&amp;nbsp;to&amp;nbsp;follow.&lt;/p&gt;

&lt;p&gt;Skills&amp;nbsp;can&amp;nbsp;include&amp;nbsp;helper&amp;nbsp;scripts.&amp;nbsp;&lt;strong&gt;You&amp;nbsp;delegate&amp;nbsp;judgment&amp;nbsp;to&amp;nbsp;the&amp;nbsp;LLM&amp;nbsp;and&amp;nbsp;deterministic&amp;nbsp;work&amp;nbsp;to&amp;nbsp;scripts.&lt;/strong&gt;&amp;nbsp;I&amp;nbsp;leaned&amp;nbsp;into&amp;nbsp;this&amp;nbsp;split&amp;nbsp;even&amp;nbsp;harder&amp;nbsp;when&amp;nbsp;I&amp;nbsp;&lt;a href="https://generativeai.pub/how-i-added-persistent-semantic-memory-to-claude-code-in-15-minutes-9b91f9399a76" rel="noopener noreferrer"&gt;added&amp;nbsp;persistent&amp;nbsp;memory&amp;nbsp;to&amp;nbsp;Claude&amp;nbsp;Code&lt;/a&gt;&amp;nbsp;—&amp;nbsp;same&amp;nbsp;principle,&amp;nbsp;different&amp;nbsp;tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The&amp;nbsp;division&amp;nbsp;I&amp;nbsp;landed&amp;nbsp;on:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Claude&amp;nbsp;handles&lt;/strong&gt;:&amp;nbsp;asking&amp;nbsp;the&amp;nbsp;user&amp;nbsp;for&amp;nbsp;inputs,&amp;nbsp;confirming&amp;nbsp;destructive&amp;nbsp;actions,&amp;nbsp;interpreting&amp;nbsp;errors&amp;nbsp;from&amp;nbsp;&lt;code&gt;gh&lt;/code&gt;&amp;nbsp;/&amp;nbsp;&lt;code&gt;npm&lt;/code&gt;&amp;nbsp;/&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;API,&amp;nbsp;deciding&amp;nbsp;whether&amp;nbsp;to&amp;nbsp;retry&amp;nbsp;or&amp;nbsp;escalate.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Python&amp;nbsp;handles&lt;/strong&gt;:&amp;nbsp;walking&amp;nbsp;a&amp;nbsp;template&amp;nbsp;directory,&amp;nbsp;substituting&amp;nbsp;placeholders,&amp;nbsp;reading&amp;nbsp;env&amp;nbsp;vars&amp;nbsp;from&amp;nbsp;sibling&amp;nbsp;projects,&amp;nbsp;POSTing&amp;nbsp;to&amp;nbsp;Render's&amp;nbsp;REST&amp;nbsp;API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't&amp;nbsp;make&amp;nbsp;the&amp;nbsp;LLM&amp;nbsp;do&amp;nbsp;regex&amp;nbsp;on&lt;/strong&gt;&amp;nbsp;&lt;code&gt;**package.json**&lt;/code&gt;&lt;strong&gt;.&lt;/strong&gt;&amp;nbsp;Don't&amp;nbsp;make&amp;nbsp;the&amp;nbsp;script&amp;nbsp;decide&amp;nbsp;whether&amp;nbsp;to&amp;nbsp;retry&amp;nbsp;a&amp;nbsp;failed&amp;nbsp;network&amp;nbsp;call.&amp;nbsp;Each&amp;nbsp;does&amp;nbsp;what&amp;nbsp;it's&amp;nbsp;good&amp;nbsp;at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nine&amp;nbsp;steps,&amp;nbsp;three&amp;nbsp;approval&amp;nbsp;gates
&lt;/h2&gt;

&lt;p&gt;I&amp;nbsp;named&amp;nbsp;the&amp;nbsp;skill&amp;nbsp;&lt;code&gt;foundary-new-project&lt;/code&gt;.&amp;nbsp;It&amp;nbsp;triggers&amp;nbsp;on&amp;nbsp;phrases&amp;nbsp;like&amp;nbsp;"nový&amp;nbsp;foundary&amp;nbsp;projekt"&amp;nbsp;or&amp;nbsp;"new&amp;nbsp;foundary&amp;nbsp;project"&amp;nbsp;—&amp;nbsp;&lt;strong&gt;same&amp;nbsp;natural-language&amp;nbsp;entry&amp;nbsp;point&amp;nbsp;as&amp;nbsp;every&amp;nbsp;other&amp;nbsp;skill&amp;nbsp;I&amp;nbsp;use&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The&amp;nbsp;workflow&amp;nbsp;is&amp;nbsp;nine&amp;nbsp;steps&lt;/strong&gt;,&amp;nbsp;three&amp;nbsp;of&amp;nbsp;which&amp;nbsp;require&amp;nbsp;my&amp;nbsp;explicit&amp;nbsp;approval:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Validate&amp;nbsp;&amp;amp;&amp;nbsp;read&amp;nbsp;secrets&amp;nbsp;from&amp;nbsp;sibling&amp;nbsp;&lt;code&gt;.env&lt;/code&gt;&amp;nbsp;files&lt;/li&gt;
&lt;li&gt; Scaffold&amp;nbsp;the&amp;nbsp;template&amp;nbsp;into&amp;nbsp;&lt;code&gt;~/foundary-tools/&amp;lt;name&amp;gt;/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Run&amp;nbsp;&lt;code&gt;npm&amp;nbsp;install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Smoke-build&amp;nbsp;with&amp;nbsp;&lt;code&gt;npm&amp;nbsp;run&amp;nbsp;build&lt;/code&gt;&amp;nbsp;—&amp;nbsp;fail&amp;nbsp;fast&amp;nbsp;before&amp;nbsp;anything&amp;nbsp;external&amp;nbsp;happens&lt;/li&gt;
&lt;li&gt; &lt;code&gt;git&amp;nbsp;init&lt;/code&gt;&amp;nbsp;+&amp;nbsp;first&amp;nbsp;commit&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Approval&amp;nbsp;gate&lt;/strong&gt;:&amp;nbsp;create&amp;nbsp;GitHub&amp;nbsp;repo,&amp;nbsp;push&lt;/li&gt;
&lt;li&gt; Fetch&amp;nbsp;Render&amp;nbsp;owner&amp;nbsp;ID&amp;nbsp;(cached&amp;nbsp;after&amp;nbsp;the&amp;nbsp;first&amp;nbsp;run)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Approval&amp;nbsp;gate&lt;/strong&gt;:&amp;nbsp;create&amp;nbsp;Render&amp;nbsp;web-service&amp;nbsp;via&amp;nbsp;API&lt;/li&gt;
&lt;li&gt; Update&amp;nbsp;CLAUDE.md&amp;nbsp;with&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;service&amp;nbsp;ID&amp;nbsp;and&amp;nbsp;print&amp;nbsp;a&amp;nbsp;recap&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The&amp;nbsp;approval&amp;nbsp;gates&amp;nbsp;exist&amp;nbsp;because&amp;nbsp;&lt;strong&gt;my&amp;nbsp;intent&amp;nbsp;changes&amp;nbsp;between&amp;nbsp;runs&lt;/strong&gt;.&amp;nbsp;Sometimes&amp;nbsp;I&amp;nbsp;want&amp;nbsp;to&amp;nbsp;scaffold&amp;nbsp;locally&amp;nbsp;and&amp;nbsp;push&amp;nbsp;later.&amp;nbsp;Sometimes&amp;nbsp;the&amp;nbsp;name&amp;nbsp;I&amp;nbsp;picked&amp;nbsp;collides&amp;nbsp;with&amp;nbsp;an&amp;nbsp;existing&amp;nbsp;Render&amp;nbsp;service.&amp;nbsp;A&amp;nbsp;hard&amp;nbsp;confirmation&amp;nbsp;before&amp;nbsp;external&amp;nbsp;state&amp;nbsp;changes&amp;nbsp;is&amp;nbsp;cheap&amp;nbsp;insurance.&lt;/p&gt;




&lt;h2&gt;
  
  
  The&amp;nbsp;scaffold&amp;nbsp;script
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;scaffold.py&lt;/code&gt;&amp;nbsp;is&amp;nbsp;&lt;strong&gt;the&amp;nbsp;least&amp;nbsp;interesting&amp;nbsp;part&lt;/strong&gt;,&amp;nbsp;which&amp;nbsp;is&amp;nbsp;how&amp;nbsp;it&amp;nbsp;should&amp;nbsp;be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;copy_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;src_root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEMPLATE_DIR&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;src_root_p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src_root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;src_root_p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relative_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEMPLATE_DIR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;dst_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;
        &lt;span class="n"&gt;dst_root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fname&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;src_root_p&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;fname&lt;/span&gt;
            &lt;span class="n"&gt;dst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dst_root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;fname&lt;/span&gt;
            &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three&amp;nbsp;placeholders:&amp;nbsp;&lt;code&gt;__NAME__&lt;/code&gt;,&amp;nbsp;&lt;code&gt;__SCHEMA__&lt;/code&gt;,&amp;nbsp;&lt;code&gt;__DESCRIPTION__&lt;/code&gt;.&amp;nbsp;&lt;strong&gt;The&amp;nbsp;schema&amp;nbsp;is&amp;nbsp;the&amp;nbsp;project&amp;nbsp;name&amp;nbsp;with&amp;nbsp;hyphens&amp;nbsp;swapped&amp;nbsp;for&amp;nbsp;underscores&lt;/strong&gt;&amp;nbsp;(SQL&amp;nbsp;identifier&amp;nbsp;rules).&lt;/p&gt;

&lt;p&gt;I&amp;nbsp;don't&amp;nbsp;have&amp;nbsp;a&amp;nbsp;keychain&amp;nbsp;integration.&amp;nbsp;I&amp;nbsp;don't&amp;nbsp;maintain&amp;nbsp;a&amp;nbsp;separate&amp;nbsp;secrets&amp;nbsp;file.&amp;nbsp;&lt;strong&gt;I&amp;nbsp;read&lt;/strong&gt;&amp;nbsp;&lt;code&gt;**DATABASE_URL**&lt;/code&gt;&amp;nbsp;&lt;strong&gt;from&lt;/strong&gt;&amp;nbsp;&lt;code&gt;**~/foundary-tools/drippery/.env.production**&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code&gt;RENDER_API_TOKEN&lt;/code&gt;&amp;nbsp;from&amp;nbsp;&lt;code&gt;~/foundary-tools/framelock/.env.local&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why?&amp;nbsp;Because&amp;nbsp;those&amp;nbsp;projects&amp;nbsp;are&amp;nbsp;already&amp;nbsp;configured.&amp;nbsp;The&amp;nbsp;files&amp;nbsp;exist.&amp;nbsp;Permissions&amp;nbsp;are&amp;nbsp;already&amp;nbsp;set&amp;nbsp;to&amp;nbsp;0600.&amp;nbsp;&lt;strong&gt;My&amp;nbsp;adjacent&amp;nbsp;project&amp;nbsp;is&amp;nbsp;my&amp;nbsp;secret&amp;nbsp;store&amp;nbsp;by&amp;nbsp;construction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;new&amp;nbsp;project's&amp;nbsp;&lt;code&gt;.env.local&lt;/code&gt;&amp;nbsp;gets&amp;nbsp;written&amp;nbsp;with&amp;nbsp;&lt;code&gt;chmod&amp;nbsp;600&lt;/code&gt;&amp;nbsp;and&amp;nbsp;added&amp;nbsp;to&amp;nbsp;a&amp;nbsp;&lt;code&gt;.gitignore&lt;/code&gt;&amp;nbsp;that&amp;nbsp;blocks&amp;nbsp;&lt;code&gt;.env*&lt;/code&gt;.&amp;nbsp;&lt;strong&gt;Normal&amp;nbsp;hygiene.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The&amp;nbsp;Render&amp;nbsp;API&amp;nbsp;call
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Render&amp;nbsp;has&amp;nbsp;a&amp;nbsp;clean&amp;nbsp;v1&amp;nbsp;REST&amp;nbsp;API&lt;/strong&gt;&amp;nbsp;where&amp;nbsp;&lt;code&gt;POST&amp;nbsp;/v1/services&lt;/code&gt;&amp;nbsp;creates&amp;nbsp;a&amp;nbsp;web-service&amp;nbsp;with&amp;nbsp;the&amp;nbsp;config&amp;nbsp;baked&amp;nbsp;in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;create_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web_service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ownerId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;autoDeploy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;branch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;serviceDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;free&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;oregon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;envSpecificDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;buildCommand&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm ci &amp;amp;&amp;amp; npm run build&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;startCommand&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node server.js&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;envVars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database_url&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The&amp;nbsp;owner&amp;nbsp;ID&amp;nbsp;is&amp;nbsp;cached&amp;nbsp;after&amp;nbsp;the&amp;nbsp;first&amp;nbsp;run&lt;/strong&gt;&amp;nbsp;in&amp;nbsp;&lt;code&gt;~/.claude/skills/foundary-new-project/.render-owner-id&lt;/code&gt;,&amp;nbsp;so&amp;nbsp;subsequent&amp;nbsp;scaffolds&amp;nbsp;skip&amp;nbsp;a&amp;nbsp;round-trip.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;whole&amp;nbsp;script&amp;nbsp;is&amp;nbsp;about&amp;nbsp;80&amp;nbsp;lines&amp;nbsp;of&amp;nbsp;&lt;code&gt;urllib.request&lt;/code&gt;&amp;nbsp;—&amp;nbsp;no&amp;nbsp;SDK,&amp;nbsp;no&amp;nbsp;extra&amp;nbsp;dependency.&amp;nbsp;&lt;strong&gt;If&amp;nbsp;the&amp;nbsp;POST&amp;nbsp;returns&amp;nbsp;409&amp;nbsp;or&amp;nbsp;400,&amp;nbsp;Python&amp;nbsp;exits&amp;nbsp;with&amp;nbsp;the&amp;nbsp;error&amp;nbsp;text&lt;/strong&gt;&amp;nbsp;and&amp;nbsp;Claude&amp;nbsp;reads&amp;nbsp;it,&amp;nbsp;tells&amp;nbsp;me,&amp;nbsp;and&amp;nbsp;asks&amp;nbsp;what&amp;nbsp;to&amp;nbsp;do.&lt;/p&gt;

&lt;p&gt;That&amp;nbsp;loop&amp;nbsp;—&amp;nbsp;script&amp;nbsp;fails&amp;nbsp;loud,&amp;nbsp;LLM&amp;nbsp;interprets,&amp;nbsp;human&amp;nbsp;decides&amp;nbsp;—&amp;nbsp;&lt;strong&gt;is&amp;nbsp;why&amp;nbsp;I&amp;nbsp;reach&amp;nbsp;for&amp;nbsp;skills&amp;nbsp;instead&amp;nbsp;of&lt;/strong&gt;&amp;nbsp;&lt;code&gt;**set&amp;nbsp;-e**&lt;/code&gt;&amp;nbsp;&lt;strong&gt;bash&amp;nbsp;scripts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you'd rather get this kind of solo-builder setup broken into a few short, copy-paste steps in your inbox, I turned the essentials into &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Template,&amp;nbsp;not&amp;nbsp;generator
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;&lt;code&gt;template/&lt;/code&gt;&amp;nbsp;directory&amp;nbsp;is&amp;nbsp;a&amp;nbsp;real&amp;nbsp;Next.js&amp;nbsp;skeleton&amp;nbsp;I&amp;nbsp;can&amp;nbsp;open&amp;nbsp;and&amp;nbsp;edit.&amp;nbsp;When&amp;nbsp;the&amp;nbsp;stack&amp;nbsp;evolves&amp;nbsp;—&amp;nbsp;new&amp;nbsp;Next.js&amp;nbsp;version,&amp;nbsp;Tailwind&amp;nbsp;upgrade,&amp;nbsp;a&amp;nbsp;&lt;code&gt;server.js&lt;/code&gt;&amp;nbsp;tweak&amp;nbsp;—&amp;nbsp;&lt;strong&gt;I&amp;nbsp;edit&amp;nbsp;the&amp;nbsp;template&amp;nbsp;files&amp;nbsp;directly&amp;nbsp;and&amp;nbsp;the&amp;nbsp;next&amp;nbsp;scaffold&amp;nbsp;picks&amp;nbsp;up&amp;nbsp;the&amp;nbsp;change&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No&amp;nbsp;code&amp;nbsp;generator&amp;nbsp;to&amp;nbsp;maintain.&amp;nbsp;No&amp;nbsp;AST&amp;nbsp;rewrites.&amp;nbsp;Just&amp;nbsp;files&amp;nbsp;with&amp;nbsp;three&amp;nbsp;placeholders.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;template&amp;nbsp;has&amp;nbsp;15&amp;nbsp;files:&amp;nbsp;&lt;code&gt;app/{layout,page,globals}&lt;/code&gt;,&amp;nbsp;&lt;code&gt;lib/db/{index,schema}&lt;/code&gt;,&amp;nbsp;&lt;code&gt;lib/env.ts&lt;/code&gt;,&amp;nbsp;&lt;code&gt;server.js&lt;/code&gt;,&amp;nbsp;&lt;code&gt;drizzle.config.ts&lt;/code&gt;,&amp;nbsp;&lt;code&gt;next.config.ts&lt;/code&gt;,&amp;nbsp;&lt;code&gt;postcss.config.mjs&lt;/code&gt;,&amp;nbsp;&lt;code&gt;tsconfig.json&lt;/code&gt;,&amp;nbsp;&lt;code&gt;.gitignore&lt;/code&gt;,&amp;nbsp;&lt;code&gt;.env.example&lt;/code&gt;,&amp;nbsp;&lt;code&gt;AGENTS.md&lt;/code&gt;,&amp;nbsp;&lt;code&gt;CLAUDE.md&lt;/code&gt;,&amp;nbsp;&lt;code&gt;README.md&lt;/code&gt;,&amp;nbsp;&lt;code&gt;package.json&lt;/code&gt;.&amp;nbsp;&lt;strong&gt;Every&amp;nbsp;one&amp;nbsp;is&amp;nbsp;either&amp;nbsp;identical&amp;nbsp;across&amp;nbsp;projects&amp;nbsp;or&amp;nbsp;differs&amp;nbsp;only&amp;nbsp;by&amp;nbsp;name/description.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;landing&amp;nbsp;page&amp;nbsp;is&amp;nbsp;deliberately&amp;nbsp;dumb&amp;nbsp;—&amp;nbsp;a&amp;nbsp;hero&amp;nbsp;with&amp;nbsp;the&amp;nbsp;project&amp;nbsp;name&amp;nbsp;and&amp;nbsp;a&amp;nbsp;"Coming&amp;nbsp;soon"&amp;nbsp;line.&amp;nbsp;No&amp;nbsp;DB&amp;nbsp;calls,&amp;nbsp;no&amp;nbsp;auth,&amp;nbsp;nothing&amp;nbsp;that&amp;nbsp;could&amp;nbsp;break&amp;nbsp;the&amp;nbsp;first&amp;nbsp;deploy.&amp;nbsp;&lt;strong&gt;The&amp;nbsp;first&amp;nbsp;deploy's&amp;nbsp;only&amp;nbsp;job&amp;nbsp;is&amp;nbsp;to&amp;nbsp;prove&amp;nbsp;the&amp;nbsp;pipeline&amp;nbsp;works.&lt;/strong&gt;&amp;nbsp;I&amp;nbsp;&lt;a href="https://medium.com/p/db51a8d7cc74" rel="noopener noreferrer"&gt;push&amp;nbsp;every&amp;nbsp;change&amp;nbsp;straight&amp;nbsp;to&amp;nbsp;production&lt;/a&gt;&amp;nbsp;anyway&amp;nbsp;—&amp;nbsp;this&amp;nbsp;just&amp;nbsp;makes&amp;nbsp;sure&amp;nbsp;the&amp;nbsp;wiring&amp;nbsp;is&amp;nbsp;correct&amp;nbsp;before&amp;nbsp;real&amp;nbsp;code&amp;nbsp;lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  90&amp;nbsp;seconds,&amp;nbsp;zero&amp;nbsp;dashboard&amp;nbsp;clicks
&lt;/h2&gt;

&lt;p&gt;From&amp;nbsp;"I&amp;nbsp;want&amp;nbsp;a&amp;nbsp;new&amp;nbsp;project&amp;nbsp;called&amp;nbsp;X"&amp;nbsp;to&amp;nbsp;"a&amp;nbsp;private&amp;nbsp;GitHub&amp;nbsp;repo&amp;nbsp;exists,&amp;nbsp;a&amp;nbsp;free&amp;nbsp;Render&amp;nbsp;service&amp;nbsp;is&amp;nbsp;deploying&amp;nbsp;from&amp;nbsp;main,&amp;nbsp;and&amp;nbsp;&lt;code&gt;npm&amp;nbsp;run&amp;nbsp;dev&lt;/code&gt;&amp;nbsp;works&amp;nbsp;locally"&amp;nbsp;—&amp;nbsp;&lt;strong&gt;about&amp;nbsp;90&amp;nbsp;seconds&amp;nbsp;of&amp;nbsp;wall&amp;nbsp;time&lt;/strong&gt;.&amp;nbsp;Most&amp;nbsp;of&amp;nbsp;that&amp;nbsp;is&amp;nbsp;&lt;code&gt;npm&amp;nbsp;install&lt;/code&gt;&amp;nbsp;and&amp;nbsp;the&amp;nbsp;initial&amp;nbsp;&lt;code&gt;next&amp;nbsp;build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three&amp;nbsp;approvals.&amp;nbsp;Zero&amp;nbsp;clicks&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;dashboard.&amp;nbsp;Zero&amp;nbsp;copy-paste&amp;nbsp;from&amp;nbsp;old&amp;nbsp;projects.&lt;/strong&gt;&amp;nbsp;Zero&amp;nbsp;chance&amp;nbsp;I&amp;nbsp;forgot&amp;nbsp;to&amp;nbsp;rename&amp;nbsp;something&amp;nbsp;in&amp;nbsp;&lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Compared&amp;nbsp;to&amp;nbsp;an&amp;nbsp;hour&amp;nbsp;of&amp;nbsp;manual&amp;nbsp;work&amp;nbsp;where&amp;nbsp;I&amp;nbsp;screwed&amp;nbsp;up&amp;nbsp;half&amp;nbsp;the&amp;nbsp;steps&amp;nbsp;—&amp;nbsp;&lt;strong&gt;worth&amp;nbsp;it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three&amp;nbsp;things&amp;nbsp;worth&amp;nbsp;stealing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Skills&amp;nbsp;beat&amp;nbsp;shell&amp;nbsp;scripts&amp;nbsp;for&amp;nbsp;anything&amp;nbsp;with&amp;nbsp;branching&amp;nbsp;logic.&lt;/strong&gt;&amp;nbsp;A&amp;nbsp;bash&amp;nbsp;script&amp;nbsp;with&amp;nbsp;&lt;code&gt;set&amp;nbsp;-e&lt;/code&gt;&amp;nbsp;exits&amp;nbsp;on&amp;nbsp;any&amp;nbsp;failure.&amp;nbsp;An&amp;nbsp;LLM-driven&amp;nbsp;skill&amp;nbsp;reads&amp;nbsp;the&amp;nbsp;error,&amp;nbsp;decides&amp;nbsp;whether&amp;nbsp;to&amp;nbsp;retry,&amp;nbsp;rephrase,&amp;nbsp;or&amp;nbsp;ask&amp;nbsp;the&amp;nbsp;human.&amp;nbsp;The&amp;nbsp;difference&amp;nbsp;shows&amp;nbsp;up&amp;nbsp;the&amp;nbsp;first&amp;nbsp;time&amp;nbsp;&lt;code&gt;gh&amp;nbsp;auth&amp;nbsp;status&lt;/code&gt;&amp;nbsp;is&amp;nbsp;expired&amp;nbsp;or&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;API&amp;nbsp;rate-limits&amp;nbsp;you&amp;nbsp;—&amp;nbsp;the&amp;nbsp;bash&amp;nbsp;script&amp;nbsp;dies,&amp;nbsp;the&amp;nbsp;skill&amp;nbsp;adapts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approval&amp;nbsp;gates&amp;nbsp;before&amp;nbsp;external&amp;nbsp;state&amp;nbsp;changes.&lt;/strong&gt;&amp;nbsp;Local&amp;nbsp;filesystem&amp;nbsp;mutations&amp;nbsp;and&amp;nbsp;&lt;code&gt;git&amp;nbsp;commit&lt;/code&gt;&amp;nbsp;are&amp;nbsp;cheap&amp;nbsp;to&amp;nbsp;undo.&amp;nbsp;GitHub&amp;nbsp;repo&amp;nbsp;creation,&amp;nbsp;Render&amp;nbsp;API&amp;nbsp;calls,&amp;nbsp;&lt;code&gt;git&amp;nbsp;push&lt;/code&gt;&amp;nbsp;—&amp;nbsp;those&amp;nbsp;leak&amp;nbsp;state&amp;nbsp;outside&amp;nbsp;my&amp;nbsp;machine.&amp;nbsp;A&amp;nbsp;hard&amp;nbsp;&lt;code&gt;[y/N]&lt;/code&gt;&amp;nbsp;confirmation&amp;nbsp;before&amp;nbsp;each&amp;nbsp;one&amp;nbsp;is&amp;nbsp;the&amp;nbsp;right&amp;nbsp;trade-off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read&amp;nbsp;secrets&amp;nbsp;from&amp;nbsp;adjacent&amp;nbsp;projects.&lt;/strong&gt;&amp;nbsp;I&amp;nbsp;was&amp;nbsp;about&amp;nbsp;to&amp;nbsp;overthink&amp;nbsp;secret&amp;nbsp;storage&amp;nbsp;—&amp;nbsp;keychain,&amp;nbsp;1Password&amp;nbsp;CLI,&amp;nbsp;encrypted&amp;nbsp;env&amp;nbsp;file.&amp;nbsp;My&amp;nbsp;sibling&amp;nbsp;projects'&amp;nbsp;&lt;code&gt;.env.local&lt;/code&gt;&amp;nbsp;files&amp;nbsp;are&amp;nbsp;already&amp;nbsp;provisioned&amp;nbsp;and&amp;nbsp;protected.&amp;nbsp;One&amp;nbsp;less&amp;nbsp;system&amp;nbsp;to&amp;nbsp;maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's&amp;nbsp;next
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;skill&amp;nbsp;is&amp;nbsp;globally&amp;nbsp;installed&amp;nbsp;at&amp;nbsp;&lt;code&gt;~/.claude/skills/foundary-new-project/&lt;/code&gt;,&amp;nbsp;so&amp;nbsp;&lt;strong&gt;it&amp;nbsp;triggers&amp;nbsp;in&amp;nbsp;any&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;session&amp;nbsp;regardless&amp;nbsp;of&amp;nbsp;working&amp;nbsp;directory&lt;/strong&gt;.&amp;nbsp;The&amp;nbsp;scripts&amp;nbsp;hard-code&amp;nbsp;paths&amp;nbsp;into&amp;nbsp;&lt;code&gt;~/foundary-tools/&lt;/code&gt;,&amp;nbsp;which&amp;nbsp;keeps&amp;nbsp;the&amp;nbsp;scope&amp;nbsp;tight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next&amp;nbsp;thing&amp;nbsp;I'm&amp;nbsp;automating:&amp;nbsp;the&amp;nbsp;shutdown&amp;nbsp;flow.&lt;/strong&gt;&amp;nbsp;When&amp;nbsp;a&amp;nbsp;project&amp;nbsp;turns&amp;nbsp;out&amp;nbsp;to&amp;nbsp;be&amp;nbsp;a&amp;nbsp;dead&amp;nbsp;end,&amp;nbsp;I&amp;nbsp;want&amp;nbsp;"archive&amp;nbsp;the&amp;nbsp;repo,&amp;nbsp;delete&amp;nbsp;the&amp;nbsp;Render&amp;nbsp;service,&amp;nbsp;drop&amp;nbsp;the&amp;nbsp;pgSchema,&amp;nbsp;move&amp;nbsp;the&amp;nbsp;folder&amp;nbsp;to&amp;nbsp;&lt;code&gt;~/foundary-tools/.graveyard/&lt;/code&gt;"&amp;nbsp;as&amp;nbsp;one&amp;nbsp;command.&amp;nbsp;Same&amp;nbsp;skill&amp;nbsp;pattern,&amp;nbsp;reversed.&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;you&amp;nbsp;run&amp;nbsp;a&amp;nbsp;portfolio&amp;nbsp;of&amp;nbsp;similar&amp;nbsp;side&amp;nbsp;projects&amp;nbsp;as&amp;nbsp;a&amp;nbsp;solo&amp;nbsp;builder,&amp;nbsp;this&amp;nbsp;is&amp;nbsp;the&amp;nbsp;best&amp;nbsp;automation&amp;nbsp;I've&amp;nbsp;set&amp;nbsp;up&amp;nbsp;this&amp;nbsp;year.&amp;nbsp;&lt;strong&gt;The&amp;nbsp;real&amp;nbsp;win&amp;nbsp;is&amp;nbsp;the&amp;nbsp;marginal&amp;nbsp;cost&lt;/strong&gt;:&amp;nbsp;I&amp;nbsp;can&amp;nbsp;spin&amp;nbsp;up&amp;nbsp;a&amp;nbsp;new&amp;nbsp;experiment&amp;nbsp;at&amp;nbsp;9:47&amp;nbsp;PM&amp;nbsp;on&amp;nbsp;a&amp;nbsp;Tuesday&amp;nbsp;and&amp;nbsp;have&amp;nbsp;it&amp;nbsp;deploying&amp;nbsp;by&amp;nbsp;9:49.&lt;/p&gt;




&lt;h2&gt;
  
  
  External&amp;nbsp;Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude&amp;nbsp;Code&amp;nbsp;Skills&lt;/a&gt;&amp;nbsp;—&amp;nbsp;official&amp;nbsp;docs&amp;nbsp;on&amp;nbsp;building&amp;nbsp;and&amp;nbsp;installing&amp;nbsp;skills&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://api-docs.render.com/reference/create-service" rel="noopener noreferrer"&gt;Render&amp;nbsp;API&amp;nbsp;—&amp;nbsp;Create&amp;nbsp;Service&lt;/a&gt;&amp;nbsp;—&amp;nbsp;the&amp;nbsp;POST&amp;nbsp;/v1/services&amp;nbsp;endpoint&amp;nbsp;used&amp;nbsp;here&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://orm.drizzle.team/" rel="noopener noreferrer"&gt;Drizzle&amp;nbsp;ORM&lt;/a&gt;&amp;nbsp;—&amp;nbsp;TypeScript&amp;nbsp;ORM&amp;nbsp;with&amp;nbsp;schema-per-project&amp;nbsp;support&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;&amp;nbsp;—&amp;nbsp;the&amp;nbsp;React&amp;nbsp;framework&amp;nbsp;powering&amp;nbsp;the&amp;nbsp;template&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want more patterns like this landing in your inbox, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; walks you through the setup over a few short emails — free.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I Taught My AI Coding Assistant to Remember — and You Can Too</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:07:06 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-i-taught-my-ai-coding-assistant-to-remember-and-you-can-too-1a21</link>
      <guid>https://dev.to/danielrusnok/how-i-taught-my-ai-coding-assistant-to-remember-and-you-can-too-1a21</guid>
      <description>&lt;p&gt;Every developer who uses AI coding assistants hits the same wall: you explain something once, and next conversation, it's forgotten. You correct a mistake, and three sessions later, the same mistake appears. It's like working with a brilliant colleague who has amnesia.&lt;/p&gt;

&lt;p&gt;Today, I want to share a workflow I've been using with Claude Code that fundamentally changes this dynamic. Instead of repeating myself, I tell Claude to &lt;strong&gt;write down what it learns&lt;/strong&gt; — and it actually sticks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Groundhog Day Development
&lt;/h2&gt;

&lt;p&gt;Here's a real scenario from my codebase. I'm building a team-based access control feature in a .NET + React application. During our first session, Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added comments to every file (I don't want comments)&lt;/li&gt;
&lt;li&gt;Created EF Core migrations (we use raw SQL scripts)&lt;/li&gt;
&lt;li&gt;Added unnecessary &lt;code&gt;using&lt;/code&gt; statements&lt;/li&gt;
&lt;li&gt;Used pricing flags instead of feature flags&lt;/li&gt;
&lt;li&gt;Forgot to add database GRANT permissions for new tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every single one of these mistakes would repeat in the next conversation. I'd have to re-explain the same rules over and over.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Two Persistence Mechanisms
&lt;/h2&gt;

&lt;p&gt;Claude Code has two built-in mechanisms for persistent context that survive across conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. CLAUDE.md — Project Rules
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; sits in your project root and acts as a set of instructions Claude reads at the start of every conversation. Think of it as a &lt;code&gt;.editorconfig&lt;/code&gt; for AI behavior.&lt;/p&gt;

&lt;p&gt;Here's what mine looks like after a day of working together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Code Style Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; No comments in code. Code should be self-explanatory.
&lt;span class="p"&gt;-&lt;/span&gt; No unnecessary usings. Every using must be actually needed.

&lt;span class="gu"&gt;## Database Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Never create EF Core migrations. Always deliver raw PostgreSQL scripts.
&lt;span class="p"&gt;-&lt;/span&gt; Always add GRANT SELECT, INSERT, UPDATE, DELETE for application-dev user.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: &lt;strong&gt;I didn't write these rules upfront.&lt;/strong&gt; They emerged organically from corrections during our work session. When I said "stop adding comments," I followed up with "write that down so you remember next time." Claude added the rule to CLAUDE.md, and the behavior stopped — permanently.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Memory Files — Contextual Knowledge
&lt;/h3&gt;

&lt;p&gt;The second mechanism is Claude's memory system — markdown files stored in &lt;code&gt;.claude/projects/.../memory/&lt;/code&gt;. Unlike CLAUDE.md (which holds rules), memory files store &lt;strong&gt;contextual knowledge&lt;/strong&gt; that helps Claude make better decisions.&lt;/p&gt;

&lt;p&gt;For example, after I explained how feature flags work in our codebase (frontend hooks, backend services, sysadmin razor pages), I told Claude to save that knowledge. It created a reference file covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which hook to use for feature flags vs pricing flags&lt;/li&gt;
&lt;li&gt;Where the sysadmin flag editor lives&lt;/li&gt;
&lt;li&gt;The naming convention for flags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next time Claude needs to add a feature flag, it won't use a pricing flag by mistake. It won't forget to add the checkbox in the sysadmin razor page. The knowledge is there, indexed and searchable.&lt;/p&gt;

&lt;p&gt;If you'd rather have this whole setup broken into a few short, copy-paste steps in your inbox, I turned it into &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a free email series.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Workflow: Correct Once, Remember Forever
&lt;/h2&gt;

&lt;p&gt;The pattern is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Claude makes a mistake&lt;/strong&gt; (or you notice a pattern worth preserving)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You correct it&lt;/strong&gt; — "don't do X" or "always do Y"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You tell Claude to save it&lt;/strong&gt; — "write that down" or "remember this for next time"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude persists it&lt;/strong&gt; — either as a CLAUDE.md rule or a memory file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future conversations benefit&lt;/strong&gt; — the rule or context is loaded automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This turns every correction into a permanent improvement. Your AI assistant gets smarter with every session — not through model updates, but through accumulated project-specific knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goes Where?
&lt;/h2&gt;

&lt;p&gt;Not everything belongs in the same place:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLAUDE.md&lt;/strong&gt; is for actionable rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code style preferences&lt;/li&gt;
&lt;li&gt;Workflow constraints (no migrations, always run tests)&lt;/li&gt;
&lt;li&gt;Project-specific patterns to follow or avoid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Memory files&lt;/strong&gt; are for contextual knowledge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How systems work (feature flags, auth, deployment)&lt;/li&gt;
&lt;li&gt;Project goals and motivations&lt;/li&gt;
&lt;li&gt;References to external resources&lt;/li&gt;
&lt;li&gt;Team member roles and responsibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Neither&lt;/strong&gt; should contain things derivable from code (architecture, file paths) or git history (recent changes, who did what).&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Impact
&lt;/h2&gt;

&lt;p&gt;After one working session with this approach, my Claude Code setup knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Never add comments to code&lt;/li&gt;
&lt;li&gt;Always provide raw SQL with GRANT statements for new database objects&lt;/li&gt;
&lt;li&gt;How feature flags work across three layers (frontend, backend, sysadmin)&lt;/li&gt;
&lt;li&gt;The full requirements spec for the feature we're building&lt;/li&gt;
&lt;li&gt;That &lt;code&gt;tms_accs&lt;/code&gt; is a feature flag, not a pricing flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tomorrow, when I start a new conversation to continue this feature, none of this context will be lost. I won't waste the first 10 minutes re-explaining constraints. Claude will just... know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;If you're using Claude Code, you can start right now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;CLAUDE.md&lt;/code&gt; in your project root&lt;/li&gt;
&lt;li&gt;Next time you correct Claude, add: "and write that down so you remember"&lt;/li&gt;
&lt;li&gt;Watch as your AI assistant accumulates project knowledge over time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best part? These files are just markdown. You can review them, edit them, commit them to your repo (CLAUDE.md), or keep them local (memory files). Your team members can benefit from the same rules, or each developer can have their own memory layer.&lt;/p&gt;

&lt;p&gt;It's not about having a smarter model. It's about building a smarter &lt;strong&gt;working relationship&lt;/strong&gt; — one correction at a time.&lt;/p&gt;

&lt;p&gt;If you want the starter version of this to land in your inbox, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; walks you through it over a few short emails — free.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>From .NET Architect to Frontend Developer — What Surprised Me, What I Miss, and What I Had to…</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Fri, 10 Jul 2026 15:03:05 +0000</pubDate>
      <link>https://dev.to/danielrusnok/from-net-architect-to-frontend-developer-what-surprised-me-what-i-miss-and-what-i-had-to-337</link>
      <guid>https://dev.to/danielrusnok/from-net-architect-to-frontend-developer-what-surprised-me-what-i-miss-and-what-i-had-to-337</guid>
      <description>&lt;h3&gt;
  
  
  From&amp;nbsp;.NET&amp;nbsp;Architect&amp;nbsp;to&amp;nbsp;Frontend&amp;nbsp;Developer&amp;nbsp;—&amp;nbsp;What&amp;nbsp;Surprised&amp;nbsp;Me,&amp;nbsp;What&amp;nbsp;I&amp;nbsp;Miss,&amp;nbsp;and&amp;nbsp;What&amp;nbsp;I&amp;nbsp;Had&amp;nbsp;to&amp;nbsp;Unlearn
&lt;/h3&gt;

&lt;h4&gt;
  
  
  You&amp;nbsp;may&amp;nbsp;remember&amp;nbsp;me&amp;nbsp;from&amp;nbsp;the&amp;nbsp;days&amp;nbsp;when&amp;nbsp;I&amp;nbsp;wrote&amp;nbsp;about&amp;nbsp;CQRS,&amp;nbsp;DDD,&amp;nbsp;and&amp;nbsp;.NET.&amp;nbsp;It’s&amp;nbsp;been&amp;nbsp;three&amp;nbsp;years&amp;nbsp;—&amp;nbsp;I’ve&amp;nbsp;crossed&amp;nbsp;the&amp;nbsp;bridge&amp;nbsp;to&amp;nbsp;the&amp;nbsp;other&amp;nbsp;side.
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2znbksd8jk517e2fcr27.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2znbksd8jk517e2fcr27.png" alt="From&amp;nbsp;.NET Architect to Frontend Developer — What Surprised Me, What I Miss, and What I Had to… cover image" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;
Bridge&amp;nbsp;between&amp;nbsp;backend&amp;nbsp;and&amp;nbsp;frontend&amp;nbsp;(chatGPT&amp;nbsp;generated)



&lt;p&gt;I&amp;nbsp;burned&amp;nbsp;out&amp;nbsp;at&amp;nbsp;my&amp;nbsp;previous&amp;nbsp;job&amp;nbsp;three&amp;nbsp;years&amp;nbsp;ago&amp;nbsp;and&amp;nbsp;started&amp;nbsp;looking&amp;nbsp;for&amp;nbsp;new&amp;nbsp;opportunities.&amp;nbsp;Along&amp;nbsp;with&amp;nbsp;a&amp;nbsp;new&amp;nbsp;company&amp;nbsp;came&amp;nbsp;the&amp;nbsp;chance&amp;nbsp;to&amp;nbsp;fill&amp;nbsp;a&amp;nbsp;missing&amp;nbsp;role&amp;nbsp;on&amp;nbsp;the&amp;nbsp;front-end&amp;nbsp;team.&amp;nbsp;I&amp;nbsp;took&amp;nbsp;the&amp;nbsp;opportunity&amp;nbsp;and&amp;nbsp;gradually&amp;nbsp;transitioned&amp;nbsp;from&amp;nbsp;full-stack&amp;nbsp;to&amp;nbsp;fully&amp;nbsp;front-end&amp;nbsp;focused.&amp;nbsp;And&amp;nbsp;just&amp;nbsp;like&amp;nbsp;that,&amp;nbsp;my&amp;nbsp;entire&amp;nbsp;scope&amp;nbsp;changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why&amp;nbsp;the&amp;nbsp;sudden&amp;nbsp;shift?
&lt;/h3&gt;

&lt;p&gt;I’ve&amp;nbsp;always&amp;nbsp;wanted&amp;nbsp;to&amp;nbsp;work&amp;nbsp;on&amp;nbsp;something&amp;nbsp;more&amp;nbsp;visible.&amp;nbsp;My&amp;nbsp;creativity&amp;nbsp;was&amp;nbsp;getting&amp;nbsp;thirstier&amp;nbsp;by&amp;nbsp;the&amp;nbsp;day,&amp;nbsp;and&amp;nbsp;the&amp;nbsp;backend&amp;nbsp;started&amp;nbsp;to&amp;nbsp;feel&amp;nbsp;dull.&lt;/p&gt;

&lt;p&gt;In&amp;nbsp;the&amp;nbsp;backend&amp;nbsp;world,&amp;nbsp;I&amp;nbsp;satisfied&amp;nbsp;my&amp;nbsp;creative&amp;nbsp;itch&amp;nbsp;through&amp;nbsp;architecture&amp;nbsp;—&amp;nbsp;from&amp;nbsp;individual&amp;nbsp;projects&amp;nbsp;and&amp;nbsp;services&amp;nbsp;to&amp;nbsp;entire&amp;nbsp;application&amp;nbsp;structures.&amp;nbsp;Now,&amp;nbsp;I&amp;nbsp;express&amp;nbsp;that&amp;nbsp;creativity&amp;nbsp;through&amp;nbsp;layout&amp;nbsp;design,&amp;nbsp;animation&amp;nbsp;choices,&amp;nbsp;and&amp;nbsp;collaboration&amp;nbsp;with&amp;nbsp;UX&amp;nbsp;designers.&lt;/p&gt;

&lt;h3&gt;
  
  
  How&amp;nbsp;do&amp;nbsp;I&amp;nbsp;feel&amp;nbsp;about&amp;nbsp;React?
&lt;/h3&gt;

&lt;p&gt;React&amp;nbsp;clicked&amp;nbsp;with&amp;nbsp;me&amp;nbsp;right&amp;nbsp;away.&amp;nbsp;Its&amp;nbsp;component-based&amp;nbsp;structure&amp;nbsp;is&amp;nbsp;exactly&amp;nbsp;my&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;fun.&amp;nbsp;Finding&amp;nbsp;the&amp;nbsp;sweet&amp;nbsp;spot&amp;nbsp;between&amp;nbsp;generic&amp;nbsp;reusability&amp;nbsp;and&amp;nbsp;the&amp;nbsp;Single&amp;nbsp;Responsibility&amp;nbsp;Principle&amp;nbsp;is&amp;nbsp;what&amp;nbsp;drives&amp;nbsp;me&amp;nbsp;most.&lt;/p&gt;

&lt;h3&gt;
  
  
  What&amp;nbsp;surprised&amp;nbsp;me&amp;nbsp;about&amp;nbsp;front&amp;nbsp;end?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  📈&amp;nbsp;The&amp;nbsp;Progress
&lt;/h4&gt;

&lt;p&gt;Before&amp;nbsp;React,&amp;nbsp;my&amp;nbsp;last&amp;nbsp;encounter&amp;nbsp;with&amp;nbsp;HTML,&amp;nbsp;CSS,&amp;nbsp;and&amp;nbsp;JavaScript&amp;nbsp;(mainly&amp;nbsp;jQuery)&amp;nbsp;was&amp;nbsp;about&amp;nbsp;ten&amp;nbsp;years&amp;nbsp;ago&amp;nbsp;—&amp;nbsp;and&amp;nbsp;mostly&amp;nbsp;just&amp;nbsp;minor&amp;nbsp;tweaks.&amp;nbsp;Today,&amp;nbsp;I&amp;nbsp;work&amp;nbsp;on&amp;nbsp;entire&amp;nbsp;websites&amp;nbsp;and&amp;nbsp;complex&amp;nbsp;features.&amp;nbsp;The&amp;nbsp;front&amp;nbsp;end&amp;nbsp;has&amp;nbsp;come&amp;nbsp;a&amp;nbsp;long&amp;nbsp;way.&amp;nbsp;With&amp;nbsp;React,&amp;nbsp;TypeScript,&amp;nbsp;Node.js,&amp;nbsp;and&amp;nbsp;Styled&amp;nbsp;Components,&amp;nbsp;it&amp;nbsp;feels&amp;nbsp;like&amp;nbsp;an&amp;nbsp;entirely&amp;nbsp;different&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;programming.&lt;/p&gt;

&lt;h4&gt;
  
  
  🛠&amp;nbsp;Tooling
&lt;/h4&gt;

&lt;p&gt;I&amp;nbsp;expected&amp;nbsp;chaos&amp;nbsp;but&amp;nbsp;got&amp;nbsp;a&amp;nbsp;surprisingly&amp;nbsp;mature&amp;nbsp;ecosystem.&amp;nbsp;Prettier&amp;nbsp;and&amp;nbsp;ESLint&amp;nbsp;help&amp;nbsp;keep&amp;nbsp;the&amp;nbsp;codebase&amp;nbsp;nice&amp;nbsp;and&amp;nbsp;tidy.&amp;nbsp;Visual&amp;nbsp;Studio&amp;nbsp;Code&amp;nbsp;is&amp;nbsp;a&amp;nbsp;pleasant,&amp;nbsp;lightweight&amp;nbsp;environment,&amp;nbsp;and&amp;nbsp;although&amp;nbsp;Microsoft&amp;nbsp;has&amp;nbsp;made&amp;nbsp;good&amp;nbsp;progress&amp;nbsp;with&amp;nbsp;the&amp;nbsp;performance&amp;nbsp;of&amp;nbsp;Visual&amp;nbsp;Studio,&amp;nbsp;it&amp;nbsp;still&amp;nbsp;feels&amp;nbsp;bulky&amp;nbsp;to&amp;nbsp;me.&lt;/p&gt;

&lt;h4&gt;
  
  
  📦&amp;nbsp;Bundle&amp;nbsp;size&amp;nbsp;matters
&lt;/h4&gt;

&lt;p&gt;In&amp;nbsp;the&amp;nbsp;backend,&amp;nbsp;I’d&amp;nbsp;happily&amp;nbsp;install&amp;nbsp;any&amp;nbsp;NuGet&amp;nbsp;package&amp;nbsp;—&amp;nbsp;service&amp;nbsp;size&amp;nbsp;wasn’t&amp;nbsp;usually&amp;nbsp;an&amp;nbsp;issue&amp;nbsp;(unless&amp;nbsp;you&amp;nbsp;were&amp;nbsp;deploying&amp;nbsp;in&amp;nbsp;some&amp;nbsp;expensive&amp;nbsp;cloud).&amp;nbsp;In&amp;nbsp;front&amp;nbsp;end,&amp;nbsp;bundle&amp;nbsp;size&amp;nbsp;affects&amp;nbsp;load&amp;nbsp;speed,&amp;nbsp;so&amp;nbsp;you&amp;nbsp;tend&amp;nbsp;to&amp;nbsp;write&amp;nbsp;utilities&amp;nbsp;yourself&amp;nbsp;rather&amp;nbsp;than&amp;nbsp;pulling&amp;nbsp;in&amp;nbsp;a&amp;nbsp;bloated&amp;nbsp;library&amp;nbsp;just&amp;nbsp;for&amp;nbsp;two&amp;nbsp;functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What&amp;nbsp;do&amp;nbsp;I&amp;nbsp;miss&amp;nbsp;from&amp;nbsp;the&amp;nbsp;backend?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ❌&amp;nbsp;Clean&amp;nbsp;compiler&amp;nbsp;errors
&lt;/h4&gt;

&lt;p&gt;Maybe&amp;nbsp;it’s&amp;nbsp;just&amp;nbsp;our&amp;nbsp;internal&amp;nbsp;tooling,&amp;nbsp;but&amp;nbsp;deciphering&amp;nbsp;cryptic&amp;nbsp;error&amp;nbsp;messages&amp;nbsp;and&amp;nbsp;not&amp;nbsp;being&amp;nbsp;able&amp;nbsp;to&amp;nbsp;click&amp;nbsp;straight&amp;nbsp;to&amp;nbsp;the&amp;nbsp;offending&amp;nbsp;file&amp;nbsp;still&amp;nbsp;feels&amp;nbsp;frustrating.&amp;nbsp;Visual&amp;nbsp;Studio&amp;nbsp;spoiled&amp;nbsp;me.&lt;/p&gt;

&lt;h4&gt;
  
  
  🧪&amp;nbsp;Unit&amp;nbsp;testing
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Side note: if you like reading about the craft of crossing between backend and frontend, I share short, free lessons like that in &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt;, a tiny email series you can join in one click.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sure,&amp;nbsp;there’s&amp;nbsp;Jest,&amp;nbsp;but&amp;nbsp;unit-testing&amp;nbsp;React&amp;nbsp;components&amp;nbsp;doesn’t&amp;nbsp;spark&amp;nbsp;joy&amp;nbsp;for&amp;nbsp;me.&amp;nbsp;It&amp;nbsp;makes&amp;nbsp;sense&amp;nbsp;in&amp;nbsp;design&amp;nbsp;systems&amp;nbsp;and&amp;nbsp;shared&amp;nbsp;libraries.&amp;nbsp;But&amp;nbsp;if&amp;nbsp;you’ve&amp;nbsp;got&amp;nbsp;a&amp;nbsp;QA&amp;nbsp;engineer&amp;nbsp;automating&amp;nbsp;tests&amp;nbsp;via&amp;nbsp;Playwright,&amp;nbsp;I&amp;nbsp;honestly&amp;nbsp;don’t&amp;nbsp;see&amp;nbsp;much&amp;nbsp;benefit.&amp;nbsp;On&amp;nbsp;the&amp;nbsp;backend,&amp;nbsp;I&amp;nbsp;often&amp;nbsp;used&amp;nbsp;TDD.&amp;nbsp;On&amp;nbsp;the&amp;nbsp;front&amp;nbsp;end,&amp;nbsp;I&amp;nbsp;haven’t&amp;nbsp;even&amp;nbsp;thought&amp;nbsp;of&amp;nbsp;it.&lt;/p&gt;

&lt;h4&gt;
  
  
  📚&amp;nbsp;Third-party&amp;nbsp;libraries
&lt;/h4&gt;

&lt;p&gt;Every&amp;nbsp;dependency&amp;nbsp;needs&amp;nbsp;to&amp;nbsp;have&amp;nbsp;a&amp;nbsp;healthy&amp;nbsp;community&amp;nbsp;and&amp;nbsp;a&amp;nbsp;small&amp;nbsp;footprint.&amp;nbsp;You&amp;nbsp;can’t&amp;nbsp;just&amp;nbsp;grab&amp;nbsp;the&amp;nbsp;first&amp;nbsp;thing&amp;nbsp;that&amp;nbsp;pops&amp;nbsp;up&amp;nbsp;in&amp;nbsp;a&amp;nbsp;search&amp;nbsp;—&amp;nbsp;you&amp;nbsp;need&amp;nbsp;to&amp;nbsp;do&amp;nbsp;at&amp;nbsp;least&amp;nbsp;some&amp;nbsp;due&amp;nbsp;diligence.&lt;/p&gt;

&lt;h3&gt;
  
  
  What&amp;nbsp;I&amp;nbsp;Had&amp;nbsp;to&amp;nbsp;Unlearn
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🧠&amp;nbsp;OOP&amp;nbsp;Principles&amp;nbsp;—&amp;nbsp;used&amp;nbsp;rarely
&lt;/h4&gt;

&lt;p&gt;I&amp;nbsp;barely&amp;nbsp;use&amp;nbsp;object-oriented&amp;nbsp;principles&amp;nbsp;these&amp;nbsp;days.&amp;nbsp;Inheritance&amp;nbsp;appears&amp;nbsp;only&amp;nbsp;thanks&amp;nbsp;to&amp;nbsp;TypeScript,&amp;nbsp;mainly&amp;nbsp;for&amp;nbsp;models&amp;nbsp;and&amp;nbsp;component&amp;nbsp;interfaces.&amp;nbsp;Encapsulation?&amp;nbsp;Only&amp;nbsp;when&amp;nbsp;a&amp;nbsp;component&amp;nbsp;is&amp;nbsp;used&amp;nbsp;exclusively&amp;nbsp;in&amp;nbsp;one&amp;nbsp;file.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;And&amp;nbsp;the&amp;nbsp;only&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;polymorphism&amp;nbsp;I&amp;nbsp;can&amp;nbsp;think&amp;nbsp;of&amp;nbsp;is&amp;nbsp;when&amp;nbsp;&lt;code&gt;children&lt;/code&gt;&amp;nbsp;are&amp;nbsp;passed&amp;nbsp;into&amp;nbsp;a&amp;nbsp;React&amp;nbsp;component&amp;nbsp;—&amp;nbsp;allowing&amp;nbsp;it&amp;nbsp;to&amp;nbsp;take&amp;nbsp;on&amp;nbsp;different&amp;nbsp;shapes&amp;nbsp;or&amp;nbsp;content.&lt;/p&gt;

&lt;h4&gt;
  
  
  🧱&amp;nbsp;Monolithic&amp;nbsp;thinking
&lt;/h4&gt;

&lt;p&gt;I&amp;nbsp;no&amp;nbsp;longer&amp;nbsp;need&amp;nbsp;to&amp;nbsp;think&amp;nbsp;in&amp;nbsp;terms&amp;nbsp;of&amp;nbsp;big&amp;nbsp;code&amp;nbsp;blocks&amp;nbsp;—&amp;nbsp;modules,&amp;nbsp;domains,&amp;nbsp;layers,&amp;nbsp;orchestration.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;Frontend&amp;nbsp;forced&amp;nbsp;me&amp;nbsp;to&amp;nbsp;think&amp;nbsp;in&amp;nbsp;much&amp;nbsp;finer&amp;nbsp;granularity&amp;nbsp;—&amp;nbsp;small&amp;nbsp;components&amp;nbsp;that&amp;nbsp;snap&amp;nbsp;together&amp;nbsp;like&amp;nbsp;Lego&amp;nbsp;bricks.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚙️&amp;nbsp;Abstraction
&lt;/h4&gt;

&lt;p&gt;On&amp;nbsp;the&amp;nbsp;backend,&amp;nbsp;I&amp;nbsp;used&amp;nbsp;to&amp;nbsp;spend&amp;nbsp;hours&amp;nbsp;building&amp;nbsp;the&amp;nbsp;perfect&amp;nbsp;abstraction.&amp;nbsp;On&amp;nbsp;the&amp;nbsp;front&amp;nbsp;end,&amp;nbsp;I&amp;nbsp;rarely&amp;nbsp;feel&amp;nbsp;the&amp;nbsp;need&amp;nbsp;—&amp;nbsp;and&amp;nbsp;often&amp;nbsp;don’t&amp;nbsp;even&amp;nbsp;see&amp;nbsp;the&amp;nbsp;room&amp;nbsp;for&amp;nbsp;it.&lt;/p&gt;

&lt;h3&gt;
  
  
  In&amp;nbsp;closing
&lt;/h3&gt;

&lt;p&gt;I’ve&amp;nbsp;missed&amp;nbsp;writing,&amp;nbsp;and&amp;nbsp;this&amp;nbsp;post&amp;nbsp;is&amp;nbsp;my&amp;nbsp;attempt&amp;nbsp;to&amp;nbsp;start&amp;nbsp;something&amp;nbsp;new.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;I’d&amp;nbsp;love&amp;nbsp;to&amp;nbsp;write&amp;nbsp;blog&amp;nbsp;posts&amp;nbsp;from&amp;nbsp;the&amp;nbsp;perspective&amp;nbsp;of&amp;nbsp;someone&amp;nbsp;standing&amp;nbsp;between&amp;nbsp;the&amp;nbsp;backend&amp;nbsp;and&amp;nbsp;front&amp;nbsp;end&amp;nbsp;worlds&amp;nbsp;—&amp;nbsp;or&amp;nbsp;from&amp;nbsp;a&amp;nbsp;backend&amp;nbsp;developer&amp;nbsp;trying&amp;nbsp;to&amp;nbsp;build&amp;nbsp;good&amp;nbsp;frontend&amp;nbsp;code.&lt;/p&gt;

&lt;p&gt;Thanks&amp;nbsp;for&amp;nbsp;reading.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;Have&amp;nbsp;any&amp;nbsp;of&amp;nbsp;you&amp;nbsp;made&amp;nbsp;a&amp;nbsp;similar&amp;nbsp;transition?&amp;nbsp;What&amp;nbsp;surprised&amp;nbsp;you&amp;nbsp;the&amp;nbsp;most?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this resonated, you might also enjoy &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a short free email series, one bite-sized lesson at a time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;nbsp;Related&amp;nbsp;Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/linq-vs-typescript-method-equivalents-at-a-glance-8be1bdcc279d%5D%C2%A0%E2%80%94%C2%A0_LINQ%C2%A0vs%C2%A0TypeScript:%C2%A0Method%C2%A0Equivalents%C2%A0at%C2%A0a%C2%A0Glance_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/linq-vs-typescript-method-equivalents-at-a-glance-8be1bdcc279d]&amp;nbsp;—&amp;nbsp;_LINQ&amp;nbsp;vs&amp;nbsp;TypeScript:&amp;nbsp;Method&amp;nbsp;Equivalents&amp;nbsp;at&amp;nbsp;a&amp;nbsp;Glance_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/3-typescript-features-that-make-c-developers-jealous-ab6e416cf368%5D%C2%A0%E2%80%94%C2%A0_3%C2%A0TypeScript%C2%A0Features%C2%A0That%C2%A0Make%C2%A0C#%C2%A0Developers%C2%A0Jealous_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/3-typescript-features-that-make-c-developers-jealous-ab6e416cf368]&amp;nbsp;—&amp;nbsp;_3&amp;nbsp;TypeScript&amp;nbsp;Features&amp;nbsp;That&amp;nbsp;Make&amp;nbsp;C#&amp;nbsp;Developers&amp;nbsp;Jealous_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://levelup.gitconnected.com/5-c-patterns-that-every-typescript-developer-should-steal-c8156c32bc4c%5D%C2%A0%E2%80%94%C2%A0_5%C2%A0C#%C2%A0Patterns%C2%A0That%C2%A0Every%C2%A0TypeScript%C2%A0Developer%C2%A0Should%C2%A0Steal_" rel="noopener noreferrer"&gt;https://levelup.gitconnected.com/5-c-patterns-that-every-typescript-developer-should-steal-c8156c32bc4c]&amp;nbsp;—&amp;nbsp;_5&amp;nbsp;C#&amp;nbsp;Patterns&amp;nbsp;That&amp;nbsp;Every&amp;nbsp;TypeScript&amp;nbsp;Developer&amp;nbsp;Should&amp;nbsp;Steal_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/ai-is-quietly-erasing-the-line-between-frontend-and-backend-developers-2fe70a9da546%5D%C2%A0%E2%80%94%C2%A0_AI%C2%A0Is%C2%A0Quietly%C2%A0Erasing%C2%A0the%C2%A0Line%C2%A0Between%C2%A0Frontend%C2%A0and%C2%A0Backend%C2%A0Developers_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/ai-is-quietly-erasing-the-line-between-frontend-and-backend-developers-2fe70a9da546]&amp;nbsp;—&amp;nbsp;_AI&amp;nbsp;Is&amp;nbsp;Quietly&amp;nbsp;Erasing&amp;nbsp;the&amp;nbsp;Line&amp;nbsp;Between&amp;nbsp;Frontend&amp;nbsp;and&amp;nbsp;Backend&amp;nbsp;Developers_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://ai.plainenglish.io/domain-driven-design-is-the-architecture-ai-agents-were-waiting-for-4742509a44db%5D%C2%A0%E2%80%94%C2%A0_Domain-Driven%C2%A0Design%C2%A0Is%C2%A0the%C2%A0Architecture%C2%A0AI%C2%A0Agents%C2%A0Were%C2%A0Waiting%C2%A0For_" rel="noopener noreferrer"&gt;https://ai.plainenglish.io/domain-driven-design-is-the-architecture-ai-agents-were-waiting-for-4742509a44db]&amp;nbsp;—&amp;nbsp;_Domain-Driven&amp;nbsp;Design&amp;nbsp;Is&amp;nbsp;the&amp;nbsp;Architecture&amp;nbsp;AI&amp;nbsp;Agents&amp;nbsp;Were&amp;nbsp;Waiting&amp;nbsp;For_&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>career</category>
      <category>frontend</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Upgrade my Code-Style of MediatR Pipeline using .NET 6</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Wed, 08 Jul 2026 15:06:44 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-i-upgrade-my-code-style-of-mediatr-pipeline-using-net-6-271f</link>
      <guid>https://dev.to/danielrusnok/how-i-upgrade-my-code-style-of-mediatr-pipeline-using-net-6-271f</guid>
      <description>&lt;h4&gt;
  
  
  SOFTWARE ARCHITECTURE &amp;amp; REFACTORING
&lt;/h4&gt;

&lt;h3&gt;
  
  
  How I Upgrade my Code-Style of MediatR Pipeline using&amp;nbsp;.NET&amp;nbsp;6
&lt;/h3&gt;

&lt;h4&gt;
  
  
  I want to share with you how&amp;nbsp;.NET 6 features with the new &lt;a href="https://github.com/ITIXO/MediatR.Extensions.AttributedBehaviors" rel="noopener noreferrer"&gt;MediatR.Extensions.AttributedBehaviors&lt;/a&gt; NuGet package helped me polish my MediatR pipelines.
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyzk0gpu99mjyep6uij0z.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyzk0gpu99mjyep6uij0z.jpeg" alt="How I Upgrade my Code-Style of MediatR Pipeline using&amp;nbsp;.NET 6 cover image" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is&amp;nbsp;MediatR
&lt;/h3&gt;

&lt;p&gt;It is a popular &lt;a href="https://github.com/jbogard/MediatR" rel="noopener noreferrer"&gt;library&lt;/a&gt; for C# created by &lt;a href="https://jimmybogard.com/" rel="noopener noreferrer"&gt;Jimmy Boggard&lt;/a&gt;, which can be described as a simple &lt;a href="https://levelup.gitconnected.com/ugly-dependency-graph-the-mediator-design-pattern-is-the-solution-for-you-8b35df60558b" rel="noopener noreferrer"&gt;Mediator Pattern&lt;/a&gt; implementation in&amp;nbsp;.NET. MediatR &lt;a href="https://www.nuget.org/packages/MediatR/" rel="noopener noreferrer"&gt;NuGet package&lt;/a&gt; currently has almost &lt;strong&gt;50 million downloads&lt;/strong&gt; and still rising.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jbogard/MediatR/wiki" rel="noopener noreferrer"&gt;Wiki page&lt;/a&gt; on its GitHub says:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MediatR is a low-ambition library trying to solve a simple problem — decoupling the in-process sending of messages from handling messages.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The word &lt;strong&gt;in-process&lt;/strong&gt; is essential. This is not a Message Broker as Kinesis or RabbitMQ. This is about sending the message from one place and handling such message in a different place, but still in one process.&lt;/p&gt;

&lt;p&gt;I use MediatR for decoupling Command and Query Requests. So In my case, the MediatR message is Query or Command, depending on the direction of data flow. This architectural design is called &lt;strong&gt;Command-Query Separation&lt;/strong&gt;, and I am explaining it in the first paragraph of blog-post &lt;a href="https://levelup.gitconnected.com/3-cqrs-architectures-that-every-software-architect-should-know-a7f69aae8b6c?source=friends_link&amp;amp;sk=b6dea517e74c8804f718418c834daa80" rel="noopener noreferrer"&gt;3 CQRS Architectures that Every Software Architect Should Know&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can see how I can handle HTTP GET by defining a &lt;code&gt;GetWarehousesQuery&lt;/code&gt; as a MediatR request (message), and &lt;code&gt;GetWarehousesQueryHandler&lt;/code&gt; as its Handler in the code sample below.&lt;/p&gt;

&lt;p&gt;Warehouses Query Handling&lt;/p&gt;




&lt;h3&gt;
  
  
  Upgrade Code with&amp;nbsp;.NET 6&amp;nbsp;Features
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Records
&lt;/h4&gt;

&lt;p&gt;Actually records are with us since&amp;nbsp;.NET 5 and C# 9, but it is related to the topic of a blog post so that I will introduce them to you too. The feature called &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record" rel="noopener noreferrer"&gt;Records&lt;/a&gt;. Records introduced a shorter syntax for defining an &lt;strong&gt;immutable class&lt;/strong&gt;. I find helpful when I am declaring Command or Query class.&lt;/p&gt;

&lt;p&gt;Look at line 8. The definition of &lt;code&gt;GetWarehousesQuery&lt;/code&gt; is now &lt;strong&gt;one-line code&lt;/strong&gt;. I like to have Query and Command classes with theirs Handler classes in one place, which makes my code cleaner.&lt;/p&gt;

&lt;p&gt;There is a &lt;strong&gt;drawback&lt;/strong&gt;. You will not be able to change the value of any property after Record initialization. It is an immutable object, and the setter of every property is defined with the &lt;code&gt;init&lt;/code&gt; keyword.&lt;/p&gt;

&lt;h4&gt;
  
  
  Global Usings
&lt;/h4&gt;

&lt;p&gt;Another sugar feature of&amp;nbsp;.NET 6 is &lt;a href="https://blog.jetbrains.com/dotnet/2021/11/18/global-usings-in-csharp-10/" rel="noopener noreferrer"&gt;Global Usings&lt;/a&gt;. The new keyword &lt;code&gt;global&lt;/code&gt; before Using directive is making it possible not to include &lt;code&gt;using MediatR&lt;/code&gt; in every file where we are implementing interfaces from the MediatR library.&lt;/p&gt;

&lt;p&gt;Global Usings are project-scoped, so I recommend you to &lt;strong&gt;create just one dedicated file for them&lt;/strong&gt; in the root of the project folder. Define your Global Usings only there. It can be a mess once you start to write &lt;code&gt;global using&lt;/code&gt; in a random file.&lt;/p&gt;

&lt;p&gt;Let’s create a &lt;code&gt;GlobalUsings.cs&lt;/code&gt; file with this line of code:&lt;/p&gt;

&lt;p&gt;global using MediatR;&lt;/p&gt;

&lt;p&gt;Now, we can remove &lt;code&gt;using MediatR;&lt;/code&gt; from the code sample.&lt;/p&gt;

&lt;h4&gt;
  
  
  File Scoped Namespaces
&lt;/h4&gt;

&lt;p&gt;File Scoped Namespace means defining &lt;strong&gt;one namespace per file&lt;/strong&gt; without curly brackets. So our code sample can be even cleaner. Take a look below.&lt;/p&gt;

&lt;p&gt;Query and Handler in one short file. That’s how I like it.&lt;/p&gt;




&lt;h3&gt;
  
  
  Upgrade Code with MediatR Attributed Behaviors
&lt;/h3&gt;

&lt;h4&gt;
  
  
  MediatR Pipeline
&lt;/h4&gt;

&lt;p&gt;Before moving to my last upgrade, I need to explain what MediatR Pipeline is. It is a pipeline defined for one MediatR Request (message). Pipelines execution starts with &lt;code&gt;Mediator.Send&lt;/code&gt; method invocation and passing an object of MediatR Request into it.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faawz8aatu0oob2ib8yum.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faawz8aatu0oob2ib8yum.jpeg" alt="Illustration" width="272" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note: if you enjoy small, practical ways to keep code clean like this, I share short free lessons in &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a tiny email series you can join in one click.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Simple pipeline&lt;/p&gt;

&lt;h4&gt;
  
  
  Pipeline Behaviors
&lt;/h4&gt;

&lt;p&gt;MediatR has a feature called &lt;strong&gt;Pipeline Behaviors&lt;/strong&gt;. Behaviors can be attached to the pipeline by defining a proper interface implementation.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4t6ajeghi6ibg0z20ut.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4t6ajeghi6ibg0z20ut.png" alt="Illustration" width="786" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pipeline with behaviors&lt;/p&gt;

&lt;p&gt;You can attach Behavior &lt;strong&gt;before or after Handler&lt;/strong&gt;, depends where you will invoke the &lt;code&gt;next()&lt;/code&gt; delegate. A typical example can be a Validation Behavior that will validate the MediatR Request form before Handler.&lt;/p&gt;

&lt;p&gt;Now some code. This is my new &lt;code&gt;CreateWarehouseCommand&lt;/code&gt; pipeline. The code in the Handler is not vital for proof of the concept. What it does is to persist the new Warehouse record into the database.&lt;/p&gt;

&lt;p&gt;Now let’s define Validation Behavior.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ValidateCreateWarehouseBehavior&lt;/code&gt; will be executed before Handler because we are invoking &lt;code&gt;next&lt;/code&gt; delegate after validation. If the &lt;code&gt;await next()&lt;/code&gt; was at line 14 before &lt;code&gt;if&lt;/code&gt;, Handler would be invoked before validation. This is how you can manage the position of Behavior towards the Handler or another Behavior in the pipeline.&lt;/p&gt;

&lt;p&gt;Behaviors have to be registered into the DI container &lt;strong&gt;manually&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;services.AddScoped&amp;gt;, ValidateCreatedWarehouseBehavior&amp;gt;();&lt;/p&gt;

&lt;p&gt;By the way, if you have multiple Behaviors for one pipeline, their &lt;strong&gt;order of execution is defined by order of registrations&lt;/strong&gt; into the DI container. This is an unpleasantly hidden way of behaving by MediatR. But I have a nice fix for it in the next paragraph.&lt;/p&gt;

&lt;h4&gt;
  
  
  MediatR Attributed Behaviors
&lt;/h4&gt;

&lt;p&gt;The last upgrade is the extension library for MediatR called &lt;a href="https://github.com/ITIXO/MediatR.Extensions.AttributedBehaviors" rel="noopener noreferrer"&gt;MediatR Attributed Behaviors&lt;/a&gt;. The library helps you &lt;strong&gt;remove the responsibility of manual DI registrations&lt;/strong&gt; of Behaviors from the developer. Also, you can see the Behaviors of your pipeline right over the MediatR Request definition. Take a look at the last code sample.&lt;/p&gt;

&lt;p&gt;Another power of this extension library is defining the order and scope of behaviors and passing it as other parameters.&lt;/p&gt;

&lt;p&gt;[MediatRBehavior(typeof(MySingletonPipelineBehavior), serviceLifetime: ServiceLifetime.Singleton, order: 1)]&lt;br&gt;&lt;br&gt;
public class MyQuery : IRequest&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/jbogard/MediatR" rel="noopener noreferrer"&gt;MediatR GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/ITIXO/MediatR.Extensions.AttributedBehaviors" rel="noopener noreferrer"&gt;MediatR Attributes GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Last Words
&lt;/h3&gt;

&lt;p&gt;I appreciate your attention. I have a list of non-restricted links for each of my blog-post &lt;a href="https://danielrusnok.medium.com/daniel-rusnok-publications-9bbe82df24ab" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I am part of the &lt;a href="https://www.itixo.com" rel="noopener noreferrer"&gt;Itixo&lt;/a&gt; company organizing the biggest&amp;nbsp;.NET conference in Central Europe, &lt;a href="https://www.updateconference.net/en" rel="noopener noreferrer"&gt;Update Conference Prague&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://levelup.gitconnected.com/from-monolith-to-microservices-in-5-minutes-83069677d021" rel="noopener noreferrer"&gt;&lt;strong&gt;From Monolith to Microservices in 5 Minutes&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_a microservice architectural style is an approach to developing a single application as a suite of small services —…_levelup.gitconnected.com&lt;/a&gt;&lt;a href="https://levelup.gitconnected.com/from-monolith-to-microservices-in-5-minutes-83069677d021" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://levelup.gitconnected.com/let-me-hear-you-screaming-architecture-3adcc02f2ca3" rel="noopener noreferrer"&gt;&lt;strong&gt;Functional Organization of Folders &amp;amp; Screaming Architecture&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_The architecture should scream the intent of the system — Uncle Bob_levelup.gitconnected.com&lt;/a&gt;&lt;a href="https://levelup.gitconnected.com/let-me-hear-you-screaming-architecture-3adcc02f2ca3" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://levelup.gitconnected.com/layers-in-software-architecture-that-every-sofware-architect-should-know-76b2452b9d9a" rel="noopener noreferrer"&gt;&lt;strong&gt;Layers in Software Architecture that Every Sofware Architect should Know&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_“All architectures have the same objective - the separation of concerns. They all achieve it by dividing the software…_levelup.gitconnected.com&lt;/a&gt;&lt;a href="https://levelup.gitconnected.com/layers-in-software-architecture-that-every-sofware-architect-should-know-76b2452b9d9a" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://levelup.gitconnected.com/3-domain-centric-architectures-every-software-developer-should-know-a15727ada79f" rel="noopener noreferrer"&gt;&lt;strong&gt;3 Domain-Centric Architectures Every Software Developer Should Know&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_The first concern of the architect is to make sure that the house is usable, it is not to ensure that the house is made…_levelup.gitconnected.com&lt;/a&gt;&lt;a href="https://levelup.gitconnected.com/3-domain-centric-architectures-every-software-developer-should-know-a15727ada79f" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;







&lt;p&gt;&lt;em&gt;If this was useful, you might also like &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a short free email series, one bite-sized lesson at a time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/ugly-dependency-graph-the-mediator-design-pattern-is-the-solution-for-you-8b35df60558b" rel="noopener noreferrer"&gt;Ugly dependency graph? The Mediator Design Pattern is the solution for you.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/decoupling-with-chain-of-responsibility-pattern-in-c-1273329ed923" rel="noopener noreferrer"&gt;Decoupling with Chain of Responsibility Pattern in C#&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/3-cqrs-architectures-that-every-software-architect-should-know-a7f69aae8b6c" rel="noopener noreferrer"&gt;3 CQRS Architectures that Every Software Architect Should Know&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/3-different-ways-to-implement-value-object-in-csharp-10-d8f43e1fa4dc" rel="noopener noreferrer"&gt;3 Different Ways to Implement Value Object in C# 10&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to Implement Azure Functions in any Language with Custom Handlers</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Mon, 06 Jul 2026 15:10:41 +0000</pubDate>
      <link>https://dev.to/danielrusnok/how-to-implement-azure-functions-in-any-language-with-custom-handlers-2b8k</link>
      <guid>https://dev.to/danielrusnok/how-to-implement-azure-functions-in-any-language-with-custom-handlers-2b8k</guid>
      <description>&lt;h3&gt;
  
  
  How&amp;nbsp;to&amp;nbsp;Implement&amp;nbsp;Azure&amp;nbsp;Functions&amp;nbsp;in&amp;nbsp;any&amp;nbsp;Language&amp;nbsp;with&amp;nbsp;Custom&amp;nbsp;Handlers
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Introduction&amp;nbsp;of&amp;nbsp;Custom&amp;nbsp;Handlers&amp;nbsp;with&amp;nbsp;Demo&amp;nbsp;using&amp;nbsp;Go&amp;nbsp;Language.
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhloxx303whv6y3z5jcvd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhloxx303whv6y3z5jcvd.png" alt="How to Implement Azure Functions in any Language with Custom Handlers cover image" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;
Azure&amp;nbsp;Functions&amp;nbsp;with&amp;nbsp;Go&amp;nbsp;Language



&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Every&amp;nbsp;Azure&amp;nbsp;Function&amp;nbsp;has&amp;nbsp;its&amp;nbsp;handler.&amp;nbsp;Azure&amp;nbsp;Functions&amp;nbsp;supports&amp;nbsp;handler&amp;nbsp;implementations&amp;nbsp;in&amp;nbsp;many&amp;nbsp;different&amp;nbsp;languages&amp;nbsp;but&amp;nbsp;they&amp;nbsp;may&amp;nbsp;not&amp;nbsp;provide&amp;nbsp;a&amp;nbsp;native&amp;nbsp;implementation&amp;nbsp;in&amp;nbsp;your&amp;nbsp;favorite&amp;nbsp;language.&amp;nbsp;That&amp;nbsp;is&amp;nbsp;where&amp;nbsp;Custom&amp;nbsp;Handlers&amp;nbsp;comes&amp;nbsp;at&amp;nbsp;the&amp;nbsp;scene.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;language&amp;nbsp;of&amp;nbsp;your&amp;nbsp;choice&amp;nbsp;must&amp;nbsp;support&amp;nbsp;HTTP&amp;nbsp;communication&amp;nbsp;because&amp;nbsp;Custom&amp;nbsp;Handler&amp;nbsp;is&amp;nbsp;a&amp;nbsp;web&amp;nbsp;server&amp;nbsp;that&amp;nbsp;receives&amp;nbsp;events&amp;nbsp;from&amp;nbsp;Functions&amp;nbsp;Host&amp;nbsp;modified&amp;nbsp;into&amp;nbsp;HTTP&amp;nbsp;requests&amp;nbsp;with&amp;nbsp;JSON&amp;nbsp;payloads.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6jb1j35zxj4jxlzzad5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6jb1j35zxj4jxlzzad5.png" alt="Illustration" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;
Communication&amp;nbsp;Diagram



&lt;p&gt;&lt;strong&gt;Functions&amp;nbsp;Host&lt;/strong&gt;&amp;nbsp;is&amp;nbsp;a&amp;nbsp;bunch&amp;nbsp;of&amp;nbsp;JSON&amp;nbsp;configuration&amp;nbsp;files&amp;nbsp;where&amp;nbsp;you&amp;nbsp;will&amp;nbsp;define&amp;nbsp;which&amp;nbsp;trigger&amp;nbsp;and&amp;nbsp;bindings&amp;nbsp;you&amp;nbsp;want&amp;nbsp;to&amp;nbsp;use&amp;nbsp;and&amp;nbsp;of&amp;nbsp;course&amp;nbsp;the&amp;nbsp;path&amp;nbsp;to&amp;nbsp;the&amp;nbsp;executable&amp;nbsp;file,&amp;nbsp;which&amp;nbsp;is&amp;nbsp;our&amp;nbsp;&lt;strong&gt;Custom&amp;nbsp;Handler&lt;/strong&gt;&amp;nbsp;(Web&amp;nbsp;Server).&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;the&amp;nbsp;&lt;strong&gt;Trigger&lt;/strong&gt;&amp;nbsp;activates&amp;nbsp;by&amp;nbsp;event,&amp;nbsp;the&amp;nbsp;Functions&amp;nbsp;Host&amp;nbsp;sends&amp;nbsp;a&amp;nbsp;request&amp;nbsp;payload&amp;nbsp;to&amp;nbsp;the&amp;nbsp;Web&amp;nbsp;Server.&amp;nbsp;The&amp;nbsp;payload&amp;nbsp;can&amp;nbsp;hold&amp;nbsp;trigger&amp;nbsp;and&amp;nbsp;input&amp;nbsp;binding&amp;nbsp;data.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;&lt;strong&gt;Web&amp;nbsp;Server&lt;/strong&gt;&amp;nbsp;invokes&amp;nbsp;the&amp;nbsp;function&amp;nbsp;and&amp;nbsp;possibly&amp;nbsp;returns&amp;nbsp;a&amp;nbsp;response&amp;nbsp;payload.&amp;nbsp;A&amp;nbsp;response&amp;nbsp;payload&amp;nbsp;can&amp;nbsp;be&amp;nbsp;used&amp;nbsp;for&amp;nbsp;output&amp;nbsp;binding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;The&amp;nbsp;source&amp;nbsp;code&amp;nbsp;can&amp;nbsp;be&amp;nbsp;found&amp;nbsp;on&amp;nbsp;my&amp;nbsp;&lt;a href="https://github.com/DannyRusnok/CustomHandlerFunctionsApp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Things&amp;nbsp;you&amp;nbsp;Need
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual&amp;nbsp;Studio&amp;nbsp;Code&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions" rel="noopener noreferrer"&gt;Azure&amp;nbsp;Functions&amp;nbsp;Extension&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#v2" rel="noopener noreferrer"&gt;Azure&amp;nbsp;Functions&amp;nbsp;Core&amp;nbsp;Tools&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://golang.org/doc/install" rel="noopener noreferrer"&gt;Go&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Create&amp;nbsp;Project
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftq7tihmflx9q6o6oh7sa.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftq7tihmflx9q6o6oh7sa.png" alt="Illustration" width="600" height="258"&gt;&lt;/a&gt;&lt;/p&gt;
Location&amp;nbsp;of&amp;nbsp;Create&amp;nbsp;New&amp;nbsp;Project&amp;nbsp;Button



&lt;ol&gt;
&lt;li&gt; Click&amp;nbsp;on&amp;nbsp;the&amp;nbsp;button&amp;nbsp;highlighted&amp;nbsp;in&amp;nbsp;the&amp;nbsp;image&amp;nbsp;to&amp;nbsp;create&amp;nbsp;a&amp;nbsp;new&amp;nbsp;project.&lt;/li&gt;
&lt;li&gt; You&amp;nbsp;will&amp;nbsp;be&amp;nbsp;asked&amp;nbsp;to&amp;nbsp;choose&amp;nbsp;basic&amp;nbsp;settings.&amp;nbsp;Select&amp;nbsp;&lt;strong&gt;Custom&lt;/strong&gt;&amp;nbsp;language,&amp;nbsp;&lt;strong&gt;HTTP&amp;nbsp;Trigger&lt;/strong&gt;,&amp;nbsp;&lt;strong&gt;HttpExample&lt;/strong&gt;&amp;nbsp;as&amp;nbsp;a&amp;nbsp;name&amp;nbsp;of&amp;nbsp;the&amp;nbsp;function,&amp;nbsp;and&amp;nbsp;&lt;strong&gt;Anonymous&lt;/strong&gt;&amp;nbsp;authorization&amp;nbsp;level&amp;nbsp;to&amp;nbsp;define&amp;nbsp;Function&amp;nbsp;Host.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Create&amp;nbsp;a&amp;nbsp;Handler
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; Create&amp;nbsp;a&amp;nbsp;file&amp;nbsp;in&amp;nbsp;the&amp;nbsp;root&amp;nbsp;folder&amp;nbsp;and&amp;nbsp;save&amp;nbsp;it&amp;nbsp;as&amp;nbsp;&lt;code&gt;handler.go.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Copy/Paste&amp;nbsp;this&amp;nbsp;code&amp;nbsp;into&amp;nbsp;the&amp;nbsp;file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The&amp;nbsp;function&amp;nbsp;&lt;code&gt;helloHandler&lt;/code&gt;&amp;nbsp;is&amp;nbsp;printing&amp;nbsp;a&amp;nbsp;simple&amp;nbsp;message&amp;nbsp;as&amp;nbsp;an&amp;nbsp;HTTP&amp;nbsp;response.&amp;nbsp;The&amp;nbsp;form&amp;nbsp;of&amp;nbsp;the&amp;nbsp;message&amp;nbsp;depends&amp;nbsp;on&amp;nbsp;the&amp;nbsp;value&amp;nbsp;of&amp;nbsp;&lt;code&gt;name&lt;/code&gt;parameter&amp;nbsp;in&amp;nbsp;the&amp;nbsp;HTTP&amp;nbsp;request.&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;the&amp;nbsp;value&amp;nbsp;&lt;code&gt;name&lt;/code&gt;&amp;nbsp;is&amp;nbsp;set,&amp;nbsp;the&amp;nbsp;response&amp;nbsp;will&amp;nbsp;be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello, {name}. This HTTP triggered function executed successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If&amp;nbsp;the&amp;nbsp;value&amp;nbsp;&lt;code&gt;name&lt;/code&gt;&amp;nbsp;is&amp;nbsp;&lt;strong&gt;NOT&lt;/strong&gt;&amp;nbsp;set,&amp;nbsp;the&amp;nbsp;response&amp;nbsp;will&amp;nbsp;look&amp;nbsp;like&amp;nbsp;this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This HTTP triggered function executed successfully. Pass a name in the query string for a personalized response.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.&amp;nbsp;Open&amp;nbsp;a&amp;nbsp;command&amp;nbsp;line&amp;nbsp;or&amp;nbsp;PowerShell&amp;nbsp;and&amp;nbsp;compile&amp;nbsp;Custom&amp;nbsp;Handler&amp;nbsp;into&amp;nbsp;an&amp;nbsp;executable&amp;nbsp;file&amp;nbsp;named&amp;nbsp;&lt;code&gt;handler.exe&lt;/code&gt;&amp;nbsp;by&amp;nbsp;using&amp;nbsp;this&amp;nbsp;command&amp;nbsp;(installed&amp;nbsp;Go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go build handler.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Modify&amp;nbsp;host.json
&lt;/h4&gt;

&lt;p&gt;Now&amp;nbsp;you&amp;nbsp;need&amp;nbsp;to&amp;nbsp;specify&amp;nbsp;the&amp;nbsp;file&amp;nbsp;path&amp;nbsp;for&amp;nbsp;&lt;code&gt;customHandler:defaulteExecutablePath&lt;/code&gt;&amp;nbsp;property&amp;nbsp;in&amp;nbsp;host.json.&amp;nbsp;If&amp;nbsp;you&amp;nbsp;created&amp;nbsp;the&amp;nbsp;&lt;code&gt;*.exe&lt;/code&gt;&amp;nbsp;file&amp;nbsp;in&amp;nbsp;the&amp;nbsp;root&amp;nbsp;folder,&amp;nbsp;you&amp;nbsp;can&amp;nbsp;set&amp;nbsp;the&amp;nbsp;value&amp;nbsp;to&amp;nbsp;&lt;code&gt;handler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You&amp;nbsp;also&amp;nbsp;need&amp;nbsp;to&amp;nbsp;set&amp;nbsp;the&amp;nbsp;value&amp;nbsp;of&amp;nbsp;&lt;code&gt;customHandler:eneableForwardingHttpRequest&lt;/code&gt;&amp;nbsp;to&amp;nbsp;&lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On a side note — if you like getting your tooling set up properly like this, I put together a short free email series, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt;, on giving AI coding agents a persistent memory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Run&amp;nbsp;the&amp;nbsp;function
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; Open&amp;nbsp;a&amp;nbsp;command&amp;nbsp;line&amp;nbsp;or&amp;nbsp;PowerShell&amp;nbsp;again&amp;nbsp;and&amp;nbsp;run&amp;nbsp;this&amp;nbsp;command&amp;nbsp;(installed&amp;nbsp;Azure&amp;nbsp;Function&amp;nbsp;Core&amp;nbsp;Tools)&amp;nbsp;in&amp;nbsp;the&amp;nbsp;root&amp;nbsp;folder:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;func start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.&amp;nbsp;Navigate&amp;nbsp;to&amp;nbsp;the&amp;nbsp;following&amp;nbsp;URL&amp;nbsp;to&amp;nbsp;execute&amp;nbsp;the&amp;nbsp;function:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[http://localhost:7071/api/HttpExample?name=medium](http://localhost:7071/api/HttpExample?name=medium)&lt;/code&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhd0smmzteoh2376rn3t.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhd0smmzteoh2376rn3t.png" alt="Illustration" width="518" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;you&amp;nbsp;get&amp;nbsp;a&amp;nbsp;similar&amp;nbsp;response&amp;nbsp;as&amp;nbsp;me,&amp;nbsp;you&amp;nbsp;were&amp;nbsp;successful.&lt;/p&gt;

&lt;p&gt;3.&amp;nbsp;You&amp;nbsp;can&amp;nbsp;also&amp;nbsp;take&amp;nbsp;a&amp;nbsp;look&amp;nbsp;into&amp;nbsp;the&amp;nbsp;console&amp;nbsp;and&amp;nbsp;see&amp;nbsp;if&amp;nbsp;your&amp;nbsp;function&amp;nbsp;was&amp;nbsp;executed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fckvj31tp3kqtynqg9vx9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fckvj31tp3kqtynqg9vx9.png" alt="Illustration" width="799" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;We&amp;nbsp;found&amp;nbsp;out&amp;nbsp;what&amp;nbsp;Custom&amp;nbsp;Handlers&amp;nbsp;of&amp;nbsp;Azure&amp;nbsp;Functions&amp;nbsp;are,&amp;nbsp;how&amp;nbsp;they&amp;nbsp;work,&amp;nbsp;and&amp;nbsp;how&amp;nbsp;we&amp;nbsp;can&amp;nbsp;easily&amp;nbsp;implement&amp;nbsp;them&amp;nbsp;with&amp;nbsp;Go&amp;nbsp;language.&amp;nbsp;As&amp;nbsp;a&amp;nbsp;next&amp;nbsp;step,&amp;nbsp;I&amp;nbsp;would&amp;nbsp;recommend&amp;nbsp;that&amp;nbsp;you&amp;nbsp;should&amp;nbsp;try&amp;nbsp;to&amp;nbsp;publish&amp;nbsp;function&amp;nbsp;into&amp;nbsp;the&amp;nbsp;Azure.&lt;/p&gt;

&lt;p&gt;If&amp;nbsp;you&amp;nbsp;like&amp;nbsp;the&amp;nbsp;article,&amp;nbsp;give&amp;nbsp;it&amp;nbsp;a&amp;nbsp;few&amp;nbsp;claps.&amp;nbsp;Thank&amp;nbsp;you&amp;nbsp;for&amp;nbsp;your&amp;nbsp;time.&lt;/p&gt;

&lt;p&gt;If a topic like this is your kind of thing, you might also enjoy my free email series &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a few short lessons on giving AI coding tools a memory that sticks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-custom-handlers" rel="noopener noreferrer"&gt;Microsoft&amp;nbsp;documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Pluralsight&amp;nbsp;course&amp;nbsp;by&amp;nbsp;Mark&amp;nbsp;Heath&amp;nbsp;—&amp;nbsp;&lt;a href="https://app.pluralsight.com/library/courses/microsoft-azure-developer-implement-azure-functions" rel="noopener noreferrer"&gt;Microsoft&amp;nbsp;Azure&amp;nbsp;Developer:&amp;nbsp;Implement&amp;nbsp;Azure&amp;nbsp;Functions.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Further&amp;nbsp;Reading
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;How&amp;nbsp;to&amp;nbsp;Create&amp;nbsp;a&amp;nbsp;Free&amp;nbsp;Azure&amp;nbsp;Account&amp;nbsp;Step&amp;nbsp;by&amp;nbsp;Step&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;Guide&amp;nbsp;for&amp;nbsp;creating&amp;nbsp;a&amp;nbsp;free&amp;nbsp;Azure&amp;nbsp;account.&amp;nbsp;What&amp;nbsp;services&amp;nbsp;you&amp;nbsp;can&amp;nbsp;use&amp;nbsp;for&amp;nbsp;free?&amp;nbsp;What&amp;nbsp;is&amp;nbsp;Directory&amp;nbsp;or&amp;nbsp;subscription&amp;nbsp;and&amp;nbsp;what…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;levelup.gitconnected.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Introduction&amp;nbsp;to&amp;nbsp;Cloud&amp;nbsp;Computing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Cloud&amp;nbsp;computing&amp;nbsp;is&amp;nbsp;the&amp;nbsp;present&amp;nbsp;and&amp;nbsp;future&amp;nbsp;of&amp;nbsp;software&amp;nbsp;utilization,&amp;nbsp;development&amp;nbsp;and&amp;nbsp;hosting.&amp;nbsp;Let&amp;nbsp;me&amp;nbsp;introduce&amp;nbsp;you&amp;nbsp;its…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;levelup.gitconnected.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;Understanding&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Groups&amp;nbsp;and&amp;nbsp;Azure&amp;nbsp;Resources&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;Also&amp;nbsp;with&amp;nbsp;Guide&amp;nbsp;How&amp;nbsp;to&amp;nbsp;Create&amp;nbsp;your&amp;nbsp;First&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Group&amp;nbsp;and&amp;nbsp;Add&amp;nbsp;your&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Into&amp;nbsp;it.&lt;/a&gt;&lt;/em&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;danielrusnok.medium.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;How&amp;nbsp;to&amp;nbsp;Choose&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Region&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;What&amp;nbsp;you&amp;nbsp;should&amp;nbsp;consider&amp;nbsp;before&amp;nbsp;choosing&amp;nbsp;Azure&amp;nbsp;Region?&amp;nbsp;How&amp;nbsp;Microsoft&amp;nbsp;geographically&amp;nbsp;divide&amp;nbsp;datacentres&amp;nbsp;position&amp;nbsp;to…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;danielrusnok.medium.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/danielrusnok" rel="noopener noreferrer"&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%2F5tm54rf5555ym89o2ne4.png" alt="Illustration" width="200" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;nbsp;Related&amp;nbsp;Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/introduction-to-cloud-computing-235e530b9fe0%5D%C2%A0%E2%80%94%C2%A0_Introduction%C2%A0to%C2%A0Cloud%C2%A0Computing_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/introduction-to-cloud-computing-235e530b9fe0]&amp;nbsp;—&amp;nbsp;_Introduction&amp;nbsp;to&amp;nbsp;Cloud&amp;nbsp;Computing_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6%5D%C2%A0%E2%80%94%C2%A0_Understanding%C2%A0the%C2%A0Azure%C2%A0Resource%C2%A0Groups%C2%A0and%C2%A0Azure%C2%A0Resources_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6]&amp;nbsp;—&amp;nbsp;_Understanding&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Groups&amp;nbsp;and&amp;nbsp;Azure&amp;nbsp;Resources_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/from-monolith-to-microservices-in-5-minutes-83069677d021%5D%C2%A0%E2%80%94%C2%A0_From%C2%A0Monolith%C2%A0to%C2%A0Microservices%C2%A0in%C2%A05%C2%A0Minutes_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/from-monolith-to-microservices-in-5-minutes-83069677d021]&amp;nbsp;—&amp;nbsp;_From&amp;nbsp;Monolith&amp;nbsp;to&amp;nbsp;Microservices&amp;nbsp;in&amp;nbsp;5&amp;nbsp;Minutes_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/my-introduction-into-azure-service-fabric-de65cc72a7b5%5D%C2%A0%E2%80%94%C2%A0_My%C2%A0introduction%C2%A0into%C2%A0Azure%C2%A0Service%C2%A0Fabric_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/my-introduction-into-azure-service-fabric-de65cc72a7b5]&amp;nbsp;—&amp;nbsp;_My&amp;nbsp;introduction&amp;nbsp;into&amp;nbsp;Azure&amp;nbsp;Service&amp;nbsp;Fabric_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/no-more-mess-in-my-head-around-phrases-related-to-identity-in-computing-482cd0f8cad3%5D%C2%A0%E2%80%94%C2%A0_No%C2%A0More%C2%A0Mess%C2%A0in%C2%A0my%C2%A0Head%C2%A0Around%C2%A0Phrases%C2%A0Related%C2%A0to%C2%A0Identity%C2%A0in%C2%A0Computing_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/no-more-mess-in-my-head-around-phrases-related-to-identity-in-computing-482cd0f8cad3]&amp;nbsp;—&amp;nbsp;_No&amp;nbsp;More&amp;nbsp;Mess&amp;nbsp;in&amp;nbsp;my&amp;nbsp;Head&amp;nbsp;Around&amp;nbsp;Phrases&amp;nbsp;Related&amp;nbsp;to&amp;nbsp;Identity&amp;nbsp;in&amp;nbsp;Computing_&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>go</category>
      <category>serverless</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>3 Things that Change my Way of Thinking in 2020</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Sat, 04 Jul 2026 15:19:33 +0000</pubDate>
      <link>https://dev.to/danielrusnok/3-things-that-change-my-way-of-thinking-in-2020-24hb</link>
      <guid>https://dev.to/danielrusnok/3-things-that-change-my-way-of-thinking-in-2020-24hb</guid>
      <description>&lt;h3&gt;
  
  
  3&amp;nbsp;Things&amp;nbsp;that&amp;nbsp;Change&amp;nbsp;my&amp;nbsp;Way&amp;nbsp;of&amp;nbsp;Thinking&amp;nbsp;in&amp;nbsp;2020
&lt;/h3&gt;

&lt;h4&gt;
  
  
  This&amp;nbsp;is&amp;nbsp;a&amp;nbsp;list&amp;nbsp;of&amp;nbsp;things&amp;nbsp;that&amp;nbsp;completely&amp;nbsp;changed&amp;nbsp;me&amp;nbsp;in&amp;nbsp;2020,&amp;nbsp;and&amp;nbsp;it&amp;nbsp;was&amp;nbsp;not&amp;nbsp;the&amp;nbsp;COVID-19.
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o6y5sn70ajyxgg4hwc2.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o6y5sn70ajyxgg4hwc2.jpeg" alt="3 Things that Change my Way of Thinking in 2020 cover image" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This&amp;nbsp;year&amp;nbsp;is&amp;nbsp;hard&amp;nbsp;for&amp;nbsp;all&amp;nbsp;of&amp;nbsp;us.&amp;nbsp;When&amp;nbsp;everybody&amp;nbsp;is&amp;nbsp;scared&amp;nbsp;of&amp;nbsp;how&amp;nbsp;global&amp;nbsp;warming&amp;nbsp;affects&amp;nbsp;humanity's&amp;nbsp;future,&amp;nbsp;other&amp;nbsp;catastrophes&amp;nbsp;came&amp;nbsp;by.&amp;nbsp;Large&amp;nbsp;fires&amp;nbsp;in&amp;nbsp;Australia,&amp;nbsp;COVID-19&amp;nbsp;Pandemic,&amp;nbsp;American&amp;nbsp;Riots,&amp;nbsp;and&amp;nbsp;recent&amp;nbsp;events,&amp;nbsp;the&amp;nbsp;Islamic&amp;nbsp;state’s&amp;nbsp;strikes&amp;nbsp;in&amp;nbsp;France&amp;nbsp;and&amp;nbsp;Austria.&lt;/p&gt;

&lt;p&gt;But&amp;nbsp;from&amp;nbsp;my&amp;nbsp;individual&amp;nbsp;perspective,&amp;nbsp;I&amp;nbsp;love&amp;nbsp;the&amp;nbsp;year&amp;nbsp;2020.&amp;nbsp;This&amp;nbsp;year&amp;nbsp;was&amp;nbsp;groundbreaking&amp;nbsp;for&amp;nbsp;my&amp;nbsp;career.&amp;nbsp;My&amp;nbsp;long-term&amp;nbsp;relationship&amp;nbsp;with&amp;nbsp;the&amp;nbsp;love&amp;nbsp;of&amp;nbsp;my&amp;nbsp;life&amp;nbsp;could&amp;nbsp;not&amp;nbsp;be&amp;nbsp;better,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;doubled&amp;nbsp;my&amp;nbsp;incomes&amp;nbsp;in&amp;nbsp;nine&amp;nbsp;months.&amp;nbsp;Here&amp;nbsp;is&amp;nbsp;what&amp;nbsp;happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entrepreneurship
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzrm298r0y6vkqpopumj7.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzrm298r0y6vkqpopumj7.jpeg" alt="Illustration" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last&amp;nbsp;year&amp;nbsp;was&amp;nbsp;the&amp;nbsp;last&amp;nbsp;time&amp;nbsp;I&amp;nbsp;was&amp;nbsp;an&amp;nbsp;employee.&amp;nbsp;I&amp;nbsp;quit&amp;nbsp;and&amp;nbsp;concluded&amp;nbsp;a&amp;nbsp;new&amp;nbsp;contract&amp;nbsp;with&amp;nbsp;the&amp;nbsp;same&amp;nbsp;company&amp;nbsp;I&amp;nbsp;worked&amp;nbsp;for,&amp;nbsp;but&amp;nbsp;this&amp;nbsp;time&amp;nbsp;as&amp;nbsp;a&amp;nbsp;hired&amp;nbsp;entrepreneur.&lt;/p&gt;

&lt;p&gt;Becoming&amp;nbsp;an&amp;nbsp;entrepreneur&amp;nbsp;was&amp;nbsp;not&amp;nbsp;my&amp;nbsp;idea.&amp;nbsp;The&amp;nbsp;origin&amp;nbsp;of&amp;nbsp;it&amp;nbsp;comes&amp;nbsp;from&amp;nbsp;the&amp;nbsp;CEO&amp;nbsp;of&amp;nbsp;the&amp;nbsp;mentioned&amp;nbsp;company&amp;nbsp;and&amp;nbsp;also&amp;nbsp;my&amp;nbsp;good&amp;nbsp;friend.&amp;nbsp;“It&amp;nbsp;will&amp;nbsp;suit&amp;nbsp;you&amp;nbsp;and&amp;nbsp;open&amp;nbsp;doors&amp;nbsp;for&amp;nbsp;you.&amp;nbsp;You’ll&amp;nbsp;see.”&amp;nbsp;He&amp;nbsp;told&amp;nbsp;me.&amp;nbsp;And&amp;nbsp;in&amp;nbsp;a&amp;nbsp;few&amp;nbsp;months,&amp;nbsp;I&amp;nbsp;find&amp;nbsp;out&amp;nbsp;he&amp;nbsp;was&amp;nbsp;right.&lt;/p&gt;

&lt;p&gt;In&amp;nbsp;the&amp;nbsp;spring,&amp;nbsp;the&amp;nbsp;company's&amp;nbsp;IT&amp;nbsp;specialist,&amp;nbsp;where&amp;nbsp;my&amp;nbsp;beloved&amp;nbsp;works,&amp;nbsp;suddenly&amp;nbsp;end&amp;nbsp;his&amp;nbsp;contract,&amp;nbsp;and&amp;nbsp;that&amp;nbsp;company&amp;nbsp;needs&amp;nbsp;to&amp;nbsp;find&amp;nbsp;someone&amp;nbsp;immediately&amp;nbsp;to&amp;nbsp;take&amp;nbsp;his&amp;nbsp;place.&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;you&amp;nbsp;are&amp;nbsp;an&amp;nbsp;entrepreneur,&amp;nbsp;you&amp;nbsp;can&amp;nbsp;have&amp;nbsp;as&amp;nbsp;many&amp;nbsp;customers&amp;nbsp;as&amp;nbsp;you&amp;nbsp;can&amp;nbsp;handle.&amp;nbsp;So&amp;nbsp;I&amp;nbsp;immediately&amp;nbsp;took&amp;nbsp;his&amp;nbsp;place&amp;nbsp;and&amp;nbsp;migrated&amp;nbsp;all&amp;nbsp;of&amp;nbsp;the&amp;nbsp;company’s&amp;nbsp;IT&amp;nbsp;obligations&amp;nbsp;under&amp;nbsp;my&amp;nbsp;wings.&lt;/p&gt;

&lt;p&gt;After&amp;nbsp;a&amp;nbsp;tough&amp;nbsp;week&amp;nbsp;of&amp;nbsp;work,&amp;nbsp;the&amp;nbsp;work&amp;nbsp;was&amp;nbsp;done,&amp;nbsp;and&amp;nbsp;now&amp;nbsp;it&amp;nbsp;cost&amp;nbsp;me&amp;nbsp;a&amp;nbsp;few&amp;nbsp;hours&amp;nbsp;of&amp;nbsp;work&amp;nbsp;every&amp;nbsp;month,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;am&amp;nbsp;paid&amp;nbsp;more&amp;nbsp;than&amp;nbsp;well.&amp;nbsp;I&amp;nbsp;couldn’t&amp;nbsp;achieve&amp;nbsp;it&amp;nbsp;if&amp;nbsp;I&amp;nbsp;stay&amp;nbsp;an&amp;nbsp;employee.&lt;/p&gt;

&lt;p&gt;Entrepreneurship&amp;nbsp;brings&amp;nbsp;you&amp;nbsp;the&amp;nbsp;freedom&amp;nbsp;to&amp;nbsp;do&amp;nbsp;more&amp;nbsp;and&amp;nbsp;help&amp;nbsp;others&amp;nbsp;more.&amp;nbsp;It&amp;nbsp;unlocks&amp;nbsp;a&amp;nbsp;different&amp;nbsp;way&amp;nbsp;of&amp;nbsp;thinking&amp;nbsp;about&amp;nbsp;work-life.&lt;/p&gt;

&lt;h3&gt;
  
  
  Psychology
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86diki88jrlm7ohykqqf.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86diki88jrlm7ohykqqf.jpeg" alt="Illustration" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I&amp;nbsp;am&amp;nbsp;Youtube&amp;nbsp;addicted.&amp;nbsp;Especially&amp;nbsp;when&amp;nbsp;it&amp;nbsp;comes&amp;nbsp;to&amp;nbsp;stand-up&amp;nbsp;comedy&amp;nbsp;or&amp;nbsp;TED&amp;nbsp;talks.&amp;nbsp;Someday&amp;nbsp;in&amp;nbsp;February,&amp;nbsp;I&amp;nbsp;came&amp;nbsp;across&amp;nbsp;the&amp;nbsp;famous&amp;nbsp;&lt;a href="https://www.youtube.com/watch?v=aMcjxSThD54&amp;amp;ab_channel=Channel4News" rel="noopener noreferrer"&gt;interview&amp;nbsp;of&amp;nbsp;Cathy&amp;nbsp;Newman&amp;nbsp;with&amp;nbsp;Dr.&amp;nbsp;Jordan&amp;nbsp;B.&amp;nbsp;Peterson&lt;/a&gt;.&amp;nbsp;The&amp;nbsp;interview&amp;nbsp;topic&amp;nbsp;should&amp;nbsp;be&amp;nbsp;the&amp;nbsp;doctor’s&amp;nbsp;new&amp;nbsp;book,&amp;nbsp;&lt;a href="https://en.wikipedia.org/wiki/12_Rules_for_Life" rel="noopener noreferrer"&gt;The&amp;nbsp;12&amp;nbsp;Rules&amp;nbsp;for&amp;nbsp;Life&amp;nbsp;—&amp;nbsp;An&amp;nbsp;Antidote&amp;nbsp;to&amp;nbsp;Chaos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From&amp;nbsp;my&amp;nbsp;perspective,&amp;nbsp;it&amp;nbsp;was&amp;nbsp;obvious&amp;nbsp;that&amp;nbsp;the&amp;nbsp;interviewer&amp;nbsp;does&amp;nbsp;not&amp;nbsp;read&amp;nbsp;the&amp;nbsp;book&amp;nbsp;nor&amp;nbsp;read&amp;nbsp;it&amp;nbsp;with&amp;nbsp;an&amp;nbsp;open&amp;nbsp;mind.&amp;nbsp;Peterson’s&amp;nbsp;comments&amp;nbsp;on&amp;nbsp;young&amp;nbsp;men’s&amp;nbsp;mindsets&amp;nbsp;touched&amp;nbsp;me,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;decided&amp;nbsp;to&amp;nbsp;search&amp;nbsp;for&amp;nbsp;another&amp;nbsp;his&amp;nbsp;interviews&amp;nbsp;or&amp;nbsp;lectures.&lt;/p&gt;

&lt;p&gt;Therefore,&amp;nbsp;I&amp;nbsp;found&amp;nbsp;out&amp;nbsp;that&amp;nbsp;he&amp;nbsp;uploads&amp;nbsp;all&amp;nbsp;of&amp;nbsp;his&amp;nbsp;psychology&amp;nbsp;lectures&amp;nbsp;for&amp;nbsp;free,&amp;nbsp;and&amp;nbsp;now&amp;nbsp;I&amp;nbsp;can’t&amp;nbsp;be&amp;nbsp;more&amp;nbsp;thankful.&amp;nbsp;It&amp;nbsp;answers&amp;nbsp;so&amp;nbsp;many&amp;nbsp;questions&amp;nbsp;every&amp;nbsp;young&amp;nbsp;man&amp;nbsp;has.&amp;nbsp;I&amp;nbsp;recommend&amp;nbsp;you&amp;nbsp;read&amp;nbsp;his&amp;nbsp;book&amp;nbsp;or&amp;nbsp;play&amp;nbsp;one&amp;nbsp;of&amp;nbsp;those&amp;nbsp;videos.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;main&amp;nbsp;thought&amp;nbsp;I&amp;nbsp;learn&amp;nbsp;from&amp;nbsp;him&amp;nbsp;is&amp;nbsp;that&amp;nbsp;life's&amp;nbsp;meaning&amp;nbsp;can&amp;nbsp;be&amp;nbsp;found&amp;nbsp;in&amp;nbsp;responsibility.&amp;nbsp;How&amp;nbsp;much&amp;nbsp;responsibility&amp;nbsp;you&amp;nbsp;can&amp;nbsp;take,&amp;nbsp;that&amp;nbsp;much&amp;nbsp;is&amp;nbsp;your&amp;nbsp;life&amp;nbsp;meaningful&amp;nbsp;for&amp;nbsp;you,&amp;nbsp;your&amp;nbsp;loved&amp;nbsp;ones,&amp;nbsp;your&amp;nbsp;community,&amp;nbsp;and&amp;nbsp;even&amp;nbsp;for&amp;nbsp;the&amp;nbsp;world.&lt;/p&gt;

&lt;p&gt;Take&amp;nbsp;responsibility&amp;nbsp;for&amp;nbsp;your&amp;nbsp;life&amp;nbsp;on&amp;nbsp;your&amp;nbsp;shoulders.&amp;nbsp;Stop&amp;nbsp;accusing&amp;nbsp;the&amp;nbsp;law,&amp;nbsp;the&amp;nbsp;rich&amp;nbsp;people,&amp;nbsp;or&amp;nbsp;the&amp;nbsp;economy&amp;nbsp;for&amp;nbsp;your&amp;nbsp;problems.&amp;nbsp;You&amp;nbsp;are&amp;nbsp;the&amp;nbsp;one&amp;nbsp;who&amp;nbsp;can&amp;nbsp;change&amp;nbsp;everything&amp;nbsp;in&amp;nbsp;your&amp;nbsp;life.&lt;/p&gt;

&lt;p&gt;Don’t&amp;nbsp;wait&amp;nbsp;until&amp;nbsp;some&amp;nbsp;politicians&amp;nbsp;discuss&amp;nbsp;the&amp;nbsp;problems&amp;nbsp;of&amp;nbsp;groups&amp;nbsp;in&amp;nbsp;society&amp;nbsp;you&amp;nbsp;are&amp;nbsp;part&amp;nbsp;of.&amp;nbsp;The&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;your&amp;nbsp;problem&amp;nbsp;can&amp;nbsp;be&amp;nbsp;only&amp;nbsp;one&amp;nbsp;google&amp;nbsp;search&amp;nbsp;away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Physical&amp;nbsp;Health
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewkd4cpqfwcw4yhta8yl.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewkd4cpqfwcw4yhta8yl.jpeg" alt="Illustration" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I&amp;nbsp;was&amp;nbsp;good&amp;nbsp;at&amp;nbsp;sports&amp;nbsp;in&amp;nbsp;my&amp;nbsp;whole&amp;nbsp;childhood.&amp;nbsp;I&amp;nbsp;played&amp;nbsp;hockey&amp;nbsp;for&amp;nbsp;ten&amp;nbsp;years.&amp;nbsp;Hockey&amp;nbsp;is&amp;nbsp;a&amp;nbsp;big&amp;nbsp;deal&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Czech&amp;nbsp;Republic,&amp;nbsp;and&amp;nbsp;many&amp;nbsp;young&amp;nbsp;men&amp;nbsp;start&amp;nbsp;with&amp;nbsp;hockey&amp;nbsp;at&amp;nbsp;a&amp;nbsp;really&amp;nbsp;young&amp;nbsp;age.&lt;/p&gt;

&lt;p&gt;More&amp;nbsp;precisely,&amp;nbsp;I&amp;nbsp;was&amp;nbsp;a&amp;nbsp;goalie.&amp;nbsp;I&amp;nbsp;wasn’t&amp;nbsp;in&amp;nbsp;a&amp;nbsp;stable&amp;nbsp;form,&amp;nbsp;once&amp;nbsp;I&amp;nbsp;catch&amp;nbsp;every&amp;nbsp;puck,&amp;nbsp;once&amp;nbsp;I&amp;nbsp;got&amp;nbsp;15&amp;nbsp;goals&amp;nbsp;in&amp;nbsp;one&amp;nbsp;match.&amp;nbsp;Today&amp;nbsp;I&amp;nbsp;think&amp;nbsp;it&amp;nbsp;was&amp;nbsp;unstable&amp;nbsp;self-esteem.&amp;nbsp;In&amp;nbsp;the&amp;nbsp;last&amp;nbsp;two&amp;nbsp;years&amp;nbsp;of&amp;nbsp;my&amp;nbsp;career,&amp;nbsp;I&amp;nbsp;was&amp;nbsp;bullied&amp;nbsp;by&amp;nbsp;the&amp;nbsp;team&amp;nbsp;members&amp;nbsp;for&amp;nbsp;my&amp;nbsp;bad&amp;nbsp;results&amp;nbsp;on&amp;nbsp;the&amp;nbsp;ice.&lt;/p&gt;

&lt;p&gt;Suddenly,&amp;nbsp;I&amp;nbsp;quit&amp;nbsp;hockey.&amp;nbsp;It&amp;nbsp;was&amp;nbsp;a&amp;nbsp;busy&amp;nbsp;childhood.&amp;nbsp;Four&amp;nbsp;pieces&amp;nbsp;of&amp;nbsp;training&amp;nbsp;weekly&amp;nbsp;plus&amp;nbsp;match&amp;nbsp;on&amp;nbsp;the&amp;nbsp;weekend&amp;nbsp;in&amp;nbsp;winter&amp;nbsp;and&amp;nbsp;five&amp;nbsp;pieces&amp;nbsp;of&amp;nbsp;training&amp;nbsp;in&amp;nbsp;summer.&amp;nbsp;It&amp;nbsp;was&amp;nbsp;a&amp;nbsp;relief.&lt;/p&gt;

&lt;p&gt;Since&amp;nbsp;then,&amp;nbsp;I&amp;nbsp;never&amp;nbsp;workout&amp;nbsp;for&amp;nbsp;more&amp;nbsp;than&amp;nbsp;one&amp;nbsp;week.&amp;nbsp;But&amp;nbsp;this&amp;nbsp;year,&amp;nbsp;I&amp;nbsp;find&amp;nbsp;out&amp;nbsp;through&amp;nbsp;my&amp;nbsp;study&amp;nbsp;that&amp;nbsp;mental&amp;nbsp;health&amp;nbsp;relies&amp;nbsp;heavily&amp;nbsp;on&amp;nbsp;physical&amp;nbsp;health,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;want&amp;nbsp;to&amp;nbsp;work&amp;nbsp;a&amp;nbsp;whole&amp;nbsp;day&amp;nbsp;and&amp;nbsp;don’t&amp;nbsp;feel&amp;nbsp;tired&amp;nbsp;the&amp;nbsp;next&amp;nbsp;morning.&amp;nbsp;So&amp;nbsp;I&amp;nbsp;want&amp;nbsp;to&amp;nbsp;do&amp;nbsp;something&amp;nbsp;about&amp;nbsp;it.&lt;/p&gt;

&lt;p&gt;First,&amp;nbsp;I&amp;nbsp;cut&amp;nbsp;the&amp;nbsp;amount&amp;nbsp;of&amp;nbsp;alcohol&amp;nbsp;consumption&amp;nbsp;to&amp;nbsp;almost&amp;nbsp;zero.&amp;nbsp;As&amp;nbsp;a&amp;nbsp;Czech&amp;nbsp;man,&amp;nbsp;I&amp;nbsp;don’t&amp;nbsp;count&amp;nbsp;one&amp;nbsp;beer&amp;nbsp;after&amp;nbsp;lunch&amp;nbsp;into&amp;nbsp;it.&amp;nbsp;But&amp;nbsp;these&amp;nbsp;situations&amp;nbsp;or&amp;nbsp;rarer&amp;nbsp;than&amp;nbsp;ever&amp;nbsp;before.&lt;/p&gt;

&lt;p&gt;Second,&amp;nbsp;I&amp;nbsp;talked&amp;nbsp;to&amp;nbsp;my&amp;nbsp;girlfriend&amp;nbsp;about&amp;nbsp;the&amp;nbsp;food,&amp;nbsp;and&amp;nbsp;she&amp;nbsp;taught&amp;nbsp;me&amp;nbsp;the&amp;nbsp;basics&amp;nbsp;of&amp;nbsp;balancing&amp;nbsp;my&amp;nbsp;daily&amp;nbsp;food&amp;nbsp;income.&amp;nbsp;Now&amp;nbsp;I&amp;nbsp;am&amp;nbsp;eating&amp;nbsp;mashed&amp;nbsp;eggs&amp;nbsp;every&amp;nbsp;morning&amp;nbsp;and&amp;nbsp;dine&amp;nbsp;a&amp;nbsp;tuna&amp;nbsp;salad&amp;nbsp;every&amp;nbsp;evening,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;feel&amp;nbsp;so&amp;nbsp;light&amp;nbsp;every&amp;nbsp;morning&amp;nbsp;I&amp;nbsp;couldn't&amp;nbsp;believe&amp;nbsp;it.&lt;/p&gt;

&lt;p&gt;Third,&amp;nbsp;I&amp;nbsp;am&amp;nbsp;daily&amp;nbsp;consuming&amp;nbsp;a&amp;nbsp;dietary&amp;nbsp;supplement.&amp;nbsp;As&amp;nbsp;a&amp;nbsp;central-Europeans,&amp;nbsp;we&amp;nbsp;are&amp;nbsp;lacking&amp;nbsp;Omega&amp;nbsp;3&amp;nbsp;acids&amp;nbsp;from&amp;nbsp;seafood,&amp;nbsp;and&amp;nbsp;almost&amp;nbsp;every&amp;nbsp;individual&amp;nbsp;lacks&amp;nbsp;Magnesium.&amp;nbsp;Plus,&amp;nbsp;some&amp;nbsp;complex&amp;nbsp;vitamins,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;feel&amp;nbsp;healthy&amp;nbsp;like&amp;nbsp;never&amp;nbsp;before.&amp;nbsp;But&amp;nbsp;this&amp;nbsp;is&amp;nbsp;a&amp;nbsp;recipe&amp;nbsp;for&amp;nbsp;me,&amp;nbsp;read&amp;nbsp;something&amp;nbsp;about&amp;nbsp;it&amp;nbsp;or&amp;nbsp;talk&amp;nbsp;to&amp;nbsp;your&amp;nbsp;doctor&amp;nbsp;before&amp;nbsp;you&amp;nbsp;take&amp;nbsp;any&amp;nbsp;action.&lt;/p&gt;

&lt;p&gt;Now&amp;nbsp;I&amp;nbsp;feel&amp;nbsp;physically&amp;nbsp;capable&amp;nbsp;of&amp;nbsp;anything,&amp;nbsp;and&amp;nbsp;I&amp;nbsp;even&amp;nbsp;started&amp;nbsp;with&amp;nbsp;a&amp;nbsp;light&amp;nbsp;daily&amp;nbsp;work-out.&amp;nbsp;It&amp;nbsp;has&amp;nbsp;been&amp;nbsp;two&amp;nbsp;months&amp;nbsp;now,&amp;nbsp;and&amp;nbsp;my&amp;nbsp;back&amp;nbsp;hurts&amp;nbsp;are&amp;nbsp;gone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Educate&amp;nbsp;yourself.&amp;nbsp;Take&amp;nbsp;responsibility&amp;nbsp;for&amp;nbsp;your&amp;nbsp;life.&amp;nbsp;Don’t&amp;nbsp;rely&amp;nbsp;on&amp;nbsp;any&amp;nbsp;system&amp;nbsp;or&amp;nbsp;anyone&amp;nbsp;else.&lt;/p&gt;

&lt;p&gt;Study&amp;nbsp;your&amp;nbsp;body&amp;nbsp;more&amp;nbsp;and&amp;nbsp;find&amp;nbsp;your&amp;nbsp;own&amp;nbsp;recipe&amp;nbsp;to&amp;nbsp;improve&amp;nbsp;it.&amp;nbsp;We&amp;nbsp;are&amp;nbsp;all&amp;nbsp;ecosystems&amp;nbsp;as&amp;nbsp;our&amp;nbsp;planet.&amp;nbsp;We&amp;nbsp;want&amp;nbsp;all&amp;nbsp;to&amp;nbsp;take&amp;nbsp;care&amp;nbsp;of&amp;nbsp;the&amp;nbsp;planet&amp;nbsp;more,&amp;nbsp;but&amp;nbsp;how&amp;nbsp;about&amp;nbsp;start&amp;nbsp;with&amp;nbsp;yourself.&amp;nbsp;Once&amp;nbsp;you&amp;nbsp;have&amp;nbsp;no&amp;nbsp;limits,&amp;nbsp;you&amp;nbsp;will&amp;nbsp;help&amp;nbsp;the&amp;nbsp;planet&amp;nbsp;more&amp;nbsp;than&amp;nbsp;the&amp;nbsp;only&amp;nbsp;wave&amp;nbsp;with&amp;nbsp;signs&amp;nbsp;in&amp;nbsp;protesters'&amp;nbsp;crowd.&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;nbsp;Related&amp;nbsp;Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/developers-are-introverts-domain-driven-design-can-help-669510b6930d" rel="noopener noreferrer"&gt;Developers are introverts. Domain-driven design can help.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/i-spent-4-years-working-from-home-now-i-miss-corporate-sprints-c64345e42929" rel="noopener noreferrer"&gt;I Spent 4 Years Working From Home. Now I Miss Corporate Sprints.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/@danielrusnok/four-reason-to-change-your-software-bf535916152d" rel="noopener noreferrer"&gt;Four Reason to Change your Software&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mindset</category>
      <category>productivity</category>
      <category>career</category>
      <category>health</category>
    </item>
    <item>
      <title>No More Mess in my Head Around Phrases Related to Identity in Computing</title>
      <dc:creator>Digital Craft Workshop</dc:creator>
      <pubDate>Thu, 02 Jul 2026 15:04:36 +0000</pubDate>
      <link>https://dev.to/danielrusnok/no-more-mess-in-my-head-around-phrases-related-to-identity-in-computing-3inb</link>
      <guid>https://dev.to/danielrusnok/no-more-mess-in-my-head-around-phrases-related-to-identity-in-computing-3inb</guid>
      <description>&lt;h4&gt;
  
  
  Azure
&lt;/h4&gt;

&lt;h3&gt;
  
  
  No&amp;nbsp;More&amp;nbsp;Mess&amp;nbsp;in&amp;nbsp;my&amp;nbsp;Head&amp;nbsp;Around&amp;nbsp;Phrases&amp;nbsp;Related&amp;nbsp;to&amp;nbsp;Identity&amp;nbsp;in&amp;nbsp;Computing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What&amp;nbsp;is&amp;nbsp;Identity?&amp;nbsp;Azure&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;is&amp;nbsp;just&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;in&amp;nbsp;Azure?&amp;nbsp;Microsoft&amp;nbsp;Graph&amp;nbsp;is&amp;nbsp;a&amp;nbsp;Data&amp;nbsp;Visualization&amp;nbsp;Framework&amp;nbsp;or&amp;nbsp;What?
&lt;/h4&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmsdupp8elr0nu41xq0h.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmsdupp8elr0nu41xq0h.png" alt="No More Mess in my Head Around Phrases Related to Identity in Computing cover image" width="782" height="522"&gt;&lt;/a&gt;&lt;/p&gt;
Credits&amp;nbsp;of&amp;nbsp;logos&amp;nbsp;for&amp;nbsp;[Microsoft](https://microsoft.com).



&lt;h3&gt;
  
  
  Identity
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What&amp;nbsp;is&amp;nbsp;Identity&amp;nbsp;in&amp;nbsp;Cloud
&lt;/h4&gt;

&lt;p&gt;Identity&amp;nbsp;is&amp;nbsp;a&amp;nbsp;unique&amp;nbsp;identification&amp;nbsp;of&amp;nbsp;an&amp;nbsp;object.&amp;nbsp;Such&amp;nbsp;an&amp;nbsp;object&amp;nbsp;can&amp;nbsp;be&amp;nbsp;a&amp;nbsp;human&amp;nbsp;being,&amp;nbsp;machine,&amp;nbsp;or&amp;nbsp;a&amp;nbsp;combination&amp;nbsp;of&amp;nbsp;it.&amp;nbsp;When&amp;nbsp;we&amp;nbsp;talk&amp;nbsp;in&amp;nbsp;the&amp;nbsp;cloud&amp;nbsp;computing&amp;nbsp;context,&amp;nbsp;identity&amp;nbsp;means&amp;nbsp;a&amp;nbsp;set&amp;nbsp;of&amp;nbsp;properties&amp;nbsp;about&amp;nbsp;this&amp;nbsp;object&amp;nbsp;stored&amp;nbsp;in&amp;nbsp;the&amp;nbsp;cloud's&amp;nbsp;datacentre.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Introduction&amp;nbsp;to&amp;nbsp;Cloud&amp;nbsp;Computing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Cloud&amp;nbsp;computing&amp;nbsp;is&amp;nbsp;the&amp;nbsp;present&amp;nbsp;and&amp;nbsp;future&amp;nbsp;of&amp;nbsp;software&amp;nbsp;utilization,&amp;nbsp;development,&amp;nbsp;and&amp;nbsp;hosting.&amp;nbsp;Let&amp;nbsp;me&amp;nbsp;introduce&amp;nbsp;you&amp;nbsp;to&amp;nbsp;its…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;levelup.gitconnected.com&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Identity&amp;nbsp;&amp;amp;&amp;nbsp;Access&amp;nbsp;Management
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Identity&amp;nbsp;Management&lt;/strong&gt;&amp;nbsp;(IdM)&amp;nbsp;and&amp;nbsp;&lt;strong&gt;Identity&amp;nbsp;and&amp;nbsp;Access&amp;nbsp;Management&lt;/strong&gt;&amp;nbsp;(IAM)&amp;nbsp;is&amp;nbsp;an&amp;nbsp;interchangeable&amp;nbsp;term&amp;nbsp;in&amp;nbsp;identity&amp;nbsp;access&amp;nbsp;management.&amp;nbsp;So&amp;nbsp;if&amp;nbsp;you&amp;nbsp;are&amp;nbsp;reading&amp;nbsp;about&amp;nbsp;one,&amp;nbsp;you&amp;nbsp;are&amp;nbsp;probably&amp;nbsp;reading&amp;nbsp;about&amp;nbsp;the&amp;nbsp;second&amp;nbsp;term&amp;nbsp;too.&lt;/p&gt;

&lt;p&gt;IAM&amp;nbsp;is&amp;nbsp;a&amp;nbsp;framework&amp;nbsp;of&amp;nbsp;policies&amp;nbsp;that&amp;nbsp;tell&amp;nbsp;what&amp;nbsp;users&amp;nbsp;can&amp;nbsp;do&amp;nbsp;in&amp;nbsp;their&amp;nbsp;restricted&amp;nbsp;area&amp;nbsp;and&amp;nbsp;what&amp;nbsp;he&amp;nbsp;needs&amp;nbsp;from&amp;nbsp;the&amp;nbsp;user&amp;nbsp;to&amp;nbsp;operate&amp;nbsp;properly.&amp;nbsp;Such&amp;nbsp;systems&amp;nbsp;identify,&amp;nbsp;authenticate,&amp;nbsp;and&amp;nbsp;authorize&amp;nbsp;individuals&amp;nbsp;or&amp;nbsp;hardware&amp;nbsp;applications&amp;nbsp;to&amp;nbsp;use&amp;nbsp;restricted&amp;nbsp;resources.&lt;/p&gt;

&lt;p&gt;IAM&amp;nbsp;exists&amp;nbsp;in&amp;nbsp;the&amp;nbsp;world&amp;nbsp;without&amp;nbsp;the&amp;nbsp;internet&amp;nbsp;too.&amp;nbsp;It&amp;nbsp;appears&amp;nbsp;in&amp;nbsp;different&amp;nbsp;forms.&amp;nbsp;For&amp;nbsp;example,&amp;nbsp;the&amp;nbsp;“Staff&amp;nbsp;Only”&amp;nbsp;label&amp;nbsp;at&amp;nbsp;doors&amp;nbsp;in&amp;nbsp;markets,&amp;nbsp;id&amp;nbsp;card&amp;nbsp;pinned&amp;nbsp;at&amp;nbsp;employees&amp;nbsp;suit,&amp;nbsp;or&amp;nbsp;doorman&amp;nbsp;as&amp;nbsp;a&amp;nbsp;profession&amp;nbsp;by&amp;nbsp;itself.&amp;nbsp;Even&amp;nbsp;your&amp;nbsp;dog&amp;nbsp;protecting&amp;nbsp;yard&amp;nbsp;is&amp;nbsp;some&amp;nbsp;Access&amp;nbsp;Management&amp;nbsp;of&amp;nbsp;your&amp;nbsp;property.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fko6smfs0jaue1uecfzlm.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fko6smfs0jaue1uecfzlm.jpeg" alt="Illustration" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;
Dog&amp;nbsp;protecting&amp;nbsp;an&amp;nbsp;off-limits&amp;nbsp;area.



&lt;p&gt;Every&amp;nbsp;IAM&amp;nbsp;operates&amp;nbsp;in&amp;nbsp;its&amp;nbsp;defined&amp;nbsp;context.&amp;nbsp;The&amp;nbsp;context&amp;nbsp;of&amp;nbsp;IAM&amp;nbsp;specifies&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;properties&amp;nbsp;it&amp;nbsp;needs&amp;nbsp;from&amp;nbsp;the&amp;nbsp;Identity.&amp;nbsp;For&amp;nbsp;example,&amp;nbsp;every&amp;nbsp;patient&amp;nbsp;has&amp;nbsp;a&amp;nbsp;folder&amp;nbsp;with&amp;nbsp;properties&amp;nbsp;about&amp;nbsp;his&amp;nbsp;identity&amp;nbsp;at&amp;nbsp;the&amp;nbsp;doctor's&amp;nbsp;office.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity&amp;nbsp;Platform
&lt;/h3&gt;

&lt;p&gt;Identity&amp;nbsp;Platform&amp;nbsp;is&amp;nbsp;an&amp;nbsp;IAM&amp;nbsp;service&amp;nbsp;provided&amp;nbsp;by&amp;nbsp;third-parties&amp;nbsp;such&amp;nbsp;as&amp;nbsp;Microsoft&amp;nbsp;or&amp;nbsp;Amazon&amp;nbsp;(&lt;a href="https://aws.amazon.com/cognito/" rel="noopener noreferrer"&gt;Amazon&amp;nbsp;Cognito&lt;/a&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  Using&amp;nbsp;External&amp;nbsp;vs.&amp;nbsp;Internal&amp;nbsp;Identity&amp;nbsp;Platform
&lt;/h4&gt;

&lt;p&gt;External&amp;nbsp;identity&amp;nbsp;platform&amp;nbsp;(IP)&amp;nbsp;helps&amp;nbsp;you&amp;nbsp;build&amp;nbsp;applications&amp;nbsp;without&amp;nbsp;its&amp;nbsp;own&amp;nbsp;identity&amp;nbsp;management&amp;nbsp;service&amp;nbsp;such&amp;nbsp;as&amp;nbsp;&lt;a href="https://identityserver.io/" rel="noopener noreferrer"&gt;Identity&amp;nbsp;Server&lt;/a&gt;.&amp;nbsp;Authorization&amp;nbsp;and&amp;nbsp;authentication&amp;nbsp;can&amp;nbsp;be&amp;nbsp;handled&amp;nbsp;externally,&amp;nbsp;and&amp;nbsp;the&amp;nbsp;only&amp;nbsp;thing&amp;nbsp;you&amp;nbsp;need&amp;nbsp;to&amp;nbsp;do&amp;nbsp;is&amp;nbsp;integrate&amp;nbsp;between&amp;nbsp;your&amp;nbsp;system&amp;nbsp;and&amp;nbsp;MIP.&lt;/p&gt;

&lt;p&gt;Integration&amp;nbsp;with&amp;nbsp;an&amp;nbsp;external&amp;nbsp;identity&amp;nbsp;platform&amp;nbsp;does&amp;nbsp;not&amp;nbsp;make&amp;nbsp;sense&amp;nbsp;if&amp;nbsp;you&amp;nbsp;are&amp;nbsp;not&amp;nbsp;using&amp;nbsp;third-party&amp;nbsp;software,&amp;nbsp;and&amp;nbsp;most&amp;nbsp;of&amp;nbsp;your&amp;nbsp;companies&amp;nbsp;applications&amp;nbsp;were&amp;nbsp;built&amp;nbsp;in-house.&amp;nbsp;For&amp;nbsp;example,&amp;nbsp;if&amp;nbsp;the&amp;nbsp;whole&amp;nbsp;company&amp;nbsp;is&amp;nbsp;using&amp;nbsp;Windows&amp;nbsp;and&amp;nbsp;Office&amp;nbsp;365,&amp;nbsp;it&amp;nbsp;does&amp;nbsp;make&amp;nbsp;sense&amp;nbsp;to&amp;nbsp;integrate&amp;nbsp;your&amp;nbsp;system&amp;nbsp;with&amp;nbsp;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform.&lt;/p&gt;

&lt;h4&gt;
  
  
  Microsoft&amp;nbsp;Identity&amp;nbsp;Platform
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;The&amp;nbsp;Microsoft&amp;nbsp;identity&amp;nbsp;platform&amp;nbsp;helps&amp;nbsp;you&amp;nbsp;build&amp;nbsp;applications&amp;nbsp;your&amp;nbsp;users&amp;nbsp;and&amp;nbsp;customers&amp;nbsp;can&amp;nbsp;sign&amp;nbsp;in&amp;nbsp;to&amp;nbsp;using&amp;nbsp;their&amp;nbsp;Microsoft&amp;nbsp;identities&amp;nbsp;or&amp;nbsp;social&amp;nbsp;accounts,&amp;nbsp;and&amp;nbsp;provide&amp;nbsp;authorized&amp;nbsp;access&amp;nbsp;to&amp;nbsp;your&amp;nbsp;own&amp;nbsp;APIs&amp;nbsp;or&amp;nbsp;Microsoft&amp;nbsp;APIs&amp;nbsp;like&amp;nbsp;Microsoft&amp;nbsp;Graph.&amp;nbsp;—&amp;nbsp;docs.microsoft.com&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Components&amp;nbsp;of&amp;nbsp;the&amp;nbsp;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  OAuth&amp;nbsp;2.0&amp;nbsp;and&amp;nbsp;OpenID&amp;nbsp;Connect&amp;nbsp;standard-compliant&amp;nbsp;authentication&amp;nbsp;service.&amp;nbsp;—&amp;nbsp;Possibility&amp;nbsp;of&amp;nbsp;secured&amp;nbsp;work&amp;nbsp;or&amp;nbsp;school&amp;nbsp;accounts&amp;nbsp;authentications.&lt;/li&gt;
&lt;li&gt;  Microsoft&amp;nbsp;Authentication&amp;nbsp;Libraries&amp;nbsp;or&amp;nbsp;MSAL.&amp;nbsp;—&amp;nbsp;Microsoft&amp;nbsp;MVP&amp;nbsp;and&amp;nbsp;my&amp;nbsp;friend&amp;nbsp;&lt;a href="https://twitter.com/DKrzyczkowski" rel="noopener noreferrer"&gt;Daniel&amp;nbsp;Krzyczkowski&lt;/a&gt;&amp;nbsp;have&amp;nbsp;great&amp;nbsp;&lt;a href="https://github.com/Daniel-Krzyczkowski/IdentityDeveloperTemplates" rel="noopener noreferrer"&gt;GitHub&amp;nbsp;repo&lt;/a&gt;&amp;nbsp;with&amp;nbsp;guidelines&amp;nbsp;for&amp;nbsp;using&amp;nbsp;MSAL.&lt;/li&gt;
&lt;li&gt;  Application&amp;nbsp;management&amp;nbsp;portal.&amp;nbsp;—&amp;nbsp;Registration&amp;nbsp;and&amp;nbsp;configuration&amp;nbsp;of&amp;nbsp;applications&amp;nbsp;in&amp;nbsp;the&amp;nbsp;&lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure&amp;nbsp;portal&lt;/a&gt;.&amp;nbsp;Management&amp;nbsp;is&amp;nbsp;also&amp;nbsp;possible&amp;nbsp;through&amp;nbsp;PowerShell&amp;nbsp;or&amp;nbsp;configuration&amp;nbsp;API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Microsoft&amp;nbsp;Graph
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Microsoft&amp;nbsp;Graph&amp;nbsp;is&amp;nbsp;the&amp;nbsp;gateway&amp;nbsp;to&amp;nbsp;data&amp;nbsp;and&amp;nbsp;intelligence.&amp;nbsp;It&amp;nbsp;provides&amp;nbsp;a&amp;nbsp;unified&amp;nbsp;programmability&amp;nbsp;model&amp;nbsp;that&amp;nbsp;you&amp;nbsp;can&amp;nbsp;use&amp;nbsp;to&amp;nbsp;access&amp;nbsp;the&amp;nbsp;tremendous&amp;nbsp;amount&amp;nbsp;of&amp;nbsp;data&amp;nbsp;in&amp;nbsp;Microsoft&amp;nbsp;365,&amp;nbsp;Windows&amp;nbsp;10,&amp;nbsp;and&amp;nbsp;Enterprise&amp;nbsp;Mobility&amp;nbsp;+&amp;nbsp;Security.&amp;nbsp;—&amp;nbsp;docs.microsoft.com&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15h7pwecrekjhb00d752.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15h7pwecrekjhb00d752.png" alt="Illustration" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
Downloaded&amp;nbsp;from&amp;nbsp;[https://docs.microsoft.com/en-us/graph/overview](https://docs.microsoft.com/en-us/graph/overview).&amp;nbsp;Credits&amp;nbsp;for&amp;nbsp;[Microsoft](https://microsoft.com).



&lt;p&gt;Mostly&amp;nbsp;when&amp;nbsp;you&amp;nbsp;are&amp;nbsp;sign-in&amp;nbsp;or&amp;nbsp;up&amp;nbsp;with&amp;nbsp;your&amp;nbsp;Microsoft&amp;nbsp;account&amp;nbsp;and&amp;nbsp;you&amp;nbsp;tracked&amp;nbsp;the&amp;nbsp;communication,&amp;nbsp;you&amp;nbsp;will&amp;nbsp;find&amp;nbsp;out&amp;nbsp;that&amp;nbsp;the&amp;nbsp;browser&amp;nbsp;is&amp;nbsp;talking&amp;nbsp;a&amp;nbsp;lot&amp;nbsp;to&amp;nbsp;&lt;a href="https://graph.microsoft." rel="noopener noreferrer"&gt;https://graph.microsoft.&lt;/a&gt;com,&amp;nbsp;which&amp;nbsp;is&amp;nbsp;a&amp;nbsp;single&amp;nbsp;endpoint&amp;nbsp;of&amp;nbsp;Microsoft&amp;nbsp;Graph&amp;nbsp;API.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note: I also write short, free lessons on getting more out of AI coding tools — if that's your thing, &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; is a tiny email series you can join in one click.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;you&amp;nbsp;are&amp;nbsp;integrating&amp;nbsp;your&amp;nbsp;application&amp;nbsp;with&amp;nbsp;the&amp;nbsp;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform,&amp;nbsp;you&amp;nbsp;will&amp;nbsp;communicate&amp;nbsp;through&amp;nbsp;this&amp;nbsp;API.&amp;nbsp;You&amp;nbsp;can&amp;nbsp;do&amp;nbsp;it&amp;nbsp;directly&amp;nbsp;or&amp;nbsp;with&amp;nbsp;MSAL,&amp;nbsp;which&amp;nbsp;encapsulates&amp;nbsp;the&amp;nbsp;HTTP&amp;nbsp;communication&amp;nbsp;with&amp;nbsp;API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Active&amp;nbsp;Directory&amp;nbsp;vs.&amp;nbsp;Azure&amp;nbsp;Active&amp;nbsp;Directory
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Active&amp;nbsp;Directory
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Active&amp;nbsp;Directory&amp;nbsp;(AD)&amp;nbsp;is&amp;nbsp;a&amp;nbsp;directory&amp;nbsp;service&amp;nbsp;developed&amp;nbsp;by&amp;nbsp;Microsoft&amp;nbsp;for&amp;nbsp;Windows&amp;nbsp;domain&amp;nbsp;networks.&amp;nbsp;—&amp;nbsp;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Physically&amp;nbsp;it&amp;nbsp;is&amp;nbsp;nothing&amp;nbsp;else&amp;nbsp;than&amp;nbsp;an&amp;nbsp;on-premise&amp;nbsp;private&amp;nbsp;server.&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;or&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;Domain&amp;nbsp;Services&amp;nbsp;is&amp;nbsp;a&amp;nbsp;database&amp;nbsp;of&amp;nbsp;your&amp;nbsp;company’s&amp;nbsp;users&amp;nbsp;and&amp;nbsp;computers.&amp;nbsp;It&amp;nbsp;provides&amp;nbsp;authentication&amp;nbsp;and&amp;nbsp;authorizations&amp;nbsp;for&amp;nbsp;applications&amp;nbsp;or&amp;nbsp;users.&amp;nbsp;It&amp;nbsp;uses&amp;nbsp;dinosaur&amp;nbsp;protocols&amp;nbsp;like&amp;nbsp;Kerberos&amp;nbsp;and&amp;nbsp;NTLM.&lt;/p&gt;

&lt;h4&gt;
  
  
  Azure&amp;nbsp;Active&amp;nbsp;Directory
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;(Azure&amp;nbsp;AD)&amp;nbsp;is&amp;nbsp;Microsoft’s&amp;nbsp;cloud-based&amp;nbsp;identity&amp;nbsp;and&amp;nbsp;access&amp;nbsp;management&amp;nbsp;service.&amp;nbsp;—&amp;nbsp;docs.microsoft.com&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fih4o2iko6iivo0ctcxd9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fih4o2iko6iivo0ctcxd9.png" alt="Illustration" width="500" height="504"&gt;&lt;/a&gt;&lt;/p&gt;
Credits&amp;nbsp;of&amp;nbsp;the&amp;nbsp;logo&amp;nbsp;to&amp;nbsp;[Microsoft](https://microsoft.com).



&lt;p&gt;Azure&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;(Azure&amp;nbsp;AD)&amp;nbsp;takes&amp;nbsp;AD&amp;nbsp;approaches,&amp;nbsp;expands&amp;nbsp;them,&amp;nbsp;and&amp;nbsp;brings&amp;nbsp;them&amp;nbsp;to&amp;nbsp;the&amp;nbsp;next&amp;nbsp;level,&amp;nbsp;the&amp;nbsp;cloud&amp;nbsp;level.&amp;nbsp;Azure&amp;nbsp;AD&amp;nbsp;provides&amp;nbsp;organizations&amp;nbsp;with&amp;nbsp;an&amp;nbsp;&lt;a href="https://auth0.com/blog/what-is-idaas/" rel="noopener noreferrer"&gt;Identity&amp;nbsp;as&amp;nbsp;a&amp;nbsp;Service&amp;nbsp;(IDaaS)&lt;/a&gt;&amp;nbsp;solution&amp;nbsp;for&amp;nbsp;applications&amp;nbsp;across&amp;nbsp;Azure&amp;nbsp;and&amp;nbsp;on-premise&amp;nbsp;servers&amp;nbsp;too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;vs.&amp;nbsp;Microsoft&amp;nbsp;Graph
&lt;/h3&gt;

&lt;p&gt;Azure&amp;nbsp;Active&amp;nbsp;Directory&amp;nbsp;is&amp;nbsp;a&amp;nbsp;security&amp;nbsp;token&amp;nbsp;server&amp;nbsp;which&amp;nbsp;analogous&amp;nbsp;to&amp;nbsp;a&amp;nbsp;directory&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Cloud.&amp;nbsp;When&amp;nbsp;organizations&amp;nbsp;want&amp;nbsp;to&amp;nbsp;move&amp;nbsp;their&amp;nbsp;on-premise&amp;nbsp;directories&amp;nbsp;to&amp;nbsp;the&amp;nbsp;cloud&amp;nbsp;and&amp;nbsp;make&amp;nbsp;their&amp;nbsp;applications&amp;nbsp;securely&amp;nbsp;accessible&amp;nbsp;anywhere&amp;nbsp;from&amp;nbsp;the&amp;nbsp;internet,&amp;nbsp;they&amp;nbsp;can&amp;nbsp;take&amp;nbsp;advantage&amp;nbsp;of&amp;nbsp;Azure&amp;nbsp;AD.&lt;/p&gt;

&lt;p&gt;Azure&amp;nbsp;AD&amp;nbsp;has&amp;nbsp;two&amp;nbsp;versions.&amp;nbsp;The&amp;nbsp;V1&amp;nbsp;endpoint&amp;nbsp;and&amp;nbsp;the&amp;nbsp;V2&amp;nbsp;endpoint&amp;nbsp;and&amp;nbsp;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform&amp;nbsp;is&amp;nbsp;made&amp;nbsp;of&amp;nbsp;the&amp;nbsp;V2&amp;nbsp;endpoint,&amp;nbsp;documentation,&amp;nbsp;and&amp;nbsp;application&amp;nbsp;registration&amp;nbsp;tools&amp;nbsp;like&amp;nbsp;App&amp;nbsp;Registrations&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;portal.&amp;nbsp;The&amp;nbsp;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform&amp;nbsp;contains&amp;nbsp;part&amp;nbsp;of&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Active&amp;nbsp;Directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://en.wikipedia.org/wiki/Identity_management" rel="noopener noreferrer"&gt;Identity&amp;nbsp;management&amp;nbsp;by&amp;nbsp;Wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.youtube.com/watch?v=zDEC7A5ZS2Q&amp;amp;ab_channel=MicrosoftAzure" rel="noopener noreferrer"&gt;What’s&amp;nbsp;the&amp;nbsp;role&amp;nbsp;of&amp;nbsp;AAD&amp;nbsp;in&amp;nbsp;the&amp;nbsp;MIP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-overview" rel="noopener noreferrer"&gt;Microsoft&amp;nbsp;Identity&amp;nbsp;Platform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/graph/overview" rel="noopener noreferrer"&gt;Microsoft&amp;nbsp;Graph&amp;nbsp;in&amp;nbsp;Microsoft&amp;nbsp;docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://en.wikipedia.org/wiki/Active_Directory" rel="noopener noreferrer"&gt;Active&amp;nbsp;Directory&amp;nbsp;by&amp;nbsp;Wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.compete366.com/blog-posts/the-difference-between-ad-and-azure-ad-explained/" rel="noopener noreferrer"&gt;The&amp;nbsp;blog&amp;nbsp;post&amp;nbsp;about&amp;nbsp;differences&amp;nbsp;between&amp;nbsp;AD&amp;nbsp;&amp;amp;&amp;nbsp;AAD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-compare-azure-ad-to-ad" rel="noopener noreferrer"&gt;Compare&amp;nbsp;Azure&amp;nbsp;AD&amp;nbsp;with&amp;nbsp;ADDS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More&amp;nbsp;about&amp;nbsp;Azure
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Introduction&amp;nbsp;to&amp;nbsp;Cloud&amp;nbsp;Computing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;Cloud&amp;nbsp;computing&amp;nbsp;is&amp;nbsp;the&amp;nbsp;present&amp;nbsp;and&amp;nbsp;future&amp;nbsp;of&amp;nbsp;software&amp;nbsp;utilization,&amp;nbsp;development,&amp;nbsp;and&amp;nbsp;hosting.&amp;nbsp;Let&amp;nbsp;me&amp;nbsp;introduce&amp;nbsp;you&amp;nbsp;to&amp;nbsp;its…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://levelup.gitconnected.com/introduction-to-cloud-computing-235e530b9fe0" rel="noopener noreferrer"&gt;levelup.gitconnected.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;How&amp;nbsp;to&amp;nbsp;Create&amp;nbsp;a&amp;nbsp;Free&amp;nbsp;Azure&amp;nbsp;Account&amp;nbsp;Step&amp;nbsp;by&amp;nbsp;Step&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;Guide&amp;nbsp;for&amp;nbsp;creating&amp;nbsp;a&amp;nbsp;free&amp;nbsp;Azure&amp;nbsp;account.&amp;nbsp;What&amp;nbsp;services&amp;nbsp;can&amp;nbsp;you&amp;nbsp;use&amp;nbsp;for&amp;nbsp;free?&amp;nbsp;What&amp;nbsp;is&amp;nbsp;Directory&amp;nbsp;or&amp;nbsp;subscription&amp;nbsp;and&amp;nbsp;what…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://levelup.gitconnected.com/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e" rel="noopener noreferrer"&gt;levelup.gitconnected.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;How&amp;nbsp;to&amp;nbsp;Choose&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Region&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;What&amp;nbsp;should&amp;nbsp;you&amp;nbsp;consider&amp;nbsp;before&amp;nbsp;choosing&amp;nbsp;Azure&amp;nbsp;Region?&amp;nbsp;How&amp;nbsp;Microsoft&amp;nbsp;geographically&amp;nbsp;divide&amp;nbsp;datacentres&amp;nbsp;position&amp;nbsp;to…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://danielrusnok.medium.com/how-to-choose-the-azure-region-2a7bfd5ef864" rel="noopener noreferrer"&gt;danielrusnok.medium.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;Understanding&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Groups&amp;nbsp;and&amp;nbsp;Azure&amp;nbsp;Resources&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;Also&amp;nbsp;with&amp;nbsp;Guide&amp;nbsp;How&amp;nbsp;to&amp;nbsp;Create&amp;nbsp;your&amp;nbsp;First&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Group&amp;nbsp;and&amp;nbsp;Add&amp;nbsp;your&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Into&amp;nbsp;it.&lt;/a&gt;&lt;/em&gt;&lt;a href="https://danielrusnok.medium.com/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6" rel="noopener noreferrer"&gt;danielrusnok.medium.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.danielrusnok.com/daniel-rusnoks-newsletter" rel="noopener noreferrer"&gt;Daniel&amp;nbsp;Rusnok’s&amp;nbsp;Newsletter&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.danielrusnok.com/daniel-rusnoks-newsletter" rel="noopener noreferrer"&gt;Every&amp;nbsp;month&amp;nbsp;I&amp;nbsp;will&amp;nbsp;send&amp;nbsp;you&amp;nbsp;an&amp;nbsp;email&amp;nbsp;about&amp;nbsp;a&amp;nbsp;list&amp;nbsp;of&amp;nbsp;my&amp;nbsp;newest&amp;nbsp;articles.&amp;nbsp;It&amp;nbsp;will&amp;nbsp;be,&amp;nbsp;of&amp;nbsp;course,&amp;nbsp;the&amp;nbsp;friendly&amp;nbsp;links…&lt;/a&gt;&lt;/em&gt;&lt;a href="https://www.danielrusnok.com/daniel-rusnoks-newsletter" rel="noopener noreferrer"&gt;www.danielrusnok.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/danielrusnok" rel="noopener noreferrer"&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%2F5tm54rf5555ym89o2ne4.png" alt="Illustration" width="200" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this helped clear things up, you might also like &lt;a href="https://drippery.app/subscribe/6e302973-cf5f-47ff-8803-22122ac3bd9d" rel="noopener noreferrer"&gt;The Claude Code Memory Starter&lt;/a&gt; — a short, free email series, one bite-sized lesson at a time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;nbsp;Related&amp;nbsp;Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/introduction-to-cloud-computing-235e530b9fe0%5D%C2%A0%E2%80%94%C2%A0_Introduction%C2%A0to%C2%A0Cloud%C2%A0Computing_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/introduction-to-cloud-computing-235e530b9fe0]&amp;nbsp;—&amp;nbsp;_Introduction&amp;nbsp;to&amp;nbsp;Cloud&amp;nbsp;Computing_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e%5D%C2%A0%E2%80%94%C2%A0_How%C2%A0to%C2%A0Create%C2%A0a%C2%A0Free%C2%A0Azure%C2%A0Account%C2%A0Step%C2%A0by%C2%A0Step_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/how-to-create-a-free-azure-account-step-by-step-348d4991ae6e]&amp;nbsp;—&amp;nbsp;_How&amp;nbsp;to&amp;nbsp;Create&amp;nbsp;a&amp;nbsp;Free&amp;nbsp;Azure&amp;nbsp;Account&amp;nbsp;Step&amp;nbsp;by&amp;nbsp;Step_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6%5D%C2%A0%E2%80%94%C2%A0_Understanding%C2%A0the%C2%A0Azure%C2%A0Resource%C2%A0Groups%C2%A0and%C2%A0Azure%C2%A0Resources_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/understanding-the-azure-resource-groups-and-azure-resources-d89ce92d25a6]&amp;nbsp;—&amp;nbsp;_Understanding&amp;nbsp;the&amp;nbsp;Azure&amp;nbsp;Resource&amp;nbsp;Groups&amp;nbsp;and&amp;nbsp;Azure&amp;nbsp;Resources_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  [LINK&amp;nbsp;PLACEHOLDER&amp;nbsp;-&amp;nbsp;&lt;a href="https://medium.com/@danielrusnok/how-to-implement-azure-functions-in-any-language-with-custom-handlers-78e627264ccb%5D%C2%A0%E2%80%94%C2%A0_How%C2%A0to%C2%A0Implement%C2%A0Azure%C2%A0Functions%C2%A0in%C2%A0any%C2%A0Language%C2%A0with%C2%A0Custom%C2%A0Handlers_" rel="noopener noreferrer"&gt;https://medium.com/@danielrusnok/how-to-implement-azure-functions-in-any-language-with-custom-handlers-78e627264ccb]&amp;nbsp;—&amp;nbsp;_How&amp;nbsp;to&amp;nbsp;Implement&amp;nbsp;Azure&amp;nbsp;Functions&amp;nbsp;in&amp;nbsp;any&amp;nbsp;Language&amp;nbsp;with&amp;nbsp;Custom&amp;nbsp;Handlers_&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>identity</category>
      <category>dotnet</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
