<?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: siddhesh kabra</title>
    <description>The latest articles on DEV Community by siddhesh kabra (@siddhesh_kabra_690ef37451).</description>
    <link>https://dev.to/siddhesh_kabra_690ef37451</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%2F4159080%2Fb53c28d9-a70b-4644-9eaf-71f740d48da3.png</url>
      <title>DEV Community: siddhesh kabra</title>
      <link>https://dev.to/siddhesh_kabra_690ef37451</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siddhesh_kabra_690ef37451"/>
    <language>en</language>
    <item>
      <title>LangGraph Tutorial: 5 Proven Steps to Fix a Fragile Agent</title>
      <dc:creator>siddhesh kabra</dc:creator>
      <pubDate>Sat, 03 Oct 2026 06:30:38 +0000</pubDate>
      <link>https://dev.to/siddhesh_kabra_690ef37451/langgraph-tutorial-5-proven-steps-to-fix-a-fragile-agent-b6i</link>
      <guid>https://dev.to/siddhesh_kabra_690ef37451/langgraph-tutorial-5-proven-steps-to-fix-a-fragile-agent-b6i</guid>
      <description>&lt;p&gt;LangGraph Tutorial: 5 Proven Steps to Fix a Fragile Agent&lt;/p&gt;

&lt;p&gt;I had an agent that worked in the demo and fell over in production. It was a linear prompt chain, and the moment a tool call failed or a user came back an hour later, it lost the thread. I rewrote it as a LangGraph StateGraph over an afternoon, and this LangGraph tutorial is the result, and the class of bugs that had been eating my week just stopped happening. This LangGraph tutorial walks that rewrite end to end: the mental model, working tool-calling code, memory with a checkpointer, and the failure modes that cost me time so they don't cost you any.&lt;/p&gt;

&lt;p&gt;I am assuming you are comfortable with Python and have touched LangChain once. You do not need prior LangGraph knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What LangGraph is, explained without the hype&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The graph mental model: state, nodes, edges&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 1-5: build a tool-calling agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding memory with a checkpointer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LangGraph vs a plain prompt chain: when it's worth it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LangGraph best practices and setup notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The failure modes that cost me time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAQ&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What LangGraph is, explained without the hype
&lt;/h2&gt;

&lt;p&gt;LangGraph is a low-level orchestration framework for building stateful, long-running agents. Instead of modelling your app as a pipeline (do this, then this, then this), it models it as a directed graph: each step is a node, the connections are edges, and all shared data flows through one central state object. That one design choice is why loops, conditional branching, retries, and multi-step memory stop being things you bolt on and start being things the structure gives you.&lt;/p&gt;

&lt;p&gt;Its GitHub repo passed 30,000 stars and it is among the most active agent frameworks in 2026. You can use it with LangChain or entirely on its own. The reason it matters: a prompt chain has no memory of where it is, so a failed tool call or a resumed conversation breaks it. A graph carries explicit state, so it can loop back, retry a failed step, and then pick up exactly where it stopped.&lt;/p&gt;

&lt;h2&gt;
  
  
  The graph mental model: state, nodes, edges
&lt;/h2&gt;

&lt;p&gt;Four primitives carry the whole model (state, nodes, edges, and the checkpointer you will add for memory):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;State is a typed dictionary that every node reads from and writes to. It is the single source of truth for the run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A node is a function. It takes the state, does something (calls the LLM, runs a tool), and returns an update to the state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An edge connects nodes. A normal edge always goes A to B. A conditional edge picks the next node based on the current state, and that is what gives you branching and loops.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A checkpointer persists the state per thread, which is what turns a one-shot run into a conversation that survives restarts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Primitive&lt;br&gt;
What it is&lt;br&gt;
Example&lt;/p&gt;

&lt;p&gt;State&lt;br&gt;
Typed shared data&lt;br&gt;
messages, iteration count&lt;/p&gt;

&lt;p&gt;Node&lt;br&gt;
A function that acts&lt;br&gt;
&lt;code&gt;reasoning_node&lt;/code&gt;, &lt;code&gt;tool_node&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Normal edge&lt;br&gt;
Always A to B&lt;br&gt;
&lt;code&gt;START -&amp;gt; reasoning&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Conditional edge&lt;br&gt;
Routes on state&lt;br&gt;
reasoning to tools OR output&lt;/p&gt;

