<?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: Yassin Eldeeb 🦀</title>
    <description>The latest articles on DEV Community by Yassin Eldeeb 🦀 (@yassineldeeb).</description>
    <link>https://dev.to/yassineldeeb</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%2F678311%2F076495dd-cb67-41af-9d10-c92de698cdaf.png</url>
      <title>DEV Community: Yassin Eldeeb 🦀</title>
      <link>https://dev.to/yassineldeeb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yassineldeeb"/>
    <language>en</language>
    <item>
      <title>The Dark Side of Grinding: Burnout, Balance, and Identity</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Mon, 24 Mar 2025 04:12:13 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/burnout-after-years-of-grinding-what-i-learned-about-passion-balance-and-rebuilding-my-drive-2c48</link>
      <guid>https://dev.to/yassineldeeb/burnout-after-years-of-grinding-what-i-learned-about-passion-balance-and-rebuilding-my-drive-2c48</guid>
      <description>&lt;h2&gt;
  
  
  🧠 What is happiness, really?
&lt;/h2&gt;

&lt;p&gt;Ask different people, get different answers.&lt;br&gt;
For some, it’s building. For others, it’s connection.&lt;br&gt;
For many, it’s a quiet feeling of peace that sneaks up on you between chaotic moments.&lt;/p&gt;

&lt;p&gt;But underneath it all, our emotions are deeply biological.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Happiness, fulfillment, motivation — they’re not random. They’re chemical.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We feel it through a balance of four key brain chemicals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dopamine&lt;/strong&gt;:
the buzz of chasing goals and progress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serotonin&lt;/strong&gt;:
grounded peace, confidence, self-worth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oxytocin&lt;/strong&gt;:
emotional connection, closeness, trust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endorphins&lt;/strong&gt;:
physical joy, stress relief, laughter&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“When all four are in sync, we feel unstoppable. But when one takes over — like the dopamine from grinding or the oxytocin from social validation— everything goes off-balance.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;This is the story of how I’ve felt each of those states at the extreme — and what it taught me about building a life that actually works.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💨 Phase 1: The Rebel Dopamine Spike
&lt;/h2&gt;

&lt;p&gt;During school years, I felt most alive doing all the wrong things.&lt;br&gt;&lt;br&gt;
Skipping school. Stealing money from parents. Smoking. Hanging out with the worst influences.&lt;/p&gt;

&lt;p&gt;We were wild — and it felt amazing.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Adrenaline. Dopamine. Brotherhood.&lt;/strong&gt;The bond with those friends? That was oxytocin, in a weird way.&lt;br&gt;&lt;br&gt;
It was all toxic, sure — but in the moment, it made me feel seen. Alive. Important. And that’s what every kid wants.&lt;br&gt;&lt;br&gt;
Until I got caught.&lt;br&gt;
And everything collapsed.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Phase 2: The Lone Builder Era
&lt;/h2&gt;

&lt;p&gt;The crash triggered a transformation — but not a graceful one.&lt;br&gt;&lt;br&gt;
My world kind of collapsed.&lt;br&gt;&lt;br&gt;
Parents were disappointed. I was pulled out of school, forced into homeschooling to keep me away from bad influences.&lt;br&gt;&lt;br&gt;
And I felt… lost. Alone. Ashamed. Like I had no one.&lt;br&gt;&lt;br&gt;
So I turned inward — toward tech.&lt;br&gt;&lt;br&gt;
Not because I wanted to get rich or build cool things — but because I needed something, anything, that could make me feel okay again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Coding became my escape. My new drug. My identity.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I cut off everyone. I didn’t just lose toxic friends — I disconnected from everyone. No school. No social life. Just me, my laptop, and the grind.&lt;br&gt;&lt;br&gt;
And I went all in.&lt;br&gt;&lt;br&gt;
I got my first dev job very early soon after 2yrs of self learning to code. Then another. And another. And another… I climbed fast. I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Built front-ends for major U.S.
homeschooling platforms&lt;/li&gt;
&lt;li&gt;
Joined many hackathons solving real-world
issues like police accountability in
Chicago&lt;/li&gt;
&lt;li&gt;
Developed trading tools for one of the
largest financial firms&lt;/li&gt;
&lt;li&gt;
Contributed to some of the most prominent
open-source projects&lt;/li&gt;
&lt;li&gt;
Spoke at international conferences online
and in-person&lt;/li&gt;
&lt;li&gt;
etc…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the outside, I looked unstoppable.&lt;br&gt;&lt;br&gt;
But inside? I was emotionally empty.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;I was living off purely on dopamine&lt;/strong&gt; — the thrill of building, shipping, winning. But I had no calm, no connection, no physical vitality. Just fast food, code, and screen time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I didn’t enjoy my life where I was — not because of the work, but because the people around me didn’t share my energy, my goals, or my mindset. I felt like a stranger in my own world.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wasn’t sad. I wasn’t happy either. I was just… &lt;strong&gt;functional&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;And that’s sometimes the most dangerous place to be — because it convinces you to stay stuck.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🌅 Phase 3: Rebirth in Europe&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Then, I moved to Europe.&lt;br&gt;&lt;br&gt;
And everything — everything — changed.&lt;br&gt;&lt;br&gt;
After years of isolation, self-imposed pressure, and emotional numbness… I stepped into a new environment, and it felt like I could finally breathe.&lt;br&gt;
For the first time in my life:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I had sunlight on my skin daily&lt;/li&gt;
&lt;li&gt;I had real, human connection&lt;/li&gt;
&lt;li&gt;I was surrounded by a different vibe — people who were alive, expressive, present&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I started rebuilding myself from the ground up.&lt;br&gt;&lt;br&gt;
I joined a boxing gym.&lt;br&gt;
Started lifting weights. I dropped 25kg of fat.&lt;br&gt;&lt;br&gt;
I went from extremely overweight to fit, strong, confident.&lt;br&gt;&lt;br&gt;
I completely cut out fast food. Cleaned up my diet.&lt;br&gt;
Started fueling and training my body like an athlete.&lt;br&gt;&lt;br&gt;
I built up my experience with dating, flirting, romance, and intimacy — stuff I never had space for in the grind years.&lt;br&gt;&lt;br&gt;
I learned what it means to give pleasure, to connect deeply, to be desired — and to desire back, with confidence.&lt;br&gt;&lt;br&gt;
I trained my social skills like I trained my muscles: with intention, patience, and reps.&lt;br&gt;&lt;br&gt;
And slowly… I began to love being in my own skin.&lt;br&gt;&lt;br&gt;
I started having fun again. Laughing. Meeting people. Building friendships that weren’t just social — they were soul-aligned.&lt;br&gt;&lt;br&gt;
For the first time, happiness didn’t come from proving myself — it came from being myself.&lt;br&gt;
And chemically? My system was finally in harmony:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serotonin&lt;/strong&gt; from sunlight, fitness, and daily movement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oxytocin&lt;/strong&gt; from real friendships and emotional connection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endorphins&lt;/strong&gt; from training and sweating and pushing my body&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dopamine&lt;/strong&gt; still there — but no longer running the show&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“It wasn’t a grind anymore. It was alignment.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  😵‍💫 But Here’s Where It Gets Complicated…
&lt;/h2&gt;

