<?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: Michael Mangialardi</title>
    <description>The latest articles on DEV Community by Michael Mangialardi (@michaelmangial1).</description>
    <link>https://dev.to/michaelmangial1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F311068%2F7b0d6bcb-b712-4885-b97a-c524bba21bc9.jpeg</url>
      <title>DEV Community: Michael Mangialardi</title>
      <link>https://dev.to/michaelmangial1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michaelmangial1"/>
    <language>en</language>
    <item>
      <title>Treating AI Chats Like Git Branches</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Fri, 07 Feb 2025 16:32:39 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/treating-ai-chats-like-git-branches-1nco</link>
      <guid>https://dev.to/michaelmangial1/treating-ai-chats-like-git-branches-1nco</guid>
      <description>&lt;p&gt;As a developer, I'm used to solving problems by composing many functions to handle one step in the solution. Solving problems via an AI chat introduces a new experience: dialoguing through a problem and its solution.&lt;/p&gt;

&lt;p&gt;This open-ended experience of interacting with an AI chat requires the imposition of verbal "tools" to mimic structured functions, libraries, etc.&lt;/p&gt;

&lt;p&gt;In this article, I'd like to show how I've imposed prompts to harness and organize my knowledge management mediated through AI chats, especially Claude.&lt;/p&gt;

&lt;p&gt;Before I imposed any prompt structure, my AI chats would go like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduce a subject/problem/question&lt;/li&gt;
&lt;li&gt;Make connections with other subjects/problems/questions&lt;/li&gt;
&lt;li&gt;Get into the weeds of the connection between the original topic and the new one and miss the big picture (the structure and interconnection of the conversation)&lt;/li&gt;
&lt;li&gt;Leave the chat session feeling stimulated with new ideas/thoughts/impressions but not being able to return and retrieve the knowledge quickly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what I did. In short, I used prompts to treat every AI chat session like a git branch.&lt;/p&gt;

&lt;p&gt;Every chat session has some subject/problem/question/theme. In other words, every session can be given a name corresponding to the holistic intent of the session. In git terms, every session is a "branch" that can be given a specific name to provide a baseline.&lt;/p&gt;

&lt;p&gt;As with every git branch, a chat session delves into specific steps/dimensions of the initial problem.&lt;/p&gt;

&lt;p&gt;The power of good commits is that they leave breadcrumbs demonstrating the logical unfolding--in short, the history—of a solution to the problem. More generically, we can say that commits trace the developer's mind as a theme is explored. Good commits are helpful not only for reviewing a branch in retrospect, but the discipline of creating them helps build awareness of the developer's approach/design.&lt;/p&gt;

&lt;p&gt;Likewise, AI chat sessions could benefit from retrospectively examining the conversation's logical evolution. Moreover, creating session "commits" facilitates the discipline of awareness and organization of thoughts in a discussion.&lt;/p&gt;

&lt;p&gt;When a git branch is completed, the code may be reviewed. Comments may be added to provide another layer of context/insight. Similarly, additional context/insight can be extracted within an AI chat session regarding a) the "commits" and b) the overall "branch."&lt;/p&gt;

&lt;p&gt;While there isn't an industry-standard tool/interface like there is with git, a user can impose prompts to structure the workflow of an AI chat session to mimic that of a git branch.&lt;/p&gt;

&lt;p&gt;There are many ways to do this, but let me showcase the prompt system I imposed on Claude.&lt;/p&gt;

&lt;p&gt;Every time I enter an AI chat session, I name the chat, mimicking a branch's name and capturing the session's high-level goal/theme.&lt;/p&gt;

&lt;p&gt;Then, I note the intent to work on a "commit" within the branch before diving into a new connection using this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Create a branch point marker. We're moving from [original topic] to [new domain].

Key context to preserve: [please generate]”