&lt;p&gt;Checkpointer&lt;br&gt;
Persists state per thread&lt;br&gt;
SqliteSaver&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1-5: build a tool-calling agent
&lt;/h2&gt;

&lt;p&gt;Below is a complete tool-calling loop, the pattern you will reuse most. It reasons, decides whether to call a tool, runs it, loops back with the result, and exits when the model has an answer.&lt;/p&gt;

&lt;p&gt;Step 1, define the state. A TypedDict with the message list and a safety counter:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph.message&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# add_messages appends, never overwrites
&lt;/span&gt;    &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;add_messages&lt;/code&gt; reducer is the small detail that matters: it appends new messages to the list instead of replacing it, so history accumulates correctly across loops.&lt;/p&gt;

&lt;p&gt;Step 2, write the nodes. Each is a plain function returning a state update:&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;reasoning_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_with_tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iterations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iterations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tool_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# execute whatever tool the last message asked for, append the result
&lt;/span&gt;    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_pending_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3, the router. A conditional edge needs a function that returns the name of the next node:&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;MAX_ITERATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;should_continue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iterations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;MAX_ITERATIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;                      &lt;span class="c1"&gt;# safety valve, never loop forever
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_calls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;                       &lt;span class="c1"&gt;# model wants a tool
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;                          &lt;span class="c1"&gt;# model gave a final answer
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4, wire the graph. This is where nodes and edges become a runnable thing:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reasoning&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reasoning_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reasoning&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reasoning&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;should_continue&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;tools&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;tools&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;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&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;reasoning&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# loop back after a tool runs
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5, compile and run. &lt;code&gt;compile()&lt;/code&gt; turns the builder into an executable graph:&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&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;user&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;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the weather in Pune?&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;iterations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a working agent. The loop &lt;code&gt;reasoning -&amp;gt; tools -&amp;gt; reasoning&lt;/code&gt; runs until &lt;code&gt;should_continue&lt;/code&gt; routes to END, and the iteration cap means a confused model degrades to a normal answer instead of spinning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding memory with a checkpointer
&lt;/h2&gt;

&lt;p&gt;The single upgrade that fixed my production problem: a checkpointer. It persists the full state after every step, keyed by a thread id, so a conversation survives a crash, a restart, or a user returning an hour later.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.checkpoint.sqlite&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SqliteSaver&lt;/span&gt;

&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SqliteSaver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;checkpoints.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# every call for the same thread_id resumes that conversation's state
&lt;/span&gt;&lt;span class="n"&gt;config&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;configurable&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;thread_id&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;user-42&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&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;user&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;and tomorrow?&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;iterations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because state is persisted per thread, "and tomorrow?" works: the graph reloads the prior messages for &lt;code&gt;user-42&lt;/code&gt; and continues. No manual session store, no re-sending the whole history yourself. This is also the foundation for human-in-the-loop approval, where the graph pauses at an &lt;code&gt;approval&lt;/code&gt; node and resumes when you send a decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  LangGraph vs a plain prompt chain: when it's worth it
&lt;/h2&gt;

&lt;p&gt;Honestly, LangGraph is not always the right tool, and reaching for it too early is its own mistake. A quick way to decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use a plain chain when the flow is genuinely linear and stateless: one prompt, one answer, no tools, no memory. The graph is overhead you don't need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use LangGraph the moment you have any of these: a tool-calling loop; branching on what the model decides; retries; or memory that must survive a restart. That is exactly where chains turn fragile.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This LangGraph tutorial's rewrite paid off because my agent had all four. If yours is a single summarisation call, skip the graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  LangGraph best practices and setup notes
&lt;/h2&gt;

&lt;p&gt;LangGraph setup is one install: &lt;code&gt;pip install langgraph langgraph-checkpoint-sqlite&lt;/code&gt;. From there, the practices that saved me the most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always cap your loops. A &lt;code&gt;MAX_ITERATIONS&lt;/code&gt; counter in state is not optional. Without it, a model that keeps requesting tools will run until your API bill notices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep nodes small and single-purpose. One node reasons, one runs tools, one formats output. Fat nodes that do three things are the hardest to debug because you cannot see which step wrote which state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let the state be the only shared data. Do not stash things in globals between nodes. If a later node needs it, put it in the state. This is what makes the checkpointer able to fully restore a run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile once, invoke many. Building the graph is setup; do it at startup, not per request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The failure modes that cost me time
&lt;/h2&gt;