&lt;p&gt;For the past 9 months… Coding has been the least of my priorities. And I’ve felt good. Really good.&lt;br&gt;&lt;br&gt;
But also… really guilty.&lt;br&gt;&lt;br&gt;
Because I used to love building. I used to wake up excited to create.&lt;br&gt;&lt;br&gt;
Now, the thought of coding for hours feels… draining.&lt;br&gt;&lt;br&gt;
Like something I’ve outgrown, even though it once defined me.&lt;br&gt;&lt;br&gt;
Which is crazy — because I’m full of insane ideas to build.&lt;br&gt;&lt;br&gt;
And I’ve never been sharper — mentally, physically, emotionally.&lt;br&gt;&lt;br&gt;
But I feel rusty. Hesitant. Unmotivated.&lt;br&gt;&lt;br&gt;
And maybe… I’m scared.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Scared that falling back in love with coding will cost me the life I fought to build. Scared that productivity will once again become a prison.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔭Here’s What I’ve Learned
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“You haven’t lost your passion. You’ve just outgrown the reason you used to work.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I used to build to survive. To feel seen. To escape. To prove something.&lt;br&gt;&lt;br&gt;
Now, I want to create from &lt;strong&gt;joy&lt;/strong&gt;, not fear.&lt;br&gt;&lt;br&gt;
From &lt;strong&gt;expression&lt;/strong&gt;, not validation.&lt;br&gt;&lt;br&gt;
I want to build something that fits the life I’ve designed — not replaces it.&lt;br&gt;
Because one thing I know for sure:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Whatever I pour my mind and soul into…I master.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tech.&lt;br&gt;&lt;br&gt;
Boxing.&lt;br&gt;&lt;br&gt;
Nutrition.&lt;br&gt;&lt;br&gt;
Social life.&lt;br&gt;&lt;br&gt;
Romance.&lt;br&gt;&lt;br&gt;
Even rebuilding my own body from scratch.&lt;/p&gt;

&lt;p&gt;So the mission now isn’t to pick one.&lt;br&gt;&lt;br&gt;
It’s to build a life where all of me gets to exist — in balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 The Line That Changed Everything
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build your social life around your mission - not as an escape from it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I first read that… I froze.&lt;br&gt;
Because it hit too close.&lt;br&gt;
I realized I had spent the past few months doing the opposite.&lt;br&gt;
Surrounding myself with good people - but not mission-aligned ones.&lt;br&gt;
Going out. Hanging out. Socializing… but drifting.&lt;br&gt;
And here's the truth:&lt;br&gt;
When your social life isn't aligned with your purpose, it starts to erode it. Slowly. Silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏡 Environment Shapes Everything
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“You don’t rise to the level of your goals — you fall to the level of your environment.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lately, I’ve been living in Aveiro — a small, slow city in Portugal.&lt;/p&gt;

&lt;p&gt;Peaceful? Yes.&lt;br&gt;
But uninspiring.&lt;br&gt;
Surrounded by retired people… and young people with no ambition.&lt;/p&gt;

&lt;p&gt;And when you’re around people with no fire,&lt;strong&gt;your flame dims too&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I started to feel retired. Lazy. Unmotivated.&lt;/p&gt;

&lt;p&gt;Like I was waiting for life to happen again.&lt;br&gt;&lt;br&gt;
And that’s when it hit me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Where you live isn’t just a location — it’s an operating system. It rewires your habits, your energy, your identity.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🥊 A New Chapter — Not a Reset, a Merge
&lt;/h2&gt;