Example Output:
=== BRANCH POINT: [New Domain] ===
&lt;span class="p"&gt;-&lt;/span&gt; [ ] - Original topic: 
&lt;span class="p"&gt;-&lt;/span&gt; [ ] - Connection point:
&lt;span class="p"&gt;-&lt;/span&gt; [ ] - New exploration:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a "commit message" that transitions from one commit to another—in other words, from one logical exploration of thought to another. I use the term "branch marker" instead of "commit" to better fit my mental model (since I have more control of this than git's interface/terminology).&lt;/p&gt;

&lt;p&gt;That way, I can create a logical history of my progression through a chat.&lt;/p&gt;

&lt;p&gt;Note: This begs the question of when to distinguish between a connection or tangential point within a logical group of thought (a "commit"/branch marker) and a new logical group. This depends on your preferences, intuition, and the nature of the theme/session. The significant point is to leave some organized trace of the different "chunks" of thought in an AI chat session.&lt;/p&gt;

&lt;p&gt;Just as you would with git, you can check the "commit"/branch marker history in your AI session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Can you (in text) list all our branch markers, including the next one?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which may produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;// output
Chat: Philosophical Realism
Branch 1: Plato's Realism
Branch 2: Aristotle's Moderate Realism
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moreover, just as you can use git hooks to do extraordinary things after a commit, I use each branch marker/"commit" to do things like aggregate notes from that chunk of thought:&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="nx"&gt;One&lt;/span&gt; &lt;span class="nx"&gt;more&lt;/span&gt; &lt;span class="nx"&gt;thing&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;move&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;summaries&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;those&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="nx"&gt;points&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;would&lt;/span&gt; &lt;span class="nx"&gt;make&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;formal&lt;/span&gt; &lt;span class="nx"&gt;notecards&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt; &lt;span class="nx"&gt;Zettlekasten&lt;/span&gt; &lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once I've wrapped up a session, I do something equivalent to a &lt;code&gt;git push&lt;/code&gt; hook to do end-of-session cool things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;"Please aggregate all zettelkasten cards from this chat in two formats:

A readable summary organized by branches, showing:

Branch name/theme
Each note's ID, title, and content

And notes in this format. Example Output:&lt;span class="sb"&gt;


&lt;/span&gt;const notes = [
    // Branch 1: Clarifying Aquinas
    {
      id: '202501261',
      title: 'AQ-ConscienceScope',
      content: &lt;span class="sb"&gt;`Natural law encompasses both moral principles discoverable by reason (synderesis) and broader principles of human flourishing. Aquinas distinguishes this from moral law, which specifically concerns divine commands and moral obligations. Natural law is thus broader, including practical and civic virtues alongside moral virtues.`&lt;/span&gt;,
      tags: 'aquinas,natural-law,moral-law,virtue,conscience'
    },
]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;"Please create a complete branch index from all branch points and suggest an appropriate chat name."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, at the end of each session, I have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An outline/index of each "commit"/branch marker&lt;/li&gt;
&lt;li&gt;Summaries on main notes/thoughts in each branch marker&lt;/li&gt;
&lt;li&gt;A final chat name (if I need to change it)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My final step is to update the branch/session name to be prefixed with (Complete) so that if I return to that chat session, I can expect to find an index and summary notes at the bottom to get right back into the swing of things.&lt;/p&gt;

&lt;p&gt;To simplify this process, I use Mac keyboard shortcuts so that my standardized prompts can feel like entering commands into a terminal, as with git.&lt;/p&gt;

&lt;p&gt;You can create your aliases/interface to invoke the prompts using keyboard shortcuts, giving you the potential to either copy the git interface verbatim or improve upon it.&lt;/p&gt;

&lt;p&gt;In conclusion, version control and git concepts have applications beyond code. AI chat sessions are a perfect example where imposing these concepts can streamline a process for better extracting knowledge from interactions with AI.&lt;/p&gt;

&lt;p&gt;If you have a similar workflow, let me know in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Does this engineering culture suck? (How to find out before you take the job)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Fri, 15 Jul 2022 18:41:12 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/does-this-engineering-culture-suck-how-to-find-out-before-you-take-the-job-2k5d</link>
      <guid>https://dev.to/michaelmangial1/does-this-engineering-culture-suck-how-to-find-out-before-you-take-the-job-2k5d</guid>
      <description>&lt;h2&gt;
  
  
  Interview the Company
&lt;/h2&gt;

&lt;p&gt;If I were to go on LinkedIn and search "UI developer," I would find a plethora of jobs with almost identical job descriptions.&lt;/p&gt;

&lt;p&gt;However, each job could have a very, very different engineering maturity in its culture that could make or break your experience there.&lt;/p&gt;

&lt;p&gt;So, how do you avoid entering into a bad engineering culture?&lt;/p&gt;

&lt;p&gt;You have to ask questions to draw this out upfront.&lt;/p&gt;

&lt;p&gt;Don't let the 5+ rounds of interviews with technical challenges fool you. You are interviewing the company as much as they are interviewing you.&lt;/p&gt;

&lt;p&gt;Before you take a job, make sure to ask good questions that give you a sense of the engineering culture. It can be a bit illusive to know what to ask, so I'll give you some pointers:&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions to Ask
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What is the acceptance criteria for a branch to get merged into main?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; No mention of making sure the code reaches a quality threshold based on determined standards/practices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is technical debt and how does this team address it?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; Very abstract conversation, nothing actual process to point to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can you tell me the difference between tactical and strategical development? Where does this team lie on the spectrum?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; Unable to understand the question.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why are professional goals important to work towards in addition to releasing features? How does the manager take this responsibility upon themself?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; Very abstract conversation, nothing actual process to point to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are the roles and responsibilities of engineering leads and engineering managers? How do the two roles differ?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; The roles don't differ, and one person is doing both.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can you show me an outline of an example 1-on-1?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; Very abstract, nothing concrete to point at.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do you distinguish between the different levels of engineering maturity between teammates when assigning work?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; There is no distinction between levels of maturity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does this team aim at maintaining good talent amidst their developers?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; They haven't really thought about it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can I explore some of the codebase?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; They won't let you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Who determines the product roadmap and what pushback do the developers have to negotiate time for technical improvements/vision?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; An abstract answer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If I want to be the best possible engineer I can, why would I join this company?&lt;br&gt;
&lt;strong&gt;🚩Red flag:&lt;/strong&gt; They won't let you.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many more questions could be thought of, but hopefully this gets you thinking on the right track.&lt;/p&gt;

&lt;p&gt;If you want to get your brain juices flowing even more, &lt;a href="https://amzn.to/3Rybaex"&gt;I highly recommend reading this book on software philosophy&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>agile</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Looking Out For Tactical Tornadoes (Why Product People Should Also Care About Quality)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Thu, 14 Jul 2022 18:55:30 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/looking-out-for-tactical-tornadoes-why-product-people-should-also-care-about-quality-27ea</link>
      <guid>https://dev.to/michaelmangial1/looking-out-for-tactical-tornadoes-why-product-people-should-also-care-about-quality-27ea</guid>
      <description>&lt;p&gt;A mature engineering organization possesses a &lt;a href="https://amzn.to/3PcIdTQ"&gt;software philosophy&lt;/a&gt; where saying no is commendable.&lt;/p&gt;

&lt;p&gt;If there is a deadline or some sort of higher-up-pressure to deliver software within a tight scope, a mature engineering culture encourages to say no to such pressure if it compromises code quality.&lt;/p&gt;

&lt;p&gt;If I were to go on LinkedIn and apply for a variety of jobs that came up when I searched "React developer," I would guess that most of the job descriptions would appear almost identical. However, each role could significantly vary based upon the engineering culture.&lt;/p&gt;

&lt;p&gt;Truth be told, some engineering cultures are heaving "tactical." The main virtue is being able to deliver features as quickly as possible.&lt;/p&gt;

&lt;p&gt;Developers that deliver very fast are enshrined by management as heroes, but the other developers think otherwise.&lt;/p&gt;

&lt;p&gt;In a word, a tactically-minded engineering culture says yes to too much, takes shortcuts, and fails to think of long-term implications in a pursuit for short-term efficiency.&lt;/p&gt;

&lt;p&gt;The code is becoming complex and needs refactoring, and a tactical approach says: "We can do a patch and get this delivered. We can always refactor later." Patch after patch the code spirals out of control, adding a level of complexity that slows down efficiency for the long-haul and produces a codebase that mature engineers (the one's you actually want on your team) don't want to contribute to.&lt;/p&gt;

&lt;p&gt;This, in a nutshell, is a "tactical tornado."&lt;/p&gt;

&lt;p&gt;What does this mean?&lt;/p&gt;

&lt;p&gt;Engineers must think about the long-term consequences of their code on the developer experience.&lt;/p&gt;

&lt;p&gt;There's a common camping maxim of "leave no trace."&lt;/p&gt;

&lt;p&gt;Is it a big deal to leave a banana peel on the campsite? It's just a banana peel!&lt;/p&gt;

&lt;p&gt;Well, yes--it is a big deal. The reason being that if one person sees that it's ok to leave a banana peel, then everyone thinks it's ok to leave behind a few scraps. Before you know it, everyone is leaving scraps and the campsite is a mess.&lt;/p&gt;

&lt;p&gt;This maxim equally applies to software development&lt;/p&gt;

&lt;p&gt;As with life, engineers should consider their legacy. Do they want to leave behind a messy, complex codebase for the gain of delivering faster for the short-term?&lt;/p&gt;

&lt;p&gt;No. Developers should think beyond just writing code that works and instead writing code that follows good designs.&lt;/p&gt;

&lt;p&gt;Good designs are not complex. They do not create unneeded dependencies and obscurity.&lt;/p&gt;

&lt;p&gt;The code is easy to follow and easy to contribute to.&lt;/p&gt;

&lt;p&gt;Good designs improve efficiency because they the code is easier to contribute to, and it prevents more mature engineers from jumping ship.&lt;/p&gt;

&lt;p&gt;However, in the short term, good designs require deliberation--extra work, extra time.&lt;/p&gt;

&lt;p&gt;This means that a quick patch is a big deal and should be said "no" to.&lt;/p&gt;

&lt;p&gt;On the side of product management, mature yet efficient (thinking both in terms of short and long-term) developers should be encouraged and celebrated--not those who get work done the quickest.&lt;/p&gt;

&lt;p&gt;Product people should understand the implications of bad software designs and how those do affect the bottom line in the long haul. To not understand this, and to not take an interest in code quality, is to manage poorly. If you ignore this aspect of management, then you'll have tornadoes on your hands.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Keeping the "Up-Factor" (And, Keeping Your Senior Engineers as a Result)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Wed, 13 Jul 2022 20:48:55 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/keeping-the-up-factor-and-keeping-your-senior-engineers-as-a-result-dlp</link>
      <guid>https://dev.to/michaelmangial1/keeping-the-up-factor-and-keeping-your-senior-engineers-as-a-result-dlp</guid>
      <description>&lt;p&gt;The Roman statesman Cicero once said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a general truth, as it seems to me, it is weariness of all pursuits that creates weariness of life.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we find an ancient observation of burnout.&lt;/p&gt;

&lt;p&gt;To put it another way, when there is a sense of "nothing up from here," people become weary.&lt;/p&gt;

&lt;p&gt;In the realm of software engineering, this phenomena is not uncommon.&lt;/p&gt;

&lt;p&gt;It is well known that impostor syndrome can cause weariness due to a lack of assurance of being able to fulfill the responsibilities of a role. However, this sort of weariness protects from another sort of weariness--the "nothing up from here" weariness.&lt;/p&gt;

&lt;p&gt;Impostor syndrome implies that there is an up-from-here. Namely, there is an active pursuit in becoming more confident in one's skills and fulfilling the responsibilities of a role.&lt;/p&gt;

&lt;p&gt;Burnout can happen when impostor syndrome is accomplished and engineers mature.&lt;/p&gt;

&lt;p&gt;They may have mastered their ability to be a sound contributor--they can do their job flawlessly. Then, there comes the creeping thought of "now what."&lt;/p&gt;

&lt;p&gt;This creeping thought may be prevented when the following circumstances are sturdy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The business is doing well and morale is good.&lt;/li&gt;
&lt;li&gt;The product team one is working on has a strong mission-mindset and great chemistry.&lt;/li&gt;
&lt;li&gt;Compensation is good.&lt;/li&gt;
&lt;li&gt;There are open-ended challenges that require rigorous technical collaboration.&lt;/li&gt;
&lt;li&gt;There are ways to master one's craft in step with product development.&lt;/li&gt;
&lt;li&gt;One is in a very specialized role that affords a lot of freedom and creativity (e.g. a design system developer).&lt;/li&gt;
&lt;li&gt;There is focus.&lt;/li&gt;
&lt;li&gt;There is clear visibility into what is being worked on and why--and who made the decision and what for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually, when teams breakdown and weariness ensues, it is due to more senior engineers burning out. They burnout when those pleasant circumstances previously described begin to evaporate. It has a cascading effect that can seriously harm the bottom line--whether higher-ups admit it or not.&lt;/p&gt;

&lt;p&gt;You see, all the circumstances described above are"up-factors."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The business is doing well --&amp;gt; I'm contributing to something that's successful.&lt;/li&gt;
&lt;li&gt;The product team has great chemistry --&amp;gt; The product team is presenting a strong vision of what we are working on, and the engineers are collaborating well to implement that vision. We're on a mission.&lt;/li&gt;
&lt;li&gt;Compensation is good --&amp;gt; I have a bonus to look forward to.&lt;/li&gt;
&lt;li&gt;There are open-ended challenges that require rigorous technical collaboration --&amp;gt; I'm learning a lot about the product and big-picture technical decision-making. I'm excited for the next product.&lt;/li&gt;
&lt;li&gt;There are ways to master one's craft --&amp;gt; I'm able to try new technologies and design patterns in the codebase. I'm excited to share the next one I'm working on.&lt;/li&gt;
&lt;li&gt;One is in a very specialized role that affords a lot of freedom and creativity --&amp;gt; I get to build out a design system. This is a really fun project. I can't wait for it to be implemented across our various products.&lt;/li&gt;
&lt;li&gt;There is focus --&amp;gt; I know what I'm working on and can easily find a way to resolve the situation if I don't. I can come into work ready to get things done.&lt;/li&gt;
&lt;li&gt;There is clear visibility into what is being worked on and why --&amp;gt; my team is on a mission, and I see how this ties in with the broader company's mission. I can't wait to see what we accomplish.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many more examples may be given, but all of these provide up-factors. They fuse together personal accomplishment and a team mission.&lt;/p&gt;

&lt;p&gt;From the vantage point of a junior engineer, these "up-factors" (or, the lack thereof) are important but not as impactful when compared to senior engineers. The reason being is that junior developers don't have as much to compare to, and they are motivated by being able to do what they're asked--they are less cognizant of the &lt;em&gt;why&lt;/em&gt; things are being done and how to do them very well.&lt;/p&gt;

&lt;p&gt;Case in point, junior engineers usually need direction to move beyond meeting the bare requirements of a story/ticket. They need to not just get their code to work, but for it to meet a good level of quality. This requires refactoring code and a large amount of intentionality. In addition to code quality, there is a such thing as an organization quality. Senior engineers becomes more cognizant of organization quality and its importance than junior engineers.&lt;/p&gt;

&lt;p&gt;Organizational quality goes down when the up-factors evaporate.&lt;/p&gt;

&lt;p&gt;From the position of a senior engineer, it can be quite illusive to sense when things are evaporating. It is not as if all circumstances are pulled out from underneath. Rather, there is a sort of death by a thousand paper-cuts--death by the slow removal of "up-factors."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The business is doing well --&amp;gt; We had a bad quarter. We have to hit all our marks in the next one.&lt;/li&gt;
&lt;li&gt;The product team has great chemistry --&amp;gt; The product manager now owns multiple teams and their appearance is more infrequent (and hence, the collaboration and visibility that developers previously has implicitly been removed).&lt;/li&gt;
&lt;li&gt;Compensation is good --&amp;gt; No bonus this year.&lt;/li&gt;
&lt;li&gt;There are open-ended challenges that require rigorous technical collaboration --&amp;gt; The product team starts to make decisions without developer input, providing tightly-defined sets of work for them--the team starts to work like contractors.&lt;/li&gt;
&lt;li&gt;There are ways to master one's craft --&amp;gt; There is not enough "bandwidth."&lt;/li&gt;
&lt;li&gt;There is focus --&amp;gt; The developers become cross-functional across multiple projects because some far away higher-ups said so.&lt;/li&gt;
&lt;li&gt;There is clear visibility into what is being worked on and why --&amp;gt; The team is split in too many directions. It's hard to keep track.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The removal of these up-factors will certainly weary senior engineers.&lt;/p&gt;

&lt;p&gt;So, what does this mean? It is imperative for software engineering management to factor in the intangibles, to present up-factors and maintain them as if it does impact the bottom line (which it does)--to not hyper-analyze efficiency (by which only short-term efficiency is assumed).&lt;/p&gt;

&lt;p&gt;Where do you see a need for up-factors?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/rethinkingagile"&gt;By the way, I wrote a book on trying to rethink Agile and present up-factors if you're interested&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>management</category>
      <category>webdev</category>
      <category>programming</category>
      <category>agile</category>
    </item>
    <item>
      <title>Roles and Responsibilities Within a Software Engineering Team</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Wed, 13 Jul 2022 14:39:30 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/roles-and-responsibilities-within-a-software-engineering-team-2agm</link>
      <guid>https://dev.to/michaelmangial1/roles-and-responsibilities-within-a-software-engineering-team-2agm</guid>
      <description>&lt;p&gt;The way to organize of developer efforts and clarify the what, who, how, and why can be achieved by first clarifying roles and responsibilities with the developer process.&lt;/p&gt;

&lt;p&gt;Generally, software teams have the following leadership roles: product manager, technical product manager, design lead, engineering manager, and engineering lead. We are not forced into this model, but it provides a helpful barometer.&lt;/p&gt;

&lt;p&gt;How do these typical roles fit in your team's organization?&lt;/p&gt;

&lt;h2&gt;
  
  
  Product Manager
&lt;/h2&gt;

&lt;p&gt;To understand how each typical role fits in our organization, we first need to clarify the responsibilities of each role.&lt;/p&gt;

&lt;p&gt;Roles can best be understood as to how they are conduits. In other words, we must understand how a role is a channel between a "higher" initiative and goal--since no one on the level of software development team is a part of the "higher-ups."&lt;/p&gt;

&lt;p&gt;A product manager serves as the channel between company initiatives and a team's roadmap of projects.&lt;/p&gt;

&lt;p&gt;The product manager is responsible for explaining what the company initiatives are, how they relate to the formation of projects in a roadmap, and how the completion of said projects will contribute the mission of the business.&lt;/p&gt;

&lt;p&gt;Also, the product manager serves as the channel between customer needs and a the roadmap of projects.&lt;/p&gt;

&lt;p&gt;The product manager is responsible for explainging what the customer needs are, how they relate the formation of projects, how the completion of said projects solves their needs, and how a customer needs and business needs are both fused into a common solution via a project.&lt;/p&gt;

&lt;p&gt;In a word, the product manager is the one to define &lt;strong&gt;what&lt;/strong&gt; is worked on, explaining the &lt;strong&gt;why&lt;/strong&gt; from the vantage point of the business and customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Product Manager
&lt;/h2&gt;

&lt;p&gt;Technical product managers are the channel between the product manager and the developers.&lt;/p&gt;

&lt;p&gt;The technical product manager is responsible for translating projects determined by the product manager into requirements and size-able projects that can be delivered to developers.&lt;/p&gt;

&lt;p&gt;Once a project is delivered, the technical product manager is responsible for ensuring that the developers are staying on track to complete a project.&lt;/p&gt;

&lt;p&gt;In this sense, the technical product manager is the channel between the product manager and the engineering manager, as both have an interest in meeting the deadlines.&lt;/p&gt;

&lt;p&gt;The technical product manager is also responsible for reenforcing &lt;strong&gt;what&lt;/strong&gt; is being worked on and &lt;strong&gt;why&lt;/strong&gt; it is being worked on from the vantage point of the customers and business. This reenforcement is important since the technical product manager is usually in more of a fixed orbit with the developers than the product managers who tend to have more communications with higher-ups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Lead
&lt;/h2&gt;

&lt;p&gt;The design lead is the channel to translate a conceptual project of the product manager into a viable prototype.&lt;/p&gt;

&lt;p&gt;The design lead is responsible for showing &lt;strong&gt;how&lt;/strong&gt; a project will look and feel for the users, postulating &lt;strong&gt;why&lt;/strong&gt; the prototype is the best expression of the product manager's vision--and hence, the the best expression of a solution for a business and customer need.&lt;/p&gt;

&lt;p&gt;Design leads, like product managers, are a step ahead the developers as they formulate a project for project roadmap while the developers are busy implementing a previously formalized project.&lt;/p&gt;

&lt;p&gt;While design leads are a step ahead of the developers, they still should orbit around the current work of the developers, frequently explaining the prototype/requirements--amending them as needed.&lt;/p&gt;

&lt;p&gt;It is also important to note that prototypes evolve as a product is constantly undergoing additions (and sometimes subtractions). Therefore, the design lead is responsible for making clear which prototype maps to which phase of a product's evolution. Since developers are a step behind, the prototypes for the current developers' project should not be modified without announcement and a conscious acceptance of the ramifications of a project's scope.&lt;/p&gt;

&lt;p&gt;Moreover, the design lead is the channel between a broader design initiative (i.e. a design system) and the developers, ensuring that the prototypes are in sync with the design patterns and principles of the other products--which then ensures a uniform experience for all customers no matter the product in the product suite.&lt;/p&gt;

&lt;p&gt;Finally, the design lead is usually the point of contact for receiving feedback from developers and translating those ideas into a prototype.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering Manager
&lt;/h2&gt;

&lt;p&gt;The engineering manager is responsible for allocating developer resources to accomplish projects distributed by the technical product manager.&lt;/p&gt;

&lt;p&gt;Therefore, the engineering manager is a channel between the developers and the technical product manager.&lt;/p&gt;

&lt;p&gt;The engineering manager advocates for project deadlines. It would be unwise for the product manager to set a deadline on the engineers that is incongruent with the deadline of the engineering manager. While the engineering manager is responsible for understanding the product initiatives, and must communicate with the product manager and technical product manager to do this, the engineering manager's deadline should able to trump the deadline of product managers if it is deemed too ambitious--since engineering managers understand both what needs to be accomplished and how it may be accomplished. Product managers do not have as much visibility into the &lt;em&gt;how&lt;/em&gt; part.&lt;/p&gt;

&lt;p&gt;The engineering manager is then also a channel between the engineering lead--who is primarily responsible for determine &lt;em&gt;how&lt;/em&gt; a project will be accomplished in code (more on this below)--and the product managers.&lt;/p&gt;

&lt;p&gt;The engineering manager should help keep the team on track to accomplish projects to meet a given deadline and ensure the team is properly implementing the project in light of product requirements.&lt;/p&gt;

&lt;p&gt;This constitutes the responsibilities of the engineering manager so far as the product side is concerned. However, the engineer also is a channel between the developers and engineering higher-ups. Therefore, there are additional responsibilities to satisfy higher technical initiatives.&lt;/p&gt;

&lt;p&gt;The engineering manager is a channel between developers and technical initiatives. Meaning, broader technical ideals for code standards, architecture, deployment, career growth, etc. should be implemented by the communication and counsel of the manager.&lt;/p&gt;

&lt;p&gt;While this type of channel is shared with the engineering lead, the engineering manager serves this capacity in more of a "eyes on, hands off" manner.&lt;/p&gt;

&lt;p&gt;When it comes to career development, a peculiar broader technical initiative. The engineering manager is responsible for helping developers build their craft amidst pursuits for tangible career goals.&lt;/p&gt;

&lt;p&gt;More broadly, engineering managers help to motivate developers by allocating work that is peculiar to their skills and interests, developing their short-term and long-term growth, helping to connect work with the big picture, and navigating through difficult seasons in a company.&lt;/p&gt;

&lt;p&gt;Finally, the engineering manager is responsible to coordinate technical work that is contingent upon other teams and communicate as needed down to the developers.&lt;/p&gt;

&lt;p&gt;With all of this in mind, it can be seen how the role is a unique blend of technical and relational skills. It is the latter which clearly distinguished from engineering leads.&lt;/p&gt;

&lt;p&gt;Due to the scope of responsibilities, it can also be understood why engineering managers often do not contribute to any writing of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering Lead
&lt;/h2&gt;

&lt;p&gt;The engineering lead is a distinct role from an engineering manager. A manager is more focused on keeping the team on track for delivering on product initiatives and cultivating a strong engineering culture marked by personal development. A lead, on the other hand, is primarily focused on keeping the team on track by planning technical decisions that coincide with product initiatives and developer experience.&lt;/p&gt;

&lt;p&gt;An engineering manager may lean upon the engineering lead to help with keeping a team on track by delegating project breakdowns, etc. The manager may also have helpful feedback for big-picture technical conversations. Yet, the roles and responsibilities and distinct.&lt;/p&gt;

&lt;p&gt;In a word, the engineering lead is responsible for &lt;strong&gt;how&lt;/strong&gt; projects are accomplished (architecture, technical constraints, etc.) while managers are responsible for ensuring that the projects are accomplished and mapping out &lt;strong&gt;how&lt;/strong&gt; the developers will be cultivated.&lt;/p&gt;

&lt;p&gt;Engineering leads are distinct from other developers not only in their leadership qualities but in that they focus on more &lt;em&gt;specialized&lt;/em&gt; work. They may work on the day-to-day stories around releasing features to customers, but they are responsible for technical work that enabled efficient releasing of features (tactical work)--such as: establishing code standards and principles, and patterns; maintaining shared libraries; informing architectural decisions; working with other leads to solve large technical projects; etc.&lt;/p&gt;

&lt;p&gt;All of this in mind, the lead is a channel between engineering manager and developers.&lt;/p&gt;

&lt;p&gt;They are also a channel between other engineering leads and the developers/manager.&lt;/p&gt;

&lt;p&gt;Finally, they are a sort of channel between technical product managers and developers, being the primary liaison for questions about the code/projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining a Team
&lt;/h2&gt;

&lt;p&gt;It is important to call out that it is impossible to enumerate roles without also thinking about how those roles serve a common purpose within the contexts of teams.&lt;/p&gt;

&lt;p&gt;Speaking very generally, there are two types of teams in mature software engineering organization: stream and enabling teams.&lt;/p&gt;

&lt;p&gt;Stream teams are focused on a "stream" of work. A stream is usually a product, but it could also be a set of experiences within a product, or a set of services that enable those experiences when applications grow larger.&lt;/p&gt;

&lt;p&gt;Stream teams require all necessary components in order to legitimately constitute a team. Those necessary components are: Application (UI + mocks, or UI and presentational API) developers, API (presentational APIs and/or microservices) developers, and (sometimes) DB developers.&lt;/p&gt;

&lt;p&gt;Usually, a product manager and technical product manager own a particular stream. If streams are smaller and scoped to a single product, then perhaps product resources could manage multiple streams. However, owning multiple streams across multiple products can be quite difficult, so it is not recommended. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>agile</category>
      <category>management</category>
    </item>
    <item>
      <title>Apply Agile to the Family</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Thu, 30 Jun 2022 03:52:10 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/apply-agile-to-the-family-449d</link>
      <guid>https://dev.to/michaelmangial1/apply-agile-to-the-family-449d</guid>
      <description>&lt;p&gt;Although I have &lt;a href="https://leanpub.com/rethinkingagile"&gt;recently criticized some aspects of Agile&lt;/a&gt;, it does some things very well.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It creates a sense of mission across a variety of roles within a team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It provides frequent opportunities to evaluate work in progress and pivot as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It emphasizes small wins that can add up to a larger purpose.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To put it another way, we can break the Agile methodology into several components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There is a team with multiple roles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The team works together towards a mission within their distinct, yet sometimes overlapping goals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The team has tasks on its mission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The team tracks its tasks and evaluates periodically as tasks are being done.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The principles of Agile may be applied across any organization that also has a team with a mission comprised of a multitude of tasks and roles within that mission.&lt;/p&gt;

&lt;p&gt;The family is such an organization.&lt;/p&gt;

&lt;p&gt;We don't always think of it in this way, but the family is a mini government, a mini organization, a mini team.&lt;/p&gt;

&lt;p&gt;Families do well to have a concrete mission. They should have aims as to what they should produce and how they may contribute to larger society for good--and how they can accomplish such things in a way that builds every member up.&lt;/p&gt;

&lt;p&gt;Members of a family have distinct skills, experience, strengths, interests, callings, roles, and responsibilities. Yet, they are contributing to a shared mission.&lt;/p&gt;

&lt;p&gt;Putting it all together, a family is a team with many roles found within it. A family may have a mission and small wins (tasks) to accomplish that mission, delegating work across the variety of members.&lt;/p&gt;

&lt;p&gt;Therefore, why can't an Agile methodology be applied to a family?&lt;/p&gt;

&lt;p&gt;Here's what it could look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write out your family mission&lt;/li&gt;
&lt;li&gt;Aggregate current tasks and projects that are a part of that mission&lt;/li&gt;
&lt;li&gt;Make these tasks and projects deliverables that are small but important wins &lt;/li&gt;
&lt;li&gt;Distribute the work across the team&lt;/li&gt;
&lt;li&gt;Take time to check in on progress, see how things are going, discuss any difficulties, pivot as needed, and reflect to commend each other for what has gone well, yet still working on areas of improvement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my family, which right now is only comprised of my wife and our not-even-one-year-old, we have formed a long term mission.&lt;/p&gt;

&lt;p&gt;While the long term mission is something we always think about and prepare for in the background, we pursue it until it changes.&lt;/p&gt;

&lt;p&gt;Each year, we set aside goals for what we would like to accomplish, to be intentional about.&lt;/p&gt;

&lt;p&gt;Every month, we set aside some projects that can help us towards some of our goals.&lt;/p&gt;

&lt;p&gt;Every week, we jot down some projects we can work on as well as the everyday life type of work.&lt;/p&gt;

&lt;p&gt;At the start of each week, we review how the past week went, discuss our plans for the new week, and record an action items, making those action items tasks for the week.&lt;/p&gt;

&lt;p&gt;Rinse and repeat.&lt;/p&gt;

&lt;p&gt;Have you tried applying Agile to your family?&lt;/p&gt;

</description>
      <category>agile</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Clean Code is About Reducing Complexity (Not Improving Readability)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Tue, 28 Jun 2022 17:50:31 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/clean-code-is-about-reducing-complexity-not-improving-readability-4do3</link>
      <guid>https://dev.to/michaelmangial1/clean-code-is-about-reducing-complexity-not-improving-readability-4do3</guid>
      <description>&lt;p&gt;When it comes to clean code, there is often an assumption that clean code means readable code.&lt;/p&gt;

&lt;p&gt;In other words, the aim of clean code is usually assumed to be making the code as readable as possible.&lt;/p&gt;

&lt;p&gt;More readable code is almost always cleaner code. However, it is not at the heart of clean code.&lt;/p&gt;

&lt;p&gt;The aim of clean code is to produce &lt;em&gt;simpler&lt;/em&gt; code. Code should be reduced to the lowest level of complexity possible while still providing an adequate solution.&lt;/p&gt;

&lt;p&gt;So, how can we reduce complexity in software?&lt;/p&gt;

&lt;p&gt;The short answer is removing as much cognitive load as possible.&lt;/p&gt;

&lt;p&gt;To put it another way, the less thinking that has to be done to make a change the better.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating a "Candidates" Pattern in Your Codebase</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Mon, 27 Jun 2022 19:54:46 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/creating-a-candidates-pattern-in-your-codebase-2k3e</link>
      <guid>https://dev.to/michaelmangial1/creating-a-candidates-pattern-in-your-codebase-2k3e</guid>
      <description>&lt;p&gt;It is good practice to extract sharable code into libraries.&lt;/p&gt;

&lt;p&gt;We all get this on some level. For example, UI teams often consume a central design system to reuse UI components that encapsulate a design system's style and behavior specifications.&lt;/p&gt;

&lt;p&gt;However, there are three ways we often miss out on extracting sharable code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;By narrowing our sense of sharable code to a very specific thing (e.g. a design system)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By failing to separate generic code from application-specific code (e.g. creating a single &lt;code&gt;GroceriesDropdown&lt;/code&gt; component instead of separating a generic &lt;code&gt;Dropdown&lt;/code&gt; component from a &lt;code&gt;GroceriesDropdown&lt;/code&gt; that merely wraps a generic component and plugs in any business logic--like sourcing a list of groceries)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By failing to stage library "candidates" (e.g. staging a design system candidate in a consuming application)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, I'll talk about the third way of missing out.&lt;/p&gt;

&lt;p&gt;Whenever a library of shareable code exists, there is always the potential of creating too large a chasm between the shared library and the consuming applications.&lt;/p&gt;

&lt;p&gt;For example, a central design system codebase may be closed off from contribution by the developers working on one of the applications that consumes it.&lt;/p&gt;

&lt;p&gt;Regardless of whether the centralized, shared library allows direct contribution from the consuming applications (e.g. creating a PR on the GitHub repo), I'd argue that all consumers of the shared library should contribute.&lt;/p&gt;

&lt;p&gt;So, what does contribution look like if the consuming applications do not contribute directly?&lt;/p&gt;

&lt;p&gt;Maybe it's jumping on a video call with the maintainers of the shared library and saying, "Hey! I made this function/component that could fit really nicely into the shared library. Here's how we're using it: [insert GitHub link to consuming application's codebase]."&lt;/p&gt;

&lt;p&gt;In other words, the consuming application can stage "candidates" for the shared library. The consuming application can call out useful functions/components/patterns that &lt;em&gt;could&lt;/em&gt; be extracted into a shared library, making these candidates easily discoverable and shareable.&lt;/p&gt;

&lt;p&gt;For example, let's say there is a central design system at a company, and there is an application that consumes it.&lt;/p&gt;

&lt;p&gt;The design system doesn't have a &lt;code&gt;Action&lt;/code&gt; component, a clickable icon that animates into a background color when hovered. However, the consuming application is implementing this pattern over and over.&lt;/p&gt;

&lt;p&gt;Without a candidate pattern, this &lt;code&gt;Action&lt;/code&gt; component could get nested within the consuming application and located in a manner that does not make it discoverable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* pages/groceries/index.js */&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Action&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;There exists in the consuming application a generic component that could be shared by any application, and hence, could be extracted into the central design system.&lt;/p&gt;

&lt;p&gt;However, if no one on the team has an awareness that they can contribute to the design system (even if indirectly), then the shareable component will never get discovered--there won't be a pattern instilling an intentionality to contribute to the design system.&lt;/p&gt;

&lt;p&gt;However, with a candidates pattern, we can instill an intentionality to contribute to the design system by having a pattern for stashing code that could be extracted into a central library.&lt;/p&gt;

&lt;p&gt;So, how can one implement a candidates pattern? It's quite simple. Segregate a folder in the consuming application that is detected to stashing shared code that could be extracted.&lt;/p&gt;

&lt;p&gt;For example, you could stash the design system candidates into a &lt;code&gt;components/design/lab&lt;/code&gt; folder in the consuming application(s).&lt;/p&gt;

&lt;p&gt;Then, when an opportunity arises, you can easily share the component within that folder with the maintainers of the design system.&lt;/p&gt;

&lt;p&gt;Finally, as a cherry on top, you can do two more things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alias the dedicated "candidate" folder to match the external package with &lt;code&gt;/lab&lt;/code&gt; appended:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;components/design/lab --&amp;gt; @mycompany/design/lab&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;By creating an alias, you can treat the candidate folder as a shared package, making it easy to change the import if it does get extracted.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write documentation to explain the candidate pattern and enforce it in code reviews.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>16 Unsurprising &amp; Surprising Tips on Developer Self-Care</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Fri, 17 Jun 2022 13:48:56 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/16-unsurprising-surprising-tips-on-developer-self-care-3n55</link>
      <guid>https://dev.to/michaelmangial1/16-unsurprising-surprising-tips-on-developer-self-care-3n55</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Learn how to pace yourself to deliver high output without wearing your mind thin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take advantage of unlimited PTO if you have it. Studies have shown that when individuals who take periodic breaks from weightlifting performed the same as those who took no break. I don't think our minds are too different from our muscles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you doing the developer work that you are gifted for? Coding teams require tactical work (e.g. building features for a product) and strategic work (e.g. designing architecture). Usually, you'll receive a mental boost when you align your work closer to your gifts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you have a friend who does something similar to you but is not a coworker? Give them a call, or even better, get coffee with them. It is refreshing to talk about your work with someone who gets it but also is out of your work orbit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you following developer trends, newsletters, blogs, etc.? It may seem counterintuitive but building your craft for the sake of your craft (not a product) can be restful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you vocalizing any concerns or question with your teammates and managers? &lt;a href="https://larahogan.me/blog/be-directive-without-being-a-jerk/"&gt;You can be directive without being a jerk&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you stretching your technical skillsets beyond your day-to-day? Maybe you should read a book on &lt;a href="https://amzn.to/3xoFiiZ"&gt;clean code&lt;/a&gt;, &lt;a href="https://amzn.to/3OgXtOq"&gt;software philosophy&lt;/a&gt;, or &lt;a href="https://amzn.to/3QEguMW"&gt;staff engineering&lt;/a&gt;. It can be refreshing to think of problems that aren't in your peripherals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code something that is fun for the sake of being fun, not making a profit. This one is especially hard for the visionary in me, but again, seeing out a little bit outside of your peripherals through learning or action is helpful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read something tangentially related to the engineer side of your brain that fuels a separate interest. For me, this would be something like a &lt;a href="https://amzn.to/3xymu0L"&gt;book on baseball analytics&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How are you stewarding your income? Yes, that includes making wise financial decisions--but, it also means spending your money in light of a greater vision. Write out a vision for how you may use the fruit of your labor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you have a vision for your career as a developer? If not, the grind of work takes on an excessive load. It is only natural and right to have something to which we are progressing towards, and coding is no exception. If you are unsure, talk with a manager or a mentor. If you have neither, seek your advice online.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work with your hands. It is a maxim that those who work with their hands rest best with their minds, and those who work with their minds rest best with their hands. The point isn't to pick one over the other but to healthfully incorporate both into your life. Perhaps this could look like &lt;a href="https://amzn.to/3zKqDkZ"&gt;backyard beekeeping&lt;/a&gt;, &lt;a href="https://amzn.to/3b9sbL1"&gt;square foot gardening&lt;/a&gt;, or &lt;a href="https://www.youtube.com/watch?v=J_mMS3EkHok"&gt;rice farming&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intentionally avoid some automation. I could automate cutting my grass. I could get one of those new robot mowers, or I could pay a teenager in my neighborhood to automate the mowing process. But, the truth is that mowing is very relaxing to me, and so, I don't automate it. It's hard for engineers sometimes to think this way, but calculated acceptance of manual processes has its merit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Study the past. As developers, we can be caught in the hustle and bustle of the latest technologies, trends, and happenings. It is only fitting that a pause from this will be restful. Pick up a book that takes you to the past. Last year, I took a break by reading &lt;a href="https://amzn.to/3O0vlQ4"&gt;&lt;em&gt;Up From Slavery&lt;/em&gt; by Booker T. Washington&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shake up your routine. I recently listened to a book called &lt;a href="https://dev.toHow%20to%20Create%20Connections%20and%20Make%20Lasting%20Memories%20with%20Your%20Kids"&gt;&lt;em&gt;Adventuring Together: How to Create Connections and Make Lasting Memories with Your Kids&lt;/em&gt;&lt;/a&gt;. I found it interesting how the other makes a case for spontaneity, and yet, also talks of the importance of family traditions. So, which is it? Routine is the foundation, and spontaneity with intention can be energizing. It is good to have a consistent work routine, but you can also be helpful to intentionally have aspects of your week where you shake things up. Working from home, I have some days where I mow or water the garden for a work break, work from a hammock, and/or work from a coffee shop to sprinkle some change to the week.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is a maxim that thankfulness lightens the heart. Well, are you recording your thanks for the aspects of your work?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>How to Start a Design System Without a Company-Led Initiative (A Use Case for Non-Enterprise Businesses)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Wed, 26 Jan 2022 16:22:27 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/how-to-start-a-design-system-without-a-company-led-initiative-a-use-case-for-non-enterprise-businesses-5fo1</link>
      <guid>https://dev.to/michaelmangial1/how-to-start-a-design-system-without-a-company-led-initiative-a-use-case-for-non-enterprise-businesses-5fo1</guid>
      <description>&lt;h2&gt;
  
  
  It's harder to start when there's not a company-led initiative
&lt;/h2&gt;

&lt;p&gt;While it does not take much to see the benefits of a design system, and there's plenty of material out there on the &lt;a href="https://leanpub.com/designsystemsfordevelopers"&gt;best way to build a design system&lt;/a&gt;, it is a bit harder to know how to start when there's not a company-led initiative.&lt;/p&gt;

&lt;p&gt;Non-enterprise companies may be more likely to not be familiar with designs systems and their importance, and many times, the need for them is unintentionally discovered in the thick of business needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Use Case
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2qdmo0isd6q58mr72iq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2qdmo0isd6q58mr72iq.png" alt="How to Start a Design System Without a Company-Led Initiative (A Use Case for Non-Enterprise Businesses)" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A company has found their niche in the _____ industry. As the company has grown, they acquire other startups that are a good fit, extend their product offering, and in turn, take the company to the next level.&lt;/p&gt;

&lt;p&gt;Suddenly, there are variety of applications for products living under one company. These applications have originated independently from one another.&lt;/p&gt;

&lt;p&gt;As a result, all the applications have very different experiences that they present to the user, even if the due diligence has been done to update the logo and some of the colors.&lt;/p&gt;

&lt;p&gt;With time, the business realizes that organizing the applications to reflect one brand and communicate a common feel/experience to users will do much to drive the business forward.&lt;/p&gt;

&lt;p&gt;Finally, an initiative for a design system comes. However, all the various teams implemented some small version of a design system (whether in an external codebase or in their existing one).&lt;/p&gt;

&lt;p&gt;The company is basically asking for a design system (whether they realize it or not) and someone needs to step up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this practical use case sounds familiar (or plausible), then what do you do?&lt;/p&gt;

&lt;p&gt;Well, first we need to consider how things would have shaken out in an ideal scenario. &lt;/p&gt;

&lt;h2&gt;
  
  
  The ideal start
&lt;/h2&gt;

&lt;p&gt;We've discussed a less-than-ideal example. But, how would a design system be started in an ideal scenario?&lt;/p&gt;

&lt;p&gt;Ideally, a design system would be initiated proactively and not reactively. Meaning, a design system would be created upfront because of it's ability to set a foundation to craft common experiences, even if the company should grow. This is in contrast to starting a design system when its discovered that the customers are (basically) asking for one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5r47pdju49prh3au2cz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5r47pdju49prh3au2cz2.png" alt="How to Start a Design System Without a Company-Led Initiative (A Use Case for Non-Enterprise Businesses)" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an ideal start, the company would dedicate full-time resources (whether internally or externally acquired) to build out a design system.&lt;/p&gt;

&lt;p&gt;And hopefully, those resources would include at least one designer and one developer, both recognizing that design systems have to be prototyped by designers and distributed by developers with a huge amount of conversation overlapping the handoffs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcfy6t6p17n0gop7g4xq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcfy6t6p17n0gop7g4xq.png" alt="How to Start a Design System Without a Company-Led Initiative (A Use Case for Non-Enterprise Businesses)" width="800" height="533"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When a design system is created proactively, there are still some dangers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The design system team fails to showcase their work and invite visibility/input from other stakeholders (the designers and developers that will be consuming the design system).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; On the developer side, the design system assets do not meet the technical needs of all the applications and/or the assets force a technical transition that others don't want to make.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The design system team releases documentation before it releases assets that can be consumed in code, leading to micro-design systems being created independently of one another.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Putting it all together, here's what we would ideally have when starting a design system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Support from the company as they recognize the business value of the design system (and not just geeking out of designers and developers).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dedicated resources working on the design system, including designers, developers, and a healthy amount of collaboration between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Communication about the design system to stakeholders, making the work visible through online documentation, well-documented source code, and announce and feedback sessions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A streamlined process for releasing versions of the design system, including both documentation and consumable assets for both designers and developers (i.e. a Figma library, CSS file, shared components, etc.). &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Making the best of the less-than-ideal situation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cafr5fiorutjj5wayer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cafr5fiorutjj5wayer.png" alt="How to Start a Design System Without a Company-Led Initiative (A Use Case for Non-Enterprise Businesses)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, so that's the ideal situation, but what about when you are in the less-than-ideal situation?&lt;/p&gt;

&lt;p&gt;Meaning, you are in the situation where you see the need for a design system, but there is no company-led initiative.&lt;/p&gt;

&lt;p&gt;Usually in such a case, bandwidth and deadlines are tight but the need for a design system is wide.&lt;/p&gt;

&lt;p&gt;What do you do?&lt;/p&gt;

&lt;p&gt;Well, you have three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You put together a strong case, including the business impacts of a design system. Then, you pitch it to whoever can make it happen (whether directly or by promoting your case).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You create an initiative within the designers and developers, creating a proof of the concept and then doing the first option collectively.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this option, you would start by putting together a strong case for a design system, but you focus more on the impact on the designers and developers. You pitch the idea to a group of designers and developers, and then see what happens.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You wait it out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Truth be told, you need a bit of each of these options.&lt;/p&gt;

&lt;p&gt;Everyone needs to familiarize themselves with the practical and technical implication from the perspectives of the business, the designers, and the developers. Everyone needs to know why a design system is valuable. Plus, you'll need to be patient throughout the process.&lt;/p&gt;

&lt;p&gt;While each option has an element of truth to it, you'll need to discern what approach is best in your specific scenario.&lt;/p&gt;

&lt;p&gt;Regardless, here are a few things you could do to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you're a designer, start organizing a design system in your design tools and drive product-specific prototypes from the unofficial design system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you're a developer, create a &lt;a href="https://twitter.com/michaelmangial1/status/1486017909612810246"&gt;POC of a design tokens pipeline&lt;/a&gt;. If there's no designer with an unofficial design system, then reverse engineer one and organize it in code using &lt;a href="https://dev.to/michaelmangial1/introduction-to-design-tokens-6f2"&gt;design tokens&lt;/a&gt;. Surely, there are some commonly used colors, typography, etc. that you could organize. &lt;strong&gt;There is always a design system, it's just a matter of whether or not it is formalized/organized.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After a POC has been created, begin to share your progress with designers and developers you work with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prepare your pitch. Write out how you could communicate the value of a design system, and how you could speak to the specific points of interest depending upon whether you're speaking with a designer, developer, and business person.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lay out some ideas of how a design team could be formalized. What resources would be needed? How would those resources work together? How would the team invite visibility?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a roadmap of what needs to be done to get to a stable state with a design system and its consumable assets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be patient and wait for an opportunity. Discern who to speak to and when.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When working for a company that is not aware of the value of a design system (a not uncommon case for non-enterprise companies), take initiative to lay a foundation and gain momentum.&lt;/p&gt;

&lt;p&gt;Although the business may be reactionary, you do not have to be. That is no knock on non-technical workers, but with your creative, technical mind, understand that you may see things before others do. And when that's the case, taking initiative is better than wallowing in disappoint.&lt;/p&gt;

&lt;p&gt;Don't become discouraged. Although in some ways the less-than-ideal scenario is (...well...) less-than-ideal, it can eventually bear sweeter rewards. There is always pros-and-cons, and do your best to see the pros.&lt;/p&gt;

&lt;p&gt;What can you do to help start a design system? &lt;/p&gt;

</description>
      <category>design</category>
      <category>career</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Wrapping React Query's useMutation (A Use Case for Wrapping External Libraries)</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Fri, 21 Jan 2022 15:05:26 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/wrapping-react-querys-usemutation-a-use-case-for-wrapping-external-libraries-4nj8</link>
      <guid>https://dev.to/michaelmangial1/wrapping-react-querys-usemutation-a-use-case-for-wrapping-external-libraries-4nj8</guid>
      <description>&lt;p&gt;React Query is a library for fetching and mutating server state via React hooks. In addition to the perk of caching, it also neatly returns metadata representing the various lifecycles of a network request for both querying (read operations) and mutating (create, update, delete operations):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isFetched&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isIdle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteTodo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This cuts down on the boilerplate when using React local state to track this metadata manually.&lt;/p&gt;

&lt;p&gt;As shown in the example above, the &lt;code&gt;useQuery&lt;/code&gt; and &lt;code&gt;useMutation&lt;/code&gt; hooks both have an argument for a function that will presumably make the network request (&lt;code&gt;getTodos&lt;/code&gt; and &lt;code&gt;deleteTodo&lt;/code&gt; respectively in our example).&lt;/p&gt;

&lt;p&gt;I have &lt;a href="https://dev.to/michaelmangial1/wrapping-react-querys-usequery-a-use-case-for-wrapping-external-libraries-34ed"&gt;previously written about alternatives to the signature of this hook that you can achieve by wrapping it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I'd like to ponder on potential ways to improve the signature of the &lt;code&gt;useMutation&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;First, there is currently no way of enforcing that all mutation functions go through the same API client.&lt;/p&gt;

&lt;p&gt;Imagine you wanted to set a pattern in the codebase to make all API requests through a wrapper around the native &lt;code&gt;fetch&lt;/code&gt; API. That way, some common logic can be encapsulated (like stringifying the request &lt;code&gt;body&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Let's say this wrapper is called &lt;code&gt;fetcher&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We would want to avoid one mutation function using the native &lt;code&gt;fetch&lt;/code&gt; API and the other using &lt;code&gt;fetcher&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, this could be enforced via code reviews, but what if there was a way to "document" the expected behavior through a design pattern?&lt;/p&gt;

&lt;p&gt;A slight improvement to inlining the functions in the file where &lt;code&gt;useMutation&lt;/code&gt; is called would be to colocate all the operations for an API endpoint in a single file, exporting each function individually.&lt;/p&gt;

&lt;p&gt;Then, each "operations" file (the file with all the operations for an API endpoint, including queries and mutations) would have a pattern of importing the &lt;code&gt;fetcher&lt;/code&gt; module and consuming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* /api/todos.js */&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fetcher&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;./fetcher&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/v1/todos&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="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;deleteTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/todos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE&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="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* some-component.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMutation&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-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteTodo&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;../api/todos&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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;removeTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteTodo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// not necessary, but wanted to showcase the `.mutate` in action&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRemoveTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine, but there's something else to consider.&lt;/p&gt;

&lt;p&gt;It is very common to "refresh" (or "requery") after doing a mutation.&lt;/p&gt;

&lt;p&gt;In this example, you would want to refresh the todos after deleting one (you could do optimistic updates, but I'm ignoring that for the sake of simplicity). &lt;/p&gt;

&lt;p&gt;To do this, you have to obtain access to &lt;code&gt;queryClient&lt;/code&gt; via the &lt;code&gt;useQueryClient&lt;/code&gt; hook, and then "invalidate" the todos query using &lt;code&gt;queryClient.invalidateQueries&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;queryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidateQueries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&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;The name of &lt;code&gt;invalidateQueries&lt;/code&gt; captures the technical sense of what's going on.&lt;/p&gt;

&lt;p&gt;To "refresh" your todos, you mark the todos as "stale" (effectively saying, "Hey! I may need to update the cached query results via an API request.").&lt;/p&gt;

&lt;p&gt;Here's what that would look like in our previous example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* some-component.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useQueryClient&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-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteTodo&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;../api/todos&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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;removeTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteTodo&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;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryClient&lt;/span&gt;&lt;span class="p"&gt;();&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;handleRemoveTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&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;removeTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;queryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidateQueries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can potentially improve this by encapsulating &lt;code&gt;useQueryClient&lt;/code&gt; and the query invalidation into a custom hook (and it provides an opportunity to come up with a preferred name to describe this logic):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* /api/index.js */&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;useRefresh&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;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryClient&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="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidateQueries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* some-component.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMutation&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-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRefresh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteTodo&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;../api&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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;removeTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteTodo&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;refresh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRefresh&lt;/span&gt;&lt;span class="p"&gt;();&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;handleRemoveTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&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;removeTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, if we wanted to inline the mutation function (&lt;code&gt;deleteTodo&lt;/code&gt;) while ensuring the same fetch client is used every time, we could expose a hook from the same file as &lt;code&gt;useRefresh&lt;/code&gt; that returns the fetch client for mutations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* /api/index.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fetcher&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;./fetcher&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;function&lt;/span&gt; &lt;span class="nf"&gt;useRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Add any mutation-specific request logic here&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* some-component.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMutation&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-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRefresh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteTodo&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;../api&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRequest&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;refresh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRefresh&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;removeTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/todos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE&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="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRemoveTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;removeTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Maybe you like these changes, maybe you don't. Either way, I hope this gets the brain juices flowing to consider ways to wrap React Query's &lt;code&gt;useMutation&lt;/code&gt; to fit the needs of your codebase.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Creating a Gradient Component in React From Design Tokens</title>
      <dc:creator>Michael Mangialardi</dc:creator>
      <pubDate>Thu, 20 Jan 2022 16:08:45 +0000</pubDate>
      <link>https://dev.to/michaelmangial1/creating-a-gradient-component-in-react-from-design-tokens-kll</link>
      <guid>https://dev.to/michaelmangial1/creating-a-gradient-component-in-react-from-design-tokens-kll</guid>
      <description>&lt;p&gt;If you're not familiar with &lt;a href="https://www.michaelmang.dev/blog/introduction-to-design-tokens" rel="noopener noreferrer"&gt;design tokens&lt;/a&gt;, they are simply representations of design specifications in code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8q5cbu96xnlznjr6ou0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8q5cbu96xnlznjr6ou0w.png" alt="Creating a Gradient Component in React From Design Tokens"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By "representations," it is meant that they are key-value pairs that represent design specifications.&lt;/p&gt;

&lt;p&gt;Generally speaking, there are two types of design tokens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"Simple" tokens - Representations of valid &lt;em&gt;values&lt;/em&gt; of the design system. These tokens usually cover the colors, typography, spacing, etc. of the design system (i.e. &lt;code&gt;color-red-500&lt;/code&gt;, &lt;code&gt;font-bold&lt;/code&gt;, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Component" tokens - Representations of the design specs for a component/element (i.e. &lt;code&gt;component-button-background-color&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsk9x7g2ps2p3gysf2z4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsk9x7g2ps2p3gysf2z4k.png" alt="Creating a Gradient Component in React From Design Tokens"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a &lt;a href="https://www.michaelmang.dev/blog/managing-and-exporting-design-tokens-with-style-dictionary" rel="noopener noreferrer"&gt;design tokens pipeline&lt;/a&gt;, you can write out design tokens in JSON format, and then translate those "raw"/JSON design tokens into formatted tokens (JavaScript modules, CSS variables, SASS variables, etc.).&lt;/p&gt;

&lt;p&gt;With that background in mind, imagine that a design system had "simple" design tokens defining valid colors.&lt;/p&gt;

&lt;p&gt;Here's the JSON representation:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&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;"color"&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;"red-50"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FFC3C2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"red-100"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FFAFAD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c1"&gt;// ...etc&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;p&gt;Now, imagine that a design tokens pipeline formats the JSON into the following JavaScript modules:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;colorRed50&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FFC3C2&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="nx"&gt;colorRed100&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FFAFAD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...etc&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And, let's say these tokens can be consumed in an application via an npm package:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// SomeComponent.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@some/design-system/tokens&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed50&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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="nx"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Some Component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, given such a setup, how can we programmatically create gradients when given two color tokens?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0zhns61di1x2xjxcik2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0zhns61di1x2xjxcik2a.png" alt="Creating a Gradient Component in React From Design Tokens"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's one way:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// SomeComponent.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@some/design-system/tokens&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;style&lt;/span&gt; &lt;span class="o"&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="s2"&gt;`
      linear-gradient(
        45deg,
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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="nx"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Some Component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Ok, but is there a way that we can refactor this?&lt;/p&gt;

&lt;p&gt;Well, we could create a helper function that returns the gradient when providing the &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; values:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// get-gradient.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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="s2"&gt;`linear-gradient(45deg, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// SomeComponent.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@some/design-system/tokens&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;getGradient&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;./get-gradient.js&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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;style&lt;/span&gt; &lt;span class="o"&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="nf"&gt;getGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed100&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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="nx"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Some Component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This refactor doesn't save in lines of code, but it does guarantee that gradients will be created the same so long as they are created through the &lt;code&gt;getGradient&lt;/code&gt; helper function.&lt;/p&gt;

&lt;p&gt;What if we refactored one step further and allowed the gradient to be applied to any child component via a wrapper component?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Gradient.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cloneElement&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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="s2"&gt;`linear-gradient(45deg, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Gradient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;cloneElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;style&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="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&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="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// SomeComponent.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@some/design-system/tokens&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AnotherComponent&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;./AnotherCompoent.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Gradient&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;./Gradient.jsx&lt;/span&gt;&lt;span class="dl"&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;SomeComponent&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="nc"&gt;Gradient&lt;/span&gt; &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorRed100&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AnotherComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Gradient&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By using &lt;code&gt;Children&lt;/code&gt; and &lt;code&gt;cloneElement&lt;/code&gt;, the &lt;code&gt;Gradient&lt;/code&gt; component clones the child element and applies the gradient.&lt;/p&gt;

&lt;p&gt;🎊 Awesome! Now, we have a pattern for applying a gradient via a wrapper component in React!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>design</category>
    </item>
  </channel>
</rss>