&lt;p&gt;Every hour I lost came from one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Overwriting messages instead of appending. If you return &lt;code&gt;{"messages": [response]}&lt;/code&gt; without the &lt;code&gt;add_messages&lt;/code&gt; reducer on the field, you clobber history. Annotate the field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A conditional edge with no exit. If &lt;code&gt;should_continue&lt;/code&gt; can never return the END branch, you built an infinite loop. The iteration cap is your seatbelt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Forgetting the checkpointer needs a thread_id. No &lt;code&gt;configurable.thread_id&lt;/code&gt; in the config means no memory, silently. The call works; it just never resumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reaching for LangGraph on a linear task. If there is no loop, branch, or memory, the graph is pure ceremony.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is LangGraph in one sentence?&lt;/strong&gt;&lt;br&gt;
A low-level framework for building stateful AI agents as a directed graph of nodes (actions) and edges (transitions) that share one typed state object, which makes loops, branching, and memory natural.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need LangChain to use LangGraph?&lt;/strong&gt;&lt;br&gt;
No. LangGraph works standalone, though the two are often used together because LangChain provides convenient model and tool wrappers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does LangGraph remember conversations?&lt;/strong&gt;&lt;br&gt;
Through a checkpointer (for example &lt;code&gt;SqliteSaver&lt;/code&gt;) that persists the full state after each step, keyed by a &lt;code&gt;thread_id&lt;/code&gt;. Any later call with the same thread id resumes that conversation's state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I NOT use LangGraph?&lt;/strong&gt;&lt;br&gt;
When your workflow is a single, linear, stateless call. If there is no tool loop, no branching, and no memory to preserve, a plain chain is simpler and the graph is just overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt; &lt;a href="https://aidevinsider.com/your-coding-agent-has-a-kill-switch-in-its-permissions-and-mine-was-of/" rel="noopener noreferrer"&gt;Your coding agent has a kill switch in its permissions, and mine was off&lt;/a&gt;, &lt;a href="https://aidevinsider.com/what-an-llm-gateway-actually-does-for-a-coding-agent/" rel="noopener noreferrer"&gt;What an LLM gateway actually does for a coding agent&lt;/a&gt;, &lt;a href="https://aidevinsider.com/claude-code-hooks-config/" rel="noopener noreferrer"&gt;Claude Code Hooks: 7 Fixes for a Painful Setup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt; &lt;a href="https://aidevinsider.com/?p=7544" rel="noopener noreferrer"&gt;PSSA: 7 Proven Reasons This Rust LM Is Painful to Ignore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sources: &lt;a href="https://langchain-ai.github.io/langgraph/" rel="noopener noreferrer"&gt;LangGraph official quickstart and Graph API docs&lt;/a&gt;; &lt;a href="https://realpython.com/langgraph-python" rel="noopener noreferrer"&gt;Real Python: Build Stateful AI Agents with LangGraph&lt;/a&gt;; &lt;a href="https://www.hostinger.com/tutorials/langgraph-tutorial" rel="noopener noreferrer"&gt;Hostinger LangGraph tutorial (approval + streaming patterns)&lt;/a&gt;. Code reflects a tool-calling agent I rebuilt from a prompt chain on my own machine in 2026; the checkpointer fix is from that migration.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aidevinsider.com/langgraph-tutorial/" rel="noopener noreferrer"&gt;aidevinsider.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Figma Dev Mode: 7 Proven Fixes for a Painful Dev Handoff</title>
      <dc:creator>siddhesh kabra</dc:creator>
      <pubDate>Sat, 03 Oct 2026 06:30:06 +0000</pubDate>
      <link>https://dev.to/siddhesh_kabra_690ef37451/figma-dev-mode-7-proven-fixes-for-a-painful-dev-handoff-4hkb</link>
      <guid>https://dev.to/siddhesh_kabra_690ef37451/figma-dev-mode-7-proven-fixes-for-a-painful-dev-handoff-4hkb</guid>
      <description>&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; 2026-10-02&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Siddhesh Kabra&lt;br&gt;