&lt;p&gt;I’m moving again…this time to the capital — Lisbon.&lt;br&gt;&lt;br&gt;
Not to run away — but to &lt;strong&gt;realign&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because I don’t need to become someone new.&lt;br&gt;&lt;br&gt;
I just need to create space for &lt;strong&gt;all the versions of me&lt;/strong&gt; to coexist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The builder&lt;/li&gt;
&lt;li&gt;
The competitive boxer&lt;/li&gt;
&lt;li&gt;
The romantic&lt;/li&gt;
&lt;li&gt;
The social connector&lt;/li&gt;
&lt;li&gt;
The ambitious grinder&lt;/li&gt;
&lt;li&gt;
The calm, grounded one&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“You don’t have to choose between the driven you, the social you, or the peaceful you. You’re allowed to build a life where all of them belong."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This next move isn’t about escape — it’s about &lt;strong&gt;integration&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
A lifestyle designed to hold the &lt;strong&gt;balance I’ve earned&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
A co-working space full of creatives and
builders at the heart of the capital&lt;/li&gt;
&lt;li&gt;
A boxing gym where I can keep pushing
myself for competing&lt;/li&gt;
&lt;li&gt;
A neighborhood where energy is alive&lt;/li&gt;
&lt;li&gt;
Routines that support clarity, movement,
and stillness&lt;/li&gt;
&lt;li&gt;
People who share momentum, not just
moments&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you’re not happy where you are — move!! You’re not a f*cking tree.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;💥 If You’re In That In-Between Place Too…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then hear this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
If your fire is fading… maybe your fuel
needs to change.&lt;/li&gt;
&lt;li&gt;
If your environment feels off… it’s okay
to outgrow it.&lt;/li&gt;
&lt;li&gt;
If you’re split between versions of
yourself — don’t choose.
&lt;strong&gt;Build the container that holds them
all.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, it took stepping &lt;em&gt;out&lt;/em&gt; of Europe — back to the place where my grind began — to finally connect the dots. I saw the driven, isolated version of me… and the free, expressive, connected version I’d become. And I realized: I need &lt;em&gt;both&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Before that, I thought Europe-me was the answer. But it turns out, neither version is complete on its own.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Balance doesn’t mean mediocrity.&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;It means creating space where your ambition and your aliveness don’t have to compete — they can coexist.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>burnout</category>
      <category>mentalhealth</category>
      <category>productivity</category>
    </item>
    <item>
      <title>So, I went down the rabbit hole of buying GitHub Stars, so you won't have to 😄</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Thu, 01 Jun 2023 14:09:35 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/so-i-went-down-the-rabbit-hole-of-buying-github-stars-so-you-wont-have-to-2alf</link>
      <guid>https://dev.to/yassineldeeb/so-i-went-down-the-rabbit-hole-of-buying-github-stars-so-you-wont-have-to-2alf</guid>
      <description>&lt;p&gt;Checkout my blog post&lt;/p&gt;

&lt;p&gt;&lt;a href="https://the-guild.dev/blog/judging-open-source-by-github-stars" rel="noopener noreferrer"&gt;https://the-guild.dev/blog/judging-open-source-by-github-stars&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deadliner</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Mon, 04 Apr 2022 19:40:07 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/deadliner-3g8f</link>
      <guid>https://dev.to/yassineldeeb/deadliner-3g8f</guid>
      <description>&lt;p&gt;🎉🥳Announcing Deadliner&lt;/p&gt;

&lt;p&gt;Manage your deadline gently by updating the wallpaper of your desktop with the time left.&lt;/p&gt;

&lt;p&gt;🗓️Set deadline&lt;br&gt;
🖼️Update wallpaper dynamically&lt;br&gt;
🤗Less annoying way for reminding you&lt;br&gt;
🎨Full Customization&lt;br&gt;
👨‍👦‍👦Cross Platform&lt;br&gt;
⚡🦀 Efficient&lt;/p&gt;

&lt;p&gt;Learn more:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/ySn-Ykdq5BU" rel="noopener noreferrer"&gt;YouTube Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deadliner.vercel.app" rel="noopener noreferrer"&gt;Landing page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/YassinEldeeb/deadliner" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>productivity</category>
      <category>product</category>
      <category>deadline</category>
    </item>
    <item>
      <title>Mutex in Rust can be tricky sometimes...</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Mon, 21 Feb 2022 21:50:16 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/mutex-in-rust-can-be-tricky-sometimes-8md</link>
      <guid>https://dev.to/yassineldeeb/mutex-in-rust-can-be-tricky-sometimes-8md</guid>
      <description>&lt;h2&gt;
  
  
  Can you guess why snippet 1 is outperforming by 400% than snippet 2 🤯
&lt;/h2&gt;

&lt;p&gt;So, this is a thread pool implementation for a simple HTTP server using an &lt;code&gt;mpsc channel&lt;/code&gt; to add incoming requests' handlers to a queue then threads can receive the sent closures (request handlers) and execute them in parallel.&lt;/p&gt;

&lt;h4&gt;
  
  
  Snippet 1:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="nf"&gt;FnOnce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&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;struct&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;JoinHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Receiver&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Job&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// here 👇&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// here 👆&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"executing on thread: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nf"&gt;job&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread&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;h4&gt;
  
  
  Snippet 2:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="nf"&gt;FnOnce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&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;struct&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;JoinHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Receiver&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Job&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// here 👇&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// here 👆&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"executing on thread: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nf"&gt;job&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread&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;h2&gt;
  
  
  Benchmarks
&lt;/h2&gt;

&lt;p&gt;Tested using &lt;a href="https://www.artillery.io/" rel="noopener noreferrer"&gt;Artillery&lt;/a&gt; on a CPU that has 16 logical processors and checked the graphs to confirm that all threads are indeed running in parallel and not concurrently.&lt;/p&gt;

&lt;p&gt;Look at the spikes 👇&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7pnLXoAYjQpt%3Fformat%3Dpng%26name%3Dsmall" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7pnLXoAYjQpt%3Fformat%3Dpng%26name%3Dsmall" alt="CPU" width="424" height="441"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Snippet 1:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7cG-XwAMN2Aj%3Fformat%3Dpng%26name%3D900x900" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7cG-XwAMN2Aj%3Fformat%3Dpng%26name%3D900x900" alt="Snippet 1" width="823" height="217"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Snippet 2:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7c0IWUAA3SyJ%3Fformat%3Dpng%26name%3D900x900" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpbs.twimg.com%2Fmedia%2FFMI7c0IWUAA3SyJ%3Fformat%3Dpng%26name%3D900x900" alt="Snippet 2" width="813" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Really? a single line can make that difference? aren't they the same though 🤔
&lt;/h2&gt;