&lt;strong&gt;Category:&lt;/strong&gt; UI/UX &amp;amp; Design&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%2F75jsv4ujbvhqu5w38cw5.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%2F75jsv4ujbvhqu5w38cw5.png" alt="Horizontal bar chart showing minutes saved per day using Figma Dev Mode features, from section statuses at 22 min to MCP server at 6 min" width="800" height="475"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Horizontal bar chart showing minutes saved per day using Figma Dev Mode features, from section statuses at 22 min to MCP server at 6 min&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What is Figma Dev Mode and Why Does It Matter in 2025?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting Into Dev Mode: The 30-Second Setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 1: Inspect Panel — Reading Design Specs Without Asking a Designer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 2: Section Statuses — Never Build the Wrong Version Again&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 3: Diffing — Catch Design Changes Before They Break Your Build&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 4: The VS Code Extension — Inspect While You Code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 5: Code Connect — Map Figma Components to Your Real Codebase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 6: Dev Mode MCP Server — Bring Design Context Into Your AI Workflow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trick 7: Component Playground — Explore Variants Without Editing the File&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real Numbers: What Teams Actually Gain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAQ: Figma Dev Mode Common Questions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is figma dev mode and why does it matter in 2025?
&lt;/h2&gt;

&lt;p&gt;For years, the handoff between design and development ran on screenshots, Zeplin exports, and Slack messages that said “can you send me that blue color code again.” Every developer who has worked with a design team knows the pain: the spec says one thing, the exported asset shows another, and by the time you figure out which margin value was final the designer has updated the file three more times.&lt;/p&gt;

&lt;p&gt;Figma Dev Mode launched in 2023 and became generally available on paid plans in 2024. By 2025 it is the standard way developers consume Figma designs at companies that take design seriously. According to Figma’s own developer survey, 90% of developers who use Dev Mode report improvements in work quality, and the average time saved is 1.5 hours per developer per week. That adds up across a team of 5 developers to over 390 hours per year.&lt;/p&gt;

&lt;p&gt;This guide is based on using figma dev mode daily across 3 production React projects. Every trick here comes from real usage, not from reading a feature changelog. The goal is to get you from “I open Figma occasionally” to “I live in Dev Mode and barely switch back to Design Mode.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who needs a Dev seat?&lt;/strong&gt; Full Dev Mode access requires a Full seat or a Dev seat on any paid Figma plan. A Dev seat costs roughly $25/month in 2025 and gives you the complete inspection and code generation workflow. Viewer accounts can see Design Mode but get limited inspection features — for any serious development work, the Dev seat pays for itself in the first week.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting into Dev Mode: the 30-second setup
&lt;/h2&gt;

&lt;p&gt;Open any Figma Design file. In the toolbar at the top, look for the mode toggle. Click it and switch from Design to Dev. Keyboard shortcut: &lt;code&gt;Shift + D&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is it. You are now in a developer-focused interface with a completely different sidebar layout. The left panel shows you frames grouped by section and status. The right panel becomes the Inspect panel showing real CSS values, spacing measurements, color tokens, and code snippets.&lt;/p&gt;

&lt;p&gt;To exit, press &lt;code&gt;Shift + D&lt;/code&gt; again or click the toggle back to Design Mode.&lt;/p&gt;

&lt;p&gt;One thing I did not realize at first: if someone sends you a Dev Mode link (a link with &lt;code&gt;?mode=dev&lt;/code&gt; in it), Figma drops you directly into Dev Mode on that specific frame. Designers can send these directly so you land on exactly what is ready for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trick 1: Inspect panel — reading design specs without asking a designer
&lt;/h2&gt;

&lt;p&gt;The inspect panel is the core of figma dev mode. Click any layer and the right sidebar shows you everything you need to implement it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Exact pixel dimensions and position&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Padding and margin values as a box model visualization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Color values in hex, RGB, or HSL (switch in settings)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Typography: font family, size, weight, line height, letter spacing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CSS code snippet that you can copy with one click&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;React/Swift/Android code snippets depending on your language setting&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What most developers miss: you can switch the code language. Go to the gear icon in the Inspect panel settings and select your preferred output. If you are building in React, the generated snippets will use JSX syntax. If you are on iOS, you get Swift.&lt;/p&gt;