&lt;p&gt;Let's discuss a few things first to understand where is the problem 👨‍🏫&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mpsc&lt;/code&gt; from its name is "multiple producers, single consumer", in this case, we want a single producer(main thread) to add requests' handlers to the queue and we want multiple consumers so that multiple threads can consume messages in parallel.&lt;/p&gt;

&lt;p&gt;So to achieve our goal we wrapped the receiver we got from &lt;code&gt;mpsc&lt;/code&gt; in an &lt;code&gt;Arc&lt;/code&gt; which gives us multiple ownership for the receiver to pass to the different threads to work with and to make it that only one thread is responsible for executing a handler we used &lt;code&gt;Mutex&lt;/code&gt; which allows only one thread to access the receiver at any given time, because we don't want two threads to respond for a given request.&lt;/p&gt;

&lt;p&gt;To access the data in a mutex, a thread must first signal that it wants access by asking to acquire the mutex’s lock. This lock keeps track of who currently has exclusive access to the data and the lock is released when the &lt;code&gt;MutexGuard&lt;/code&gt; is dropped.&lt;/p&gt;
&lt;h3&gt;
  
  
  Notice in snippet 1:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// -------⬇⬇⬇⬇Temporary Value⬇⬇⬇⬇&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;✨the trick here is: using &lt;code&gt;let&lt;/code&gt;, any temporary values used in the expression on the right-hand side of the equals sign are immediately dropped when the let statement ends!&lt;/p&gt;

&lt;p&gt;So that means that the lock is released before the thread even starts executing the handler, which means that other threads can acquire the lock to receive incoming requests' handlers to process them 💪&lt;/p&gt;

&lt;p&gt;As you see here we're running 16 threads in parallel which is freaking awesome!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;executing on thread: 0
executing on thread: 1
executing on thread: 2
executing on thread: 5
executing on thread: 4
executing on thread: 3
executing on thread: 10
executing on thread: 7
executing on thread: 13
executing on thread: 9
executing on thread: 6
executing on thread: 11
executing on thread: 12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  On the other hand with snippet 2:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;acquired_lock&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
       &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;acquired_lock&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

       &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"executing on thread: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

       &lt;span class="nf"&gt;job&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// `acquired_lock` is dropped here and lock is released.&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the lock is released after the execution of the handler, specifically at the end of the scope where It was defined.&lt;/p&gt;

&lt;p&gt;Therefore the threads, in this case, are running concurrently and not in parallel, cause each thread has to wait for the other thread who acquired the lock to release it so that it can read the sent closures from the receiver.&lt;/p&gt;

&lt;p&gt;And actually the current lock acquirer probably will pick it up again faster than other threads cause it's like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;acquire lock.&lt;/li&gt;
&lt;li&gt;release lock.&lt;/li&gt;
&lt;li&gt;next iteration of the loop.&lt;/li&gt;
&lt;li&gt;acquire lock.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;which finally leads to single-threaded execution even if there are threads spawned and waiting in the pool, As shown below 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
executing on thread: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very tricky right? 😅&lt;/p&gt;

&lt;p&gt;The lesson here is, to be careful when dealing with &lt;code&gt;Mutex&lt;/code&gt; cause the compiler can't guarantee the desired threading behavior you wanna achieve such as this scenario or other scenarios like deadlocks which are so much worse.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That's why I've included a picture of Ferris that means that "This code compiles but does not produce the desired behavior." from the &lt;a href="https://doc.rust-lang.org/book/ch00-00-introduction.html#ferris" rel="noopener noreferrer"&gt;rust lang book&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without the logs, I wouldn't even notice that there was a problem 🤷‍♂️&lt;/p&gt;

&lt;p&gt;Hope you enjoyed it 🤗&lt;/p&gt;

</description>
      <category>rust</category>
      <category>tricky</category>
      <category>mutex</category>
      <category>multithreading</category>
    </item>
    <item>
      <title>Create Prisma Generator</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Sat, 25 Dec 2021 15:14:03 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/create-prisma-generator-2mdg</link>
      <guid>https://dev.to/yassineldeeb/create-prisma-generator-2mdg</guid>
      <description>&lt;p&gt;This blog is hosted on &lt;a href="https://github.com/YassinEldeeb/create-prisma-generator/tree/main/dev.to/blogs/create-prisma-generator"&gt;this github repo&lt;/a&gt; in &lt;code&gt;content.md&lt;/code&gt; file so feel free to correct me when I miss up by making a PR there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's a prisma generator? 🤔
&lt;/h2&gt;

&lt;p&gt;Prisma has a concept called "Generator". A generator is an executable program, which takes the parsed Prisma schema as an input and has full freedom to output anything.&lt;/p&gt;

&lt;p&gt;The most prominent generator is called &lt;a href="https://github.com/prisma/prisma/tree/main/packages/client" rel="noopener noreferrer"&gt;&lt;code&gt;prisma-client-js&lt;/code&gt;&lt;/a&gt;. It's the ORM Client powering the main TypeScript and JavaScript usage of Prisma from Node.js.&lt;/p&gt;