&lt;p&gt;One practical tip: always click through to the component rather than stopping at the instance. Figma shows you the instance-level overrides separately from the base component properties. If a designer changed the text content but not the styling, you see both — the current override and what the component defaults to.&lt;/p&gt;

&lt;p&gt;From the official Figma documentation: “The inspect panel displays design specs and relevant component information needed to understand a design and transform it into code.” What they do not mention is that clicking Compare with main component shows you exactly what the designer customized for this particular screen — which saves a real conversation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trick 2: Section statuses — never build the wrong version again
&lt;/h2&gt;

&lt;p&gt;This is the trick that changed how I work with design teams most. In Dev Mode, designers can mark sections or individual frames with a “Ready for dev” status. You see a green indicator in the left sidebar next to anything that is ready.&lt;/p&gt;

&lt;p&gt;The result: no more “is this the final version?” Slack messages. If it is not marked Ready, it is not final. If it is marked Ready, you can start building it.&lt;/p&gt;

&lt;p&gt;Here is how to set it up on the designer side (useful if you work with a designer who has not used this yet): in Dev Mode, select a frame or section, then click “Mark as ready for dev” in the toolbar. On Organization and Enterprise plans there is also a “Completed” status that developers can set when they finish implementing — closing the loop without a meeting.&lt;/p&gt;

&lt;p&gt;You also get notifications when a status changes. If you have a Dev or Full seat and you have viewed a file in Dev Mode, Figma will notify you when designs get marked Ready. This is essentially an async ping that says “your queue just updated” without anyone having to find you on Slack.&lt;/p&gt;

&lt;p&gt;I track my implementation queue entirely through section statuses on larger projects. The left sidebar in Dev Mode with “Ready for development” as a filter shows exactly what I need to build next, in priority order.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trick 3: Diffing — catch design changes before they break your build
&lt;/h2&gt;

&lt;p&gt;Diffing is one of the most underused features in figma dev mode. If a designer changes a component after you started building it, the Inspect panel shows “Compare changes” below the layer name. Click that and you get a side-by-side view of the current version versus the previous version.&lt;/p&gt;

&lt;p&gt;This is critical for avoiding the situation where you spend 3 hours implementing a component, then realize halfway through that the design changed 2 days ago and you are working from the wrong spec. With diffing, you know immediately.&lt;/p&gt;

&lt;p&gt;The diff view highlights what actually changed: a border radius went from 4px to 8px, a spacing token changed, the color shifted. You see the exact delta, not just “this is different.” For component instances, there is a separate “Compare with main component” option that shows local overrides versus the base component.&lt;/p&gt;

&lt;p&gt;I check the diff on any component I am about to start implementing if more than a day has passed since I last looked at the frame. It takes 5 seconds and has saved me from at least one full rework on every project where I have used it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trick 4: The VS Code extension — inspect while you code
&lt;/h2&gt;

&lt;p&gt;The Figma for VS Code extension is a full Dev Mode implementation inside your editor. Install it from the VS Code Extensions marketplace (search “Figma”) and connect it with a Personal Access Token from your Figma account settings.&lt;/p&gt;

&lt;p&gt;What you get inside VS Code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The same inspect panel from Dev Mode, showing CSS values and code snippets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time comments and activity from designers (you can respond without leaving VS Code)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigation through frames organized by section and status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code suggestions based on the selected design component&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ability to link code files to specific design components&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The setup takes about 4 minutes: install the extension, generate a token in Figma account settings under Personal Access Tokens (read access to files and dev resources is enough), and paste it when VS Code prompts you.&lt;/p&gt;

&lt;p&gt;The practical workflow: I open VS Code with Figma side-by-side in a split window. I select a component in the Figma sidebar inside VS Code, see the CSS values and code snippet, and write my implementation without switching windows. For me this eliminates around 40 context switches per development session compared to alt-tabbing between apps constantly.&lt;/p&gt;

&lt;p&gt;One quirk: the VS Code extension shows frames grouped by section and status just like Dev Mode, but only shows frames with a parent section or an assigned status. Frames sitting loose on a Figma page without a section are not visible by default. Tell your designers to put everything in named sections.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trick 5: Code Connect — map Figma components to your real codebase
&lt;/h2&gt;

&lt;p&gt;Code Connect is the most powerful feature in figma dev mode for teams with established design systems. It creates a mapping between Figma components and your actual production code components.&lt;/p&gt;

&lt;p&gt;Without Code Connect, when you inspect a button component in Figma, the Inspect panel shows autogenerated CSS. With Code Connect, it shows your actual &lt;code&gt;&amp;lt;Button variant="primary" size="lg"&amp;gt;&lt;/code&gt; component from your real component library, with the exact props mapped to Figma’s variant names.&lt;/p&gt;

&lt;p&gt;The setup uses the Code Connect CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @figma/code-connect
figma connect init

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI walks you through linking your codebase to your Figma file via a Personal Access Token with dev access. You then create mapping files that define which Figma component corresponds to which code component and how Figma’s property names map to your component API props.&lt;/p&gt;

&lt;p&gt;According to Figma’s blog, internal evals and alpha customers using Code Connect with the MCP server saw “more consistent code output, faster file navigation, and improved token efficiency from AI agents.” The human benefit is simpler: you stop copying autogenerated code that does not match your component library. You start copying your actual component usage.&lt;/p&gt;

&lt;p&gt;Code Connect also enhances the MCP server’s capability significantly. When your design system components are linked to code, the MCP server can pass production component references to AI coding agents instead of just visual specs — which means the AI generates code that uses &lt;code&gt;&amp;lt;Button&amp;gt;&lt;/code&gt; from your actual system, not some inferred style approximation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trick 6: Dev Mode MCP server — bring design context into your AI workflow
&lt;/h2&gt;

&lt;p&gt;This is where figma dev mode connects to the current AI coding workflow. The Figma MCP server is a Model Context Protocol implementation that lets AI coding assistants (Cursor, VS Code Copilot, Claude Code, Codex, Windsurf) read design context directly from Figma files.&lt;/p&gt;

&lt;p&gt;Here is the practical workflow without the MCP server: you inspect a Figma component, mentally note the specs, switch to your editor, and either write the component from memory or paste a screenshot into your AI assistant. The AI does its best to estimate measurements it cannot reliably read from an image.&lt;/p&gt;

&lt;p&gt;With the MCP server running, the workflow is: copy a Figma link, paste it into your AI assistant, and prompt it to implement the design. The MCP server tools give the assistant exact measurements, color values, typography specs, spacing, and (with Code Connect) actual component references — without you manually transferring any of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup: Remote Figma MCP Server (recommended)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the simpler path, available on all plans:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In your Figma account, go to Settings, then “Personal access tokens”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a token with “MCP” as the description, scopes: files (read), dev resources (read)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In your MCP client (e.g., Cursor), add the Figma MCP server:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"figma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.figma.com/v1/ai/mcp/sse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"X-Figma-Token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-personal-access-token"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restart your editor. The Figma MCP tools appear in your agent’s tool list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The whitelist reality:&lt;/strong&gt; Figma’s MCP server lists supported clients (VS Code, Cursor, Windsurf, Claude Code, Codex, Gemini CLI, Xcode) on its MCP catalog at figma.com/mcp-catalog. If you use a client not on that list, you are working with community-built alternatives rather than the official server. The Figma community forum has active threads about this approach breaking “the core promise of MCP” — that any client should work with any server. For now, the listed clients cover the most common AI coding workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limits:&lt;/strong&gt; The Figma API allows approximately 6,000 credits per minute with a daily cap of 1,200,000 credits. File access costs 50 credits per request; image rendering costs 200 credits. For a typical development session this is well within free limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trick 7: Component playground — explore variants without editing the file
&lt;/h2&gt;

&lt;p&gt;This is a small feature but a time-saver when you are trying to understand how a component behaves across its variants. In Dev Mode, click a component instance and look for “Component Playground” in the Inspect panel.&lt;/p&gt;

&lt;p&gt;The Component Playground lets you switch between all the variants and states of a component (primary/secondary, size small/medium/large, disabled/active, etc.) and see the exact spec changes for each one. You can try every combination without having a Design seat and without modifying the file.&lt;/p&gt;

&lt;p&gt;This solves a specific problem: understanding what value a prop should be for each visual state without the designer having to explain it or you having to decode 12 similar screens. You cycle through the variants in the Playground and check the inspect panel values for each one. For a button with 3 variants, 3 sizes, and 2 states, you can cover all 18 combinations in under 2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real numbers: what teams actually gain
&lt;/h2&gt;