&lt;p&gt;Generators will always be called when you run &lt;code&gt;prisma generate&lt;/code&gt;. However, only the generators mentioned in the &lt;code&gt;schema.prisma&lt;/code&gt; file are being run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://prismaio.notion.site/Prisma-Generators-a2cdf262207a4e9dbcd0e362dfac8dc0" rel="noopener noreferrer"&gt;Strongly recommend reading the full article, It's pretty damn good&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From a community perspective when integrating prisma in different environments you'll often notice that there's a thing that you always go to change after modifying your prisma schema in your codebase, and that's when great developers realize that this thing should be automated to eliminate the problem of maintaining two or more different sources of the same definitions.&lt;/p&gt;

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

&lt;p&gt;Now that you've a high level overview of what a prisma generator is, let's discuss the hello world prisma generator you'll get when using create-prisma-generator CLI 💪&lt;/p&gt;

&lt;p&gt;I made it so that it requires the least amount of effort to start developing your own prisma generator.&lt;/p&gt;

&lt;p&gt;Answer the prompt questions to setup your project, The project setup will be based on your answers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: "? setup workspace for testing the generator" means to symlink the generator with another sample usage project so that when you run &lt;code&gt;prisma generate&lt;/code&gt; from your terminal, It uses the local generator in the workspace which is very useful when developing, I strongly recommend it.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx create-prisma-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll go and answer Yes for everything to go with the full capabilities of this CLI but you can follow along with your setup too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1olao75k8i398k22jo0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1olao75k8i398k22jo0f.png" alt="my-answers-to-questions" width="750" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And once you see the success message in your terminal saying that your project is now ready, open the project in your favourite IDE and let's have some fun 😉&lt;/p&gt;

&lt;p&gt;First let's open the &lt;code&gt;schema.prisma&lt;/code&gt; which you can find it at &lt;code&gt;packages/usage/prisma/schema.prisma&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You'll notice your generator there symlinked with the generator code in the workspace&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: the provider can differ from package manager to another, here I chose &lt;code&gt;pnpm&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;generator&lt;/span&gt; &lt;span class="nx"&gt;custom_generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx my-gen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;output&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../types&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;You'll also see some enums there, that's because the hello world generator that you get from running &lt;code&gt;create-prisma-generator&lt;/code&gt; is for generating Typescript Enums from &lt;code&gt;schema.prisma&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let's run the &lt;code&gt;prisma generate&lt;/code&gt; command which should run all of the generators listed in &lt;code&gt;schema.prisma&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;packages/usage
&lt;span class="nv"&gt;$ &lt;/span&gt;npx prisma generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, WOW! the types directory wasn't there before, what the hell happened!&lt;/p&gt;

&lt;p&gt;You can see that the &lt;code&gt;types&lt;/code&gt; directory was generated after running &lt;code&gt;prisma generate&lt;/code&gt; which contains all of the different enums defined in &lt;code&gt;schema.prisma&lt;/code&gt; organized by an enum per file.&lt;/p&gt;

&lt;p&gt;So if you opened any of the files in the &lt;code&gt;types&lt;/code&gt; directory, you'll see an enum that matches exactly with the name and values as defined in &lt;code&gt;schema.prisma&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Language&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Typescript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Typescript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Javascript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Rust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rust&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Go&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Go&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Python&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Python&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Cpp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cpp&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;Noticed something? the output option in the &lt;code&gt;custom_generator&lt;/code&gt; block in &lt;code&gt;schema.prisma&lt;/code&gt; tells the generator where to output the generated files with a path relative to the directory where &lt;code&gt;schema.prisma&lt;/code&gt; is located, try to change this option to something different like &lt;code&gt;../src/types&lt;/code&gt; and run &lt;code&gt;npx prisma generate&lt;/code&gt; again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;generator&lt;/span&gt; &lt;span class="nx"&gt;custom_generator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx my-gen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;output&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../src/types&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;You'll see that it created all of the directories for the defined path and outputted the generated enums there.&lt;/p&gt;

&lt;p&gt;Now after we've played around with the Hello World generator, Let's take a look at the code for it.&lt;/p&gt;

&lt;p&gt;You can find the generator code located under &lt;code&gt;packages/generator&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;packages/generator/src/generator.(ts|js)&lt;/code&gt; and let's slowly discuss what's in there.&lt;/p&gt;

&lt;p&gt;At the top you'll see we're importing some strange modules like &lt;code&gt;@prisma/generator-helper&lt;/code&gt;, &lt;code&gt;@prisma/sdk&lt;/code&gt;, what are those?&lt;/p&gt;

&lt;h2&gt;
  
  
  @prisma/generator-helper
&lt;/h2&gt;

&lt;p&gt;The generator has to be an executable binary somewhere in the filesystem. This binary, for example &lt;code&gt;./my-gen&lt;/code&gt; needs to implement a JSON RPC interface via stdio.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When &lt;code&gt;@prisma/sdk&lt;/code&gt; spawns our generator, It uses &lt;a href="https://en.wikipedia.org/wiki/JSON-RPC" rel="noopener noreferrer"&gt;RPCs&lt;/a&gt; to communicate with our generator to send it the parsed datamodel AST as an example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Luckily for us, prisma has wrote a helper library called &lt;code&gt;@prisma/generator-helper&lt;/code&gt;. It takes all the work of implementing the interface and gives us simple callbacks where we can implement our business logic.&lt;/p&gt;

&lt;p&gt;And as you can see, It has a callback called &lt;code&gt;generatorHandler&lt;/code&gt; which takes two methods:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;onManifest:&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When running the prisma cli with the following command &lt;code&gt;prisma generate&lt;/code&gt; It gets our generator manifest that gets returned from the &lt;code&gt;onManifest&lt;/code&gt; callback method which contains all of the information about our generator like It's name, version, default output, which binaries and which version the generator needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;generatorHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nf"&gt;onManifest&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;...&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;h3&gt;
  
  
  &lt;code&gt;onGenerate:&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is a callback method that run when &lt;code&gt;@prisma/sdk&lt;/code&gt; calls it with the correct arguments that contains the parsed datamodel AST, generator options and other useful information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;generatorHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;onGenerate&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="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GeneratorOptions&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="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;h2&gt;
  
  
  @prisma/sdk
&lt;/h2&gt;

&lt;p&gt;This is an internal API that has some very cool utilities that are often used when developing prisma generators which I've documented some parts about it &lt;a href="https://github.com/YassinEldeeb/create-prisma-generator/blob/main/PRISMA_SDK_REFERENCE.md" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to our Hello World generator
&lt;/h2&gt;

&lt;p&gt;After we've dicussed a bit about &lt;code&gt;@prisma/generator-helper&lt;/code&gt; and &lt;code&gt;@prisma/sdk&lt;/code&gt;, Let's get back to &lt;code&gt;generator.(ts|js)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You'll first see that we're importing the generator's package.json and grabbing the version out if it to pass it as a part of the generator manifest,&lt;/p&gt;

&lt;p&gt;then using the &lt;code&gt;GENERATOR_NAME&lt;/code&gt; constant which is imported from &lt;code&gt;packages/generator/constants.ts&lt;/code&gt; to log an info message to let us know when our generator is registred then returning an object expressing our generator manifest.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;version&lt;/code&gt; and &lt;code&gt;prettyName&lt;/code&gt; are used by &lt;code&gt;@prisma/sdk&lt;/code&gt; when It calls &lt;code&gt;getGeneratorSuccessMessage&lt;/code&gt; to generate a success message from our generator manifest like shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkha7d1ei1jrig7av809.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkha7d1ei1jrig7av809.png" alt="generator-success-message" width="633" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;defaultOutput&lt;/code&gt; is a fallback for the &lt;code&gt;output&lt;/code&gt; option if It wasn't provided in the generator block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;generatorHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nf"&gt;onManifest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&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;GENERATOR_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:Registered`&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;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;defaultOutput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../generated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;prettyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GENERATOR_NAME&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's get to the &lt;code&gt;onGenerate&lt;/code&gt; callback where you'll receive the generator options which you can find the latest type definitions &lt;a href="https://github.com/prisma/prisma/blob/main/packages/generator-helper/src/types.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;, this contains a lot of information for our generator to use like pure datamodel, dmmf, generator(config, name, output, provider), schemaPath, version and hell a lot more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DMMF?? It's the Datamodel Meta Format. It is an AST (abstract syntax tree) of the datamodel in the form of JSON.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can see that we're specifically making use of &lt;code&gt;options.dmmf.datamodel.enums&lt;/code&gt; which contains all of the parsed enums as AST that we can then have full freedom of outputting anything with this information.&lt;/p&gt;

&lt;p&gt;We're using a helper function that can be found in &lt;code&gt;packages/generator/src/helpers/genEnum.(ts|js)&lt;/code&gt; that takes the enum information and gives us back a string containing a Typescript Enum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;generatorHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;onGenerate&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="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GeneratorOptions&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dmmf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;datamodel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&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;enumInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tsEnum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;genEnum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;enumInfo&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;writeLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;!&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;enumInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.ts`&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;writeFileSafely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;writeLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tsEnum&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;Nothing crazy to make a Typescript Enum from the enum info, you can take a look at the file, It's really really simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genEnum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;DMMF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DatamodelEnum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enumValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&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;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;name&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;name&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&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;`enum &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; { \n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;enumValues&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n }`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another thing you'll see is a utility function called &lt;code&gt;writeFileSafely&lt;/code&gt; which takes the write location for the file and the content for that file then It creates all of the directories recursivly following the write location path and uses another utility function called &lt;code&gt;formatFile&lt;/code&gt; to format the content using prettier before writing the file to the specified path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;writeFileSafely&lt;/span&gt; &lt;span class="o"&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;writeLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;writeLocation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;writeLocation&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;formatFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, that's our Hello World generator, hope It was a fun ride.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I develop within this workspace?
&lt;/h2&gt;

&lt;p&gt;1- Open a new terminal and cd into &lt;code&gt;packages/generator&lt;/code&gt; and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# You can use whatever package manager to run the dev script&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will watch your changes and compile on save into a dist folder.&lt;/p&gt;

&lt;p&gt;2- Open another terminal and cd into &lt;code&gt;packages/usage&lt;/code&gt; and here you'll have the latest build of your generator's code symlinked to this package so running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx prisma generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;..will always use the latest code of your compiled generator.&lt;/p&gt;

&lt;p&gt;And as you iterate over your generator's code, you can run &lt;code&gt;npx prisma generate&lt;/code&gt; to see the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing 🧪
&lt;/h2&gt;

&lt;p&gt;Quality Software can't be shipped directly to the users and have to be well tested before It goes live.&lt;/p&gt;

&lt;p&gt;That's why I've included jest in any project that gets bootstrapped by &lt;code&gt;create-prisma-generator&lt;/code&gt; CLI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't know what jest is? It's a JavaScript Testing Framework &lt;a href="https://jestjs.io/docs/getting-started" rel="noopener noreferrer"&gt;learn more about it here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's a very simple test located under &lt;code&gt;packages/generator/__tests__/&lt;/code&gt; called &lt;code&gt;genEnum.test.ts&lt;/code&gt;, If you opened this file you'll see a test written that compares the generated output of the genEnum() helper function we've talked about previously with the already taken snapshot of a working version of this function.&lt;/p&gt;