&lt;p&gt;Here is what the actual data on figma dev mode adoption shows:&lt;/p&gt;

&lt;p&gt;Metric&lt;br&gt;
Value&lt;br&gt;
Source&lt;/p&gt;

&lt;p&gt;Devs reporting work quality improvements&lt;br&gt;
90%&lt;br&gt;
Figma Developer Survey, 2025&lt;/p&gt;

&lt;p&gt;Average hours saved per dev per week&lt;br&gt;
1.5 hours&lt;br&gt;
Figma Developer Survey, 2025&lt;/p&gt;

&lt;p&gt;Annual hours saved on a 5-developer team&lt;br&gt;
390 hours&lt;br&gt;
Calculated from above&lt;/p&gt;

&lt;p&gt;Figma paid plans with Dev Mode access&lt;br&gt;
All paid plans&lt;br&gt;
Figma pricing docs, 2025&lt;/p&gt;

&lt;p&gt;MCP server supported clients&lt;br&gt;
7 official + community&lt;br&gt;
figma.com/mcp-catalog, 2025&lt;/p&gt;

&lt;p&gt;Code Connect frameworks supported&lt;br&gt;
React, Vue, Angular, iOS, Android&lt;br&gt;
Figma Code Connect docs, 2025&lt;/p&gt;

&lt;p&gt;The 1.5 hours/week comes primarily from eliminating back-and-forth. Instead of 3-4 “what is this value” messages per day, you look it up yourself in 10 seconds via the Inspect panel. Over a 5-day week, that adds up quickly.&lt;/p&gt;

&lt;p&gt;The work quality improvement number reflects fewer implementation errors. When developers can inspect exact specs and see actual component code via Code Connect, the gap between what was designed and what got built shrinks. Fewer rounds of design QA. Fewer “this is not quite right” review comments.&lt;/p&gt;

&lt;p&gt;From a cost standpoint: if a developer’s time is worth $60/hour, 1.5 saved hours/week is $90/week per developer. A Dev seat costs around $25/month. The ROI is obvious.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: figma dev mode common questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is figma dev mode free?&lt;/strong&gt;&lt;br&gt;
Dev Mode requires a paid Figma plan and a Full or Dev seat. Dev seats are cheaper than Full seats and designed specifically for developers who need inspection and code access without design editing rights. Free accounts get limited inspection in Viewer mode but not the full Dev Mode experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between Dev Mode and Design Mode?&lt;/strong&gt;&lt;br&gt;
Design Mode is for creating and editing designs. Dev Mode is read-only for the design but adds developer-specific features: the Inspect panel with CSS/code snippets, section statuses for tracking handoff state, the diffing tool for catching design changes, and access to Dev Mode plugins like Storybook and GitHub integrations. Developers should almost always be in Dev Mode, not Design Mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the Figma VS Code extension require Dev Mode?&lt;/strong&gt;&lt;br&gt;
Yes, the Figma for VS Code extension uses the same inspection APIs that power Dev Mode. You need a Dev or Full seat to get code snippets and full inspection data through the extension.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the figma dev mode MCP server?&lt;/strong&gt;&lt;br&gt;
The Figma MCP server is an implementation of Anthropic’s Model Context Protocol that lets AI coding assistants (Cursor, VS Code Copilot, Claude Code, Codex, and others) access design context from Figma files. It lets you paste a Figma link into your AI assistant and have it extract exact specs, component properties, and (with Code Connect) production component references automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need Code Connect to use Dev Mode?&lt;/strong&gt;&lt;br&gt;
No. Dev Mode works without Code Connect and still provides autogenerated CSS/code snippets. Code Connect is an enhancement that replaces autogenerated snippets with your actual production component usage, which is particularly valuable for teams with established design systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a developer suggest design changes in Dev Mode?&lt;/strong&gt;&lt;br&gt;
Dev Mode is read-only for design elements — you cannot move or resize things on the canvas. You can leave comments (using the comment tool in the toolbar) which designers can see and respond to. This keeps the feedback loop in one place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the Figma Dev Mode MCP server available on Starter plans?&lt;/strong&gt;&lt;br&gt;
The remote MCP server is available on all seats and all paid plans. The desktop MCP server (runs locally via the Figma desktop app) requires a Dev or Full seat on any paid plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The single change that matters most: get a Dev seat and use the Inspect panel instead of asking designers for values. Everything else above builds on that habit.&lt;/p&gt;