&lt;p&gt;We can run that test by running the following command in &lt;code&gt;packages/generator&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# You can use whatever package manager to run the test script&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pnpm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see all of the tests are passing, that means our software is ready to be shipped! 🥳&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fdq1u70zhrdyqua727k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fdq1u70zhrdyqua727k.png" alt="generator-success-message" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see that we're not getting the DMMF from &lt;code&gt;@prisma/sdk&lt;/code&gt;, mmm... that's strange but how are we getting the DMMF from a &lt;code&gt;schema.prisma&lt;/code&gt; and where is even that &lt;code&gt;schema.prisma&lt;/code&gt; file?&lt;/p&gt;

&lt;p&gt;Usually in production the DMMF gets sent through this cycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@prisma/cli -&amp;gt; @prisma/sdk -&amp;gt; Spawns Generators -&amp;gt; Send DMMF through RPCs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which works perfectly fine but not the ideal when testing prisma generators, we can cut this cycle and just get the utility function in @prisma/sdk that's responsible for generating the DMMF from a prisma definitions string which called &lt;code&gt;getDMMF&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So as you can see we're calling &lt;code&gt;getSampleDMMF()&lt;/code&gt; from the fixtures defined in the tests directory which then reads the &lt;code&gt;sample.prisma&lt;/code&gt; located under &lt;code&gt;__tests__/__fixtures__/&lt;/code&gt; and parse it to an AST exactly like the one we get normally in a production environment.&lt;/p&gt;

&lt;p&gt;And now It's up to you to write tests for your own generator.&lt;/p&gt;

&lt;p&gt;I'm curios to see your creative solutions for testing your prisma generator 🤗.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fancy Stuff ✨
&lt;/h2&gt;

&lt;p&gt;Now let's get fancy with the full capabilities of this CLI and manage this project like an elite open source programmer 💪.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto Publishing 🚀
&lt;/h3&gt;

&lt;p&gt;Remember the "automate publishing the generator with Github Actions" I've said yes to it at first.&lt;/p&gt;

&lt;p&gt;That had setup a Github Actions workflow at &lt;code&gt;.github/workflows/CI.yml&lt;/code&gt; which will run all of our generator tests then if they're all passing It will publish the package to npm using your Access Token.&lt;/p&gt;

&lt;p&gt;To get an access token, you must first be logged in with your npm account or &lt;a href="https://www.npmjs.com/signup" rel="noopener noreferrer"&gt;register here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on your profile picture and go to "Access Tokens" like shown in the screenshot below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81mspmk0fa58mn2e1wx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81mspmk0fa58mn2e1wx1.png" alt="npm-profile-dropdown" width="404" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on "Generate New Token" and select the token type to be "Automation" so that you don't require 2FA when running in a CI environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkcchfnpxt5h3swohdiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkcchfnpxt5h3swohdiz.png" alt="npm-profile-dropdown" width="776" height="754"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before start publishing your package to npm, you'll need to replace the placeholders in &lt;code&gt;packages/generator/package.json&lt;/code&gt; with actual information like: description, homepage, repository, author and keywords.&lt;br&gt;
Check the docs to know what all of those fields mean &lt;a href="https://docs.npmjs.com/cli/v8/configuring-npm/package-json" rel="noopener noreferrer"&gt;npm package.json docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that you've your npm access token you can create a new github repository and add a new secret to your github actions secrets with this exact same name &lt;code&gt;NPM_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa32oytes4ytviesqhbcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa32oytes4ytviesqhbcn.png" alt="npm-profile-dropdown" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's make a small change to this generator like changing the name of the generator as an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- export const GENERATOR_NAME = 'my-gen'
&lt;/span&gt;&lt;span class="gi"&gt;+ export const GENERATOR_NAME = 'my-super-gen'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then commit &amp;amp; push to your repository on the &lt;code&gt;main&lt;/code&gt; branch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="s2"&gt;"fix: generator name"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you push, go to your repository on github specifically on tha &lt;code&gt;Actions&lt;/code&gt; tab and you'll immediately see the tests running and after they finish, the package will be published to npm with the version specified in the generator's package.json using your access token which you can then find using the following url &lt;code&gt;https://www.npmjs.com/package/$your-generator-name&lt;/code&gt; 🥳.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi8zbf1nmk0atzwp7dsh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi8zbf1nmk0atzwp7dsh.png" alt="github-actions.png" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Semantic Versioning 🤖
&lt;/h3&gt;

&lt;p&gt;Don't know what semantic versioning is?, Mahmoud Abdelwahab got you covered with a 1 minute video about it &lt;a href="https://www.youtube.com/watch?v=5NQUut8uf9w" rel="noopener noreferrer"&gt;check it out&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we've a workflow for testing and automatic publishing the package to npm but It's not very nice having to go and manually bump the version in the &lt;code&gt;package.json&lt;/code&gt; everytime you change something and wanna publish it.&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://github.com/semantic-release/semantic-release" rel="noopener noreferrer"&gt;semantic-release&lt;/a&gt;, we can just focus on our commit messages and It'll do the rest of the work for us like: bumping the version, github release, git tag, generating a CHANGELOG and a lot more.&lt;/p&gt;

&lt;p&gt;Remember the "(Github Actions) setup automatic semantic release" I've said yes to it at first.&lt;/p&gt;

&lt;p&gt;That had setup semantic-release for me with the Github Actions workflow and added husky with commitlint to force &lt;a href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format" rel="noopener noreferrer"&gt;Conventional Commit Messages&lt;/a&gt; which then semantic-release will recognize and decide the next version based on it and do all of the stuff for us.&lt;/p&gt;

&lt;p&gt;But there's a very small configuration we still need to make for this to work as intended.&lt;/p&gt;

&lt;p&gt;Remember when I said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;bumping the version, github release, git tag, generating a CHANGELOG and a lot more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, semantic-release needs read/write access over public/private repos to achieve all of that.&lt;/p&gt;

&lt;p&gt;Create a new github access token &lt;a href="https://github.com/settings/tokens/new?scopes=repo" rel="noopener noreferrer"&gt;from this link&lt;/a&gt; providing a note for it so you can remember what it was for.&lt;/p&gt;

&lt;p&gt;Now that you've your github access token you can add a new secret to your github actions secrets with this exact same name GH_TOKEN which semantic-release will look for to do all of the magic for us.&lt;/p&gt;

&lt;p&gt;Let's make a smalll change to this generator like changing the name of the generator as an example and call it a minor release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  generatorHandler({
  onManifest() {
&lt;span class="gd"&gt;-   logger.info(`${GENERATOR_NAME}:Registered`)
&lt;/span&gt;&lt;span class="gi"&gt;+   logger.info(`${GENERATOR_NAME}:Hooked`)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then commit &amp;amp; push to your repository on the &lt;code&gt;main&lt;/code&gt; branch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="s2"&gt;"new register message"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh crab what the hell is this?&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnlnsnlhsrxbxnb26tjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnlnsnlhsrxbxnb26tjj.png" alt="husky-with-commitlint" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember when I told you that this CLI has setup husky with commitlint to validate your commit messages if it was conventional or not before commiting so that semantic-release can decide what the next version is based on your commit messages.&lt;/p&gt;

&lt;p&gt;Now let's run a proper conventional commit message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="s2"&gt;"feat: new register message"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you push, go to your repository on github specifically on tha Actions tab and you'll see the same running tests and after they finish, you'll notice something different, semantic-release has bumped the version to &lt;code&gt;1.1.0&lt;/code&gt; and modified the package.json version to sync it with npm, generated a CHANGELOG for you, created a new tag and published a github release for you 🤯&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52vvhwnvhfq38col8m7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52vvhwnvhfq38col8m7m.png" alt="github-actions.png" width="352" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6jre1od0yy709zpzdxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6jre1od0yy709zpzdxx.png" alt="semantic-release-generated-changelog" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WOW! I had a 0.01% chance that someone can read through all of that till the very end. I'm very proud of you, please mention or DM me on twitter and let me know you're one of the 0.01% of people.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>prisma</category>
      <category>generator</category>
    </item>
    <item>
      <title>Typing process.env automatically with this VSC extension</title>
      <dc:creator>Yassin Eldeeb 🦀</dc:creator>
      <pubDate>Sun, 05 Dec 2021 22:17:31 +0000</pubDate>
      <link>https://dev.to/yassineldeeb/typing-processenv-automatically-with-this-vsc-extension-10pe</link>
      <guid>https://dev.to/yassineldeeb/typing-processenv-automatically-with-this-vsc-extension-10pe</guid>
      <description>&lt;p&gt;what's up typescript enthusiasts 👋&lt;br&gt;
tired from writing types for your env variables to get a type-safe version of process.env &lt;a href="https://dev.to/isthatcentered/typing-process-env-and-dealing-with-nodeenv-3ilm"&gt;as seen in this tutorial&lt;/a&gt;?&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;1- Install &lt;code&gt;@types/node&lt;/code&gt; in your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add @types/node &lt;span class="nt"&gt;-D&lt;/span&gt;

// or using npm

&lt;span class="nv"&gt;$ &lt;/span&gt;npm i @types/node &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- First of all, download the VSC extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=YassinEldeeb.env-typings" rel="noopener noreferrer"&gt;TS Env Typings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- Specify &lt;code&gt;env-typings.json&lt;/code&gt; file in the root of your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05tgij9a3qk5sr7jdosg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05tgij9a3qk5sr7jdosg.png" alt="config JSON file in the root directory" width="259" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4- Add &lt;code&gt;path&lt;/code&gt; field to your development &lt;code&gt;.env&lt;/code&gt; file&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvv35jrhdictxezclx1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvv35jrhdictxezclx1z.png" alt="JSON config file" width="800" height="246"&gt;&lt;/a&gt;&lt;br&gt;
and yep! you even have auto-completion in this JSON config too 😎&lt;/p&gt;

&lt;p&gt;That's it, Enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Cool Features 🆒
&lt;/h2&gt;

&lt;p&gt;1- Specify path for the generated output using &lt;code&gt;output&lt;/code&gt; field in the JSON config.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1kjekvysd0c17qu9758.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1kjekvysd0c17qu9758.png" alt="output option in config file" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- Auto detect env variable type so that It can give you a nice example in the intellisense on how to use and parse it.&lt;/p&gt;

&lt;p&gt;so as an example if you've a number env variable It'll tell you to use parseInt to parse it before using it cause env variables are always read as strings.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmbj2gemqke91k0hg85q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmbj2gemqke91k0hg85q.png" alt="example in the intellisense on every env variable" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- Variants for an env variable, so you tell the extension what are the possible values for an env variable so It can generate better types for it and recommend you a nicer example to use&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg86j6aisnllzra8creb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg86j6aisnllzra8creb.png" alt="variants for an env variable" width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to specify Variants in .env file?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;add a comment at the end of the env line that includes "# variants:"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;specify the different variants for your variable seperated by a "|" like you would in typscript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;quotes are optional around the variants values&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpslspgt2jl5x2a05ya5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpslspgt2jl5x2a05ya5g.png" alt="Specify Variants in .env file" width="800" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;If you liked the extension, please give it a &lt;a href="https://github.com/YassinEldeeb/Env-Typings-VSC" rel="noopener noreferrer"&gt;star here 🌟&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you've a great day, curios to see your feedback 🤗&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>vscode</category>
      <category>processenv</category>
    </item>
  </channel>
</rss>