&lt;p&gt;After that, add section statuses to your team workflow so you always know what is ready to build. Set up the VS Code extension to eliminate context switching. If your team has a component library, invest a few hours in Code Connect — it pays back in the first sprint.&lt;/p&gt;

&lt;p&gt;The MCP server is the newest piece and genuinely changes AI-assisted development. Pasting a Figma link into Cursor and getting a component implementation that actually uses your design system’s spacing tokens and component API is a qualitatively different experience than describing a design to an AI in words.&lt;/p&gt;

&lt;p&gt;Figma Dev Mode turned the handoff from a process that ran on hope and Slack threads into something that can be tracked, inspected, and automated. The 90% quality improvement and 1.5 hours saved per week are real numbers from real teams. At the pace Figma is integrating AI tooling into Dev Mode — the MCP server, Code Connect in-app mapping, bidirectional canvas capture — the gap between what was designed and what gets built is shrinking toward zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt; &lt;a href="https://aidevinsider.com/cloud-cost-optimization/" rel="noopener noreferrer"&gt;Cloud cost optimization: 7 proven fixes for a painful AWS bill&lt;/a&gt;, &lt;a href="https://aidevinsider.com/?p=7512" rel="noopener noreferrer"&gt;System Design Interview: 7 Proven Fixes for a Painful Round&lt;/a&gt;, &lt;a href="https://aidevinsider.com/cursor-vs-claude-code/" rel="noopener noreferrer"&gt;Cursor vs Claude Code: 7 Proven Tests Reveal Painful Gaps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt;&lt;br&gt;
– &lt;a href="https://help.figma.com/hc/en-us/articles/15023124644247-Guide-to-Dev-Mode" rel="noopener noreferrer"&gt;Figma Dev Mode official documentation&lt;/a&gt; — Figma Help Center&lt;br&gt;
– &lt;a href="https://help.figma.com/hc/en-us/articles/32132100833559-Guide-to-the-Figma-MCP-server" rel="noopener noreferrer"&gt;Figma MCP Server guide&lt;/a&gt; — Figma Help Center&lt;br&gt;
– &lt;a href="https://www.figma.com/dev-mode" rel="noopener noreferrer"&gt;Figma Developer stats (90% quality improvement, 1.5hrs/week saved)&lt;/a&gt; — Figma Dev Mode landing page&lt;br&gt;
– &lt;a href="https://help.figma.com/hc/en-us/articles/23920389749655-Code-Connect" rel="noopener noreferrer"&gt;Code Connect documentation&lt;/a&gt; — Figma Help Center&lt;br&gt;
– &lt;a href="https://www.figma.com/blog/design-context-everywhere-you-build" rel="noopener noreferrer"&gt;Design Context Everywhere You Build&lt;/a&gt; — Figma Blog&lt;br&gt;
– &lt;a href="https://help.figma.com/hc/en-us/articles/15023121296151-Figma-for-VS-Code" rel="noopener noreferrer"&gt;Figma for VS Code extension documentation&lt;/a&gt; — Figma Help Center&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%2Faidevinsider.com%2Fwp-content%2Fuploads" 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%2Faidevinsider.com%2Fwp-content%2Fuploads" alt="Bar chart showing Figma Dev Mode ROI: weekly hours saved by team size, from 1.5h solo to 30h for 20-person teams" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figma Dev Mode ROI by team size. A 5-developer team saves 390 hours per year at 1.5h/dev/week (Figma Developer Survey 2025).&lt;/em&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%2Faidevinsider.com%2Fwp-content%2Fuploads" 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%2Faidevinsider.com%2Fwp-content%2Fuploads" alt="Heatmap matrix showing Figma Code Connect framework support for React, Vue, Angular, Svelte, iOS, Android, Flutter and HTML/CSS" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Code Connect framework support matrix. React, Vue, and Angular have full support across all five capability columns as of October 2026.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aidevinsider.com/figma-dev-mode/" rel="noopener noreferrer"&gt;aidevinsider.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uxdesign</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
