<?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: Jairo Fernández</title>
    <description>The latest articles on DEV Community by Jairo Fernández (@jairofernandez).</description>
    <link>https://dev.to/jairofernandez</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%2F295346%2Fa264c1d7-4e66-4342-b0a3-22e972dd7064.png</url>
      <title>DEV Community: Jairo Fernández</title>
      <link>https://dev.to/jairofernandez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jairofernandez"/>
    <language>en</language>
    <item>
      <title>🚀 FNPM Just Became Invisible (In the Good Way): Transparent Alias, Better Tests &amp; a Smoother Experience</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Fri, 14 Nov 2025 07:47:36 +0000</pubDate>
      <link>https://dev.to/jairofernandez/fnpm-just-became-invisible-in-the-good-way-transparent-alias-better-tests-a-smoother-2af</link>
      <guid>https://dev.to/jairofernandez/fnpm-just-became-invisible-in-the-good-way-transparent-alias-better-tests-a-smoother-2af</guid>
      <description>&lt;p&gt;There are moments when you stop, look at your terminal, and think:&lt;br&gt;&lt;br&gt;
&lt;em&gt;“Why does something as simple as managing packages in JavaScript has to be… so dramatic?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've been around the Node.js ecosystem for more than 5 minutes, you know exactly what I mean.&lt;/p&gt;

&lt;p&gt;Well, &lt;strong&gt;FNPM just got its biggest update ever&lt;/strong&gt;, and no, it’s not “just another technical improvement.” This update is about giving you the experience we all secretly wanted: using your favorite package manager &lt;em&gt;while something way smarter runs behind the scenes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;


&lt;h2&gt;
  
  
  🎭 Before: npm, pnpm, yarn… drama.
&lt;/h2&gt;
&lt;h2&gt;
  
  
  🎉 Now: use whatever you want. FNPM does the hard work.
&lt;/h2&gt;

&lt;p&gt;The biggest change (and my personal favorite) is the new &lt;strong&gt;transparent alias system&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
This means you can now type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…and behind the scenes, &lt;strong&gt;FNPM is actually doing the job&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why is this so massive?&lt;/p&gt;

&lt;p&gt;Because for the first time, an alternative package manager can &lt;em&gt;sneak into&lt;/em&gt; (yeah, sounds weird but it’s beautiful) your workflow &lt;strong&gt;without asking you to change anything&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your team uses &lt;code&gt;pnpm&lt;/code&gt;, perfect.&lt;br&gt;&lt;br&gt;
If you prefer FNPM’s model and how it handles things, also perfect.&lt;br&gt;&lt;br&gt;
If your environment is mixed… well, guess what? It works too.&lt;/p&gt;

&lt;p&gt;FNPM now behaves as a &lt;strong&gt;real drop-in replacement&lt;/strong&gt;, like &lt;em&gt;for real real&lt;/em&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🪄 How does this alias magic works?
&lt;/h2&gt;

&lt;p&gt;FNPM now includes a smart &lt;strong&gt;hook system&lt;/strong&gt; that intercepts the traditional package manager commands and transforms them into FNPM operations.&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It detects what you want (&lt;code&gt;install&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;run&lt;/code&gt;, etc.).
&lt;/li&gt;
&lt;li&gt;It maps it to FNPM’s internal engine.
&lt;/li&gt;
&lt;li&gt;It keeps the CLI experience you already know.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All without breaking scripts, without changing your mental model, and without asking you to learn new commands (because, honestly, nobody wants that anymore 😅).&lt;/p&gt;


&lt;h2&gt;
  
  
  🧪 Better test coverage (and now &lt;em&gt;actually&lt;/em&gt; cross-platform)
&lt;/h2&gt;

&lt;p&gt;Another big step forward is the &lt;strong&gt;improved test coverage&lt;/strong&gt;, which now behaves consistently across systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux
&lt;/li&gt;
&lt;li&gt;macOS
&lt;/li&gt;
&lt;li&gt;Windows (yes, Windows got some love this time 😎)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Error messages, symlink behavior, path formatting… all those cross-platform headaches?&lt;br&gt;&lt;br&gt;
FNPM now handles them.&lt;/p&gt;

&lt;p&gt;This means FNPM isn’t just “usable” on Windows —&lt;br&gt;&lt;br&gt;
it’s &lt;strong&gt;reliable&lt;/strong&gt;, &lt;strong&gt;predictable&lt;/strong&gt;, and &lt;strong&gt;CI-friendly&lt;/strong&gt; across all platforms.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ Other cool improvements worth mentioning
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;New &lt;code&gt;fnpm source&lt;/code&gt; command for shell integration
&lt;/li&gt;
&lt;li&gt;GitHub Workflows + issue templates for better contributing
&lt;/li&gt;
&lt;li&gt;Updated dependencies (thanks Dependabot 💚)
&lt;/li&gt;
&lt;li&gt;Cleaner project structure with better dev tooling
&lt;/li&gt;
&lt;li&gt;A more complete test suite for future expansions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FNPM keeps growing with a focus on simplicity + power, not complexity.&lt;/p&gt;


&lt;h2&gt;
  
  
  🪄 A real example: turning &lt;code&gt;pnpm&lt;/code&gt; into FNPM (without anyone noticing)
&lt;/h2&gt;

&lt;p&gt;Here’s a real example of how easy this is.&lt;br&gt;&lt;br&gt;
I swear the first time you run it, you’ll feel that “oh wow” moment 😅.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; ➜  awesome-project fnpm setup pnpm  
Selected package manager: pnpm  

🎉 FNPM hooks created successfully!

Setup Instructions:  
Unix/Linux/macOS:  
  1. Source the setup script:  
     &lt;span class="nb"&gt;source&lt;/span&gt; .fnpm/setup.sh  
  2. Or add to your shell profile &lt;span class="o"&gt;(&lt;/span&gt;~/.bashrc, ~/.zshrc&lt;span class="o"&gt;)&lt;/span&gt;:  
     &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'eval "$(fnpm source)"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc  

Usage:  
  • Now you can use pnpm directly:  
    pnpm add some-package  
    pnpm &lt;span class="nb"&gt;install  
    &lt;/span&gt;pnpm run my-script  
  • Commands will be automatically redirected to fnpm  

Note:  
  • Hooks only work &lt;span class="k"&gt;in &lt;/span&gt;directories with .fnpm configuration  
  • Use full path to bypass: &lt;span class="si"&gt;$(&lt;/span&gt;which pnpm&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; ➜  awesome-project &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'eval "$(fnpm source)"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now try any &lt;code&gt;pnpm&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; ➜  awesome-project pnpm &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;🔄 This pnpm &lt;span class="nb"&gt;command &lt;/span&gt;is intercepted by FNPM  
Available commands:  
  &lt;span class="nb"&gt;install&lt;/span&gt;, add, remove, run, list, update, cache, clean  

Use &lt;span class="s1"&gt;'fnpm --help'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;more information  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔥 Boom.&lt;br&gt;&lt;br&gt;
From that moment on, you keep using &lt;code&gt;pnpm&lt;/code&gt; like always…&lt;br&gt;&lt;br&gt;
but FNPM is the one doing the heavy lifting behind the curtain.&lt;/p&gt;

&lt;p&gt;No workflow changes.&lt;br&gt;&lt;br&gt;
No broken scripts.&lt;br&gt;&lt;br&gt;
No new habits.&lt;br&gt;&lt;br&gt;
Just smooth developer life.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ In short: FNPM is no longer “used”… it’s &lt;em&gt;felt&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;With this transparent alias system, FNPM stops being a command you remember to type, and becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast
&lt;/li&gt;
&lt;li&gt;consistent
&lt;/li&gt;
&lt;li&gt;cross-platform
&lt;/li&gt;
&lt;li&gt;and completely invisible when you want it to be
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it was useful before, now it feels… &lt;em&gt;kinda magical&lt;/em&gt;, honestly.&lt;/p&gt;




&lt;h3&gt;
  
  
  🤖 PS: we used AI to help us write this article — because great tools deserve great storytelling.
&lt;/h3&gt;

&lt;p&gt;🙌🏼&lt;a href="https://fnpm-docs.vercel.app/" rel="noopener noreferrer"&gt;Documentation here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>pnpm</category>
      <category>fnpm</category>
      <category>node</category>
    </item>
    <item>
      <title>FNPM: The Package Manager Drama Ends Here 🚀</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Thu, 13 Feb 2025 07:16:26 +0000</pubDate>
      <link>https://dev.to/jairofernandez/fnpm-the-package-manager-drama-ends-here-4i0f</link>
      <guid>https://dev.to/jairofernandez/fnpm-the-package-manager-drama-ends-here-4i0f</guid>
      <description>&lt;h3&gt;
  
  
  FNPM: The Package Manager Drama Ends Here 🚀
&lt;/h3&gt;

&lt;p&gt;Hey devs! 👋 Tired of the endless debates over package managers? Ever wished for a solution that brings peace to the package manager wars? Meet FNPM – because life's too short for package manager drama! 😅&lt;/p&gt;

&lt;p&gt;I work at &lt;a href="https://konstruct.io" rel="noopener noreferrer"&gt;Konstruct.io&lt;/a&gt; we have free Fridays, and this idea was stuck in my mind for a while. I finally took advantage of AI to bring it to life! 🚀 So please give us ⭐️ on &lt;a href="https://github.com/konstructio/kubefirst" rel="noopener noreferrer"&gt;konstructio/kubefirst&lt;/a&gt;, a great and amazing way to setup your kubernetes infrastructure following gitOps Philosophy.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is FNPM? 🤔
&lt;/h4&gt;

&lt;p&gt;FNPM stands for &lt;strong&gt;Fuck NPM&lt;/strong&gt;. It's a tool designed to end the eternal conflicts between npm, yarn, pnpm, and others by supporting them all seamlessly. Think of it as the peace treaty in the package manager soap opera. 🕊️&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Should You Care? 🤓
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Universal Support 🌐&lt;/strong&gt; – FNPM supports multiple package managers, including npm, yarn, pnpm, bun, and deno. Use your favorite; FNPM has your back!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One Lock File to Rule Them All 🔒&lt;/strong&gt; – No more lock file conflicts! FNPM ensures consistent dependencies across your team, regardless of individual preferences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Happy CI/CD 😊&lt;/strong&gt; – Standardized workflows and consistent builds mean no more "works on my machine" excuses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team Harmony 🤝&lt;/strong&gt; – Let developers be developers. Stop the package manager wars and focus on building awesome stuff!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to Get Started 🏁
&lt;/h4&gt;

&lt;p&gt;Getting FNPM up and running is super simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/ideascoldigital/fnpm/refs/heads/main/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, just use it like you would with your preferred package manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fnpm setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And boom! 💥 Your dependencies are managed without the drama. 🎉&lt;/p&gt;

&lt;h4&gt;
  
  
  Basic Commands 📜
&lt;/h4&gt;

&lt;p&gt;Here's a quick reference of basic commands supported across all package managers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;FNPM Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install dependencies&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs all project dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add a package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm add &amp;lt;package&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds a new package to your project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove a package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm remove &amp;lt;package&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes a package from your project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm update&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Updates packages to their latest versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run a script&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm run &amp;lt;script&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs a script defined in package.json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean cache&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm clean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cleans the package manager cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fnpm list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lists installed packages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Final Thoughts 💡
&lt;/h4&gt;

&lt;p&gt;FNPM is here to bring harmony to your development workflow. It's easy to install, easy to use, and might just save you from the package manager drama. 🕰️💻&lt;/p&gt;

&lt;p&gt;Check out the official docs here 👉 &lt;a href="https://fnpm-docs.vercel.app/" rel="noopener noreferrer"&gt;FNPM Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you tried FNPM? Let me know what you think! 🚀✨&lt;/p&gt;

</description>
      <category>node</category>
      <category>yarn</category>
      <category>pnpm</category>
      <category>fucknpm</category>
    </item>
    <item>
      <title>The sad story of node update!</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Wed, 14 Aug 2024 00:37:19 +0000</pubDate>
      <link>https://dev.to/jairofernandez/the-sad-story-of-node-update-21gd</link>
      <guid>https://dev.to/jairofernandez/the-sad-story-of-node-update-21gd</guid>
      <description>&lt;p&gt;Yesterday, I was happily finishing an upgrade at work, and everything seemed perfect 😄. All the dependencies migrated smoothly, and my npm audit looked great 🚀. But then…&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%2F3xvlg53wmek6q1ers7x0.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%2F3xvlg53wmek6q1ers7x0.png" alt=" " width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Server-Side Request Forgery in axios ⚠️&lt;br&gt;
&lt;a href="https://github.com/advisories/GHSA-8hc4-vh64-cxmj" rel="noopener noreferrer"&gt;https://github.com/advisories/GHSA-8hc4-vh64-cxmj&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr641p36716xifmrkx29g.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%2Fr641p36716xifmrkx29g.png" alt=" " width="445" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I spent a lot of time fixing things, only to see that stupid message 😡. My OCD was driving me crazy 🤯.&lt;/p&gt;




&lt;p&gt;And, I said, hmmm how exactly this error works? what the hell is SSRF? I'll try to explain fast the concept and share with you the discovery :D &lt;/p&gt;

&lt;p&gt;SSRF, or Server-Side Request Forgery, is like tricking your server into being an unintentional errand boy 🕵️‍♂️. It’s when a hacker gets your server to make requests to places it shouldn’t, kind of like sending your dog to fetch a stick but it comes back with a bomb instead 💣. (from ChatGPT 😍)&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;In code please!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Normally, axios works, in your server when you need to do some external request to &lt;a href="https://some-domain.com/api/" rel="noopener noreferrer"&gt;https://some-domain.com/api/&lt;/a&gt;, you can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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;In theory, this is our innocent and pure server meant to fetch resources from jsonplaceholder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/fetch-data&lt;/span&gt;&lt;span class="dl"&gt;'&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;URL:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error fetching data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&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;message&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can try this one on terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3000/fetch-data &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url": "/todos/1"}'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The response is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"delectus aut autem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&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;everything is beautiful, but...&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%2Fqbmr6hdc7a09a8tilwct.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%2Fqbmr6hdc7a09a8tilwct.png" alt=" " width="195" height="259"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now, if you have another server (acting as a malicious server) on &lt;code&gt;http://localhost:4000&lt;/code&gt;, what happens when the user tests it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/private-data&lt;/span&gt;&lt;span class="dl"&gt;'&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Private URL:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WTF??????&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data fetched&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;catch &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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;URL:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error fetching data&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3000/fetch-data &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url": "//localhost:4000/private-data"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will get this response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;:&lt;span class="s2"&gt;"Data fetched"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="c"&gt;# data from other server!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“So, this is really bad 😱 because you’re trusting the axios instance. The good news is that within a day, the issue in axios was successfully fixed in version 1.7.4 🎉.”&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;If you want to play with this, please check the experiment here 👇 &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/ssrf-axios-1-7?embed=1&amp;amp;file=README.md&amp;amp;hideNavigation=1&amp;amp;view=editor" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>security</category>
      <category>node</category>
      <category>axios</category>
    </item>
    <item>
      <title>Docker is destroying my machine! 💥</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Fri, 26 Jul 2024 01:52:20 +0000</pubDate>
      <link>https://dev.to/jairofernandez/docker-is-destroying-my-machine-53p4</link>
      <guid>https://dev.to/jairofernandez/docker-is-destroying-my-machine-53p4</guid>
      <description>&lt;p&gt;Other possible titles for this post&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“RTFM, oh boy…”&lt;br&gt;
Buy a new laptop…&lt;br&gt;
Saving Private Ryan, where are you daemon.json?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I need to reconsider the use of Docker on my Mac M1 Pro. With a small disk and 1000 programs 😅, everything is fine at least until I start Docker Desktop. I use a lot of images and experiments that I never finish because I’m a lazy person. I was looking for some solution because my machine is crying all the time, and I feel like a loser deleting files, running docker system prune, and deleting my 1 million node modules from unfinished projects…&lt;/p&gt;

&lt;p&gt;I have an old machine that I just use to do some experiments or run Windows for specific tasks or problems. That machine has Ubuntu and Windows as a dual boot. Yes, it’s a Frankenstein, and I feel nostalgic about Ubuntu.&lt;/p&gt;

&lt;p&gt;— Sheldon: “Oh, Ubuntu!”&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%2Fgjdsh7x7sd8b64h9hopu.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%2Fgjdsh7x7sd8b64h9hopu.png" alt=" " width="800" height="1105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, give me the 💩 solution. &lt;/p&gt;

&lt;p&gt;I installed Docker on Ubuntu, allowed remote connection, and overrode the Docker client host to point to my old machine, and voila!&lt;/p&gt;

&lt;p&gt;Or at least, I thought it was really easy to do. I checked the internet and ChatGPT told me to edit /etc/docker/daemon.json on my Ubuntu machine and just put:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2376"
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy peasy…&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%2Foqkwt736bzehm425y5vv.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%2Foqkwt736bzehm425y5vv.png" alt=" " width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No, that broke my Docker on Ubuntu (24.04 LTS).&lt;/p&gt;

&lt;p&gt;After a couple of hours and going through a lot of tutorials, I found the documentation!! (Yes, RTFM) &lt;a href="https://docs.docker.com/config/daemon/remote-access/" rel="noopener noreferrer"&gt;https://docs.docker.com/config/daemon/remote-access/&lt;/a&gt; and finally understood why I couldn’t find the file. It was a misunderstanding of how Docker runs on the OS and the changes of Ubuntu to systemd.&lt;/p&gt;

&lt;p&gt;For systemd we need to edit the service with &lt;code&gt;sudo systemctl edit docker.service&lt;/code&gt;, as the documentation said, but, oh surprise, it didn’t work for me…&lt;/p&gt;

&lt;p&gt;So, what happened was I needed to edit the service file directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /lib/systemd/system/docker.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I commented out the lines containing ExecStart below [Service], and added these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I restarted the service with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl daemon-reload
sudo systemctl restart docker.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to confirm if port 2375 is accessible on your local network (this is another story; on my machine, it was available by default).&lt;/p&gt;

&lt;p&gt;For now, that’s all on Ubuntu. Now, on the Mac, Docker doesn’t start on login, so when I run docker ps on the terminal, you’ll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps      
Cannot connect to the Docker daemon at unix:///Users/your_user/.docker/run/docker.sock. Is the docker daemon running?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s ok. Now for the magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export DOCKER_HOST=tcp://&amp;lt;UBUNTU_LOCAL_IP&amp;gt;:2375
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where UBUNTU_LOCAL_IP is the IP of your Ubuntu machine on the same network. Now, if you are on the same network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it! Enjoy! 🎉&lt;/p&gt;

&lt;p&gt;Please consider the security consequences of using this over your local network.&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>CLI Maker: More Than We See</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Wed, 24 Jul 2024 02:25:15 +0000</pubDate>
      <link>https://dev.to/jairofernandez/-cli-maker-more-than-we-see-3gk4</link>
      <guid>https://dev.to/jairofernandez/-cli-maker-more-than-we-see-3gk4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Build your ideas so fast! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@ideascol/cli-maker" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@ideascol/cli-maker&lt;/a&gt;&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;npx&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ideascol&lt;/span&gt;&lt;span class="sr"&gt;/cli-make&lt;/span&gt;&lt;span class="err"&gt;r
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are creating and improving cli-maker, and when I showed my partner the latest version, he said to me, “Hey man, you can’t see this advantage directly by looking at the create command or checking the readme.” So, I decided to write this simple and short (I hope) article. ✍️📄&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete and simple CI configured 🚀
&lt;/h3&gt;

&lt;p&gt;You just need to add a secret NPM_TOKEN to your repository. Now, when you create a PR on Github, you’ll see the testing job running on the actions tab. When you merge or push code to the main branch, you will see 2 jobs: testing and publish job (for publishing, you need to change your package.json version manually).&lt;br&gt;
I think it’s great to see that configuration without any effort. 👍✨&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Library exportable to npm 📦
&lt;/h3&gt;

&lt;p&gt;Your library is usable (folder src/lib) using an import like this: &lt;code&gt;import { AwesomeThing } from '@company/your-library'&lt;/code&gt; 📚&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic binary CLI 🛠️
&lt;/h3&gt;

&lt;p&gt;Your library, of course, is usable using &lt;code&gt;npx @company/your-library&lt;/code&gt;. Your users will have access to your functionalities so fast! ⚡&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup unit testing without any extra dependencies 🧪
&lt;/h3&gt;

&lt;p&gt;Testing in Node.js, or in general JavaScript, is totally broken for me. Jest, Mocha, any new flavors, it’s a terrible thing (yes Jest, forgive me, you know how I love you). In Node.js 20, we finally have native testing (&lt;a href="https://nodejs.org/docs/latest-v20.x/api/test.html" rel="noopener noreferrer"&gt;test runner Node.js 20 LTS&lt;/a&gt;). 🥳🎉&lt;/p&gt;




&lt;p&gt;So, that’s it! I hope you enjoy and check it out for yourself. 🙌😊&lt;/p&gt;

</description>
      <category>cli</category>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>Create a simple CLI, a mess</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Sat, 20 Jul 2024 20:44:11 +0000</pubDate>
      <link>https://dev.to/jairofernandez/create-a-simple-cli-a-mess-2g7j</link>
      <guid>https://dev.to/jairofernandez/create-a-simple-cli-a-mess-2g7j</guid>
      <description>&lt;p&gt;In all my different jobs and personal projects, whenever I needed to create some kind of console application for any purpose, I always started from scratch. I used bash scripting, Cobra (Golang), Commander.js (Node.js), and even Dart and PHP. However, I always ended up with a bad taste in my mouth. Why? Starting the process is terrible 😩 (I guess the best starting point is with Cobra 😅). Checking the structure, discussing the correct place for the code, or simply putting all the code into a copy-paste example with 1000 options turns this simple task into a mess… 🤯&lt;/p&gt;

&lt;p&gt;Aha, I decided to contribute to the chaos by creating my own library in Node.js. However, I have a strong stance about &lt;code&gt;node_modules&lt;/code&gt;, I haven’t felt good about the huge size for simple things: too many testing frameworks, compilers, etc. I recently heard about Node.js LTS (20), which allows you to use the native testing library. I thought, I can support &lt;code&gt;typeScript&lt;/code&gt; and &lt;code&gt;@types/node&lt;/code&gt; as dev dependencies. It’s not perfect, but it’s just two dependencies.&lt;/p&gt;

&lt;p&gt;The next challenge for me was configuring the CI, unit testing, and dealing with the garbage produced by GPT-4 trying to help me create this as an experiment, which ended really well 😅. (Don’t kill me in the future, AI, I am faithful to the machine cause 🤖.) But I need to recognize that this work would have been impossible to do without using GPT-4o in just one week! After my normal job, with a lot of coffee ☕, so thanks, GPT-4o! 😄&lt;/p&gt;

&lt;p&gt;Which characteristics do I need from a &lt;code&gt;CLI maker&lt;/code&gt;, that is the name of the library&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I need to start from zero with just one command; I hate to copy, paste, and rethink the same stupid things 🤦‍♂️&lt;/li&gt;
&lt;li&gt;I need a simple structure supporting TypeScript.&lt;/li&gt;
&lt;li&gt;I need a simple CI with GitHub Actions automatically set up.&lt;/li&gt;
&lt;li&gt;I need the CLI exportable automatically.&lt;/li&gt;
&lt;li&gt;I need to use my library like a simple package with and &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;import&lt;/code&gt; in other parts.&lt;/li&gt;
&lt;li&gt;I need support for an interactive CLI. I love the &lt;a href="https://symfony.com/" rel="noopener noreferrer"&gt;Symfony&lt;/a&gt; terminal—interactive, fast, great UX or something similar to &lt;a href="https://github.com/charmbracelet/gum" rel="noopener noreferrer"&gt;Gum&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I need to use the CLI in a direct mode passing the parameters.&lt;/li&gt;
&lt;li&gt;I need simple types, I want to add emails, url, list and use them easily&lt;/li&gt;
&lt;li&gt;I don’t want to configure 1 million dev dependencies&lt;/li&gt;
&lt;li&gt;I want to see my commands and not want to vomit because of the mess 🤢&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yeah, I'm not picky,  but I wanted something like this for myself 😅.&lt;/p&gt;

&lt;p&gt;So, hands of work, I would like to present you &lt;code&gt;cli-maker&lt;/code&gt; my own version of the hell, just execute this command and check the magic,&lt;/p&gt;

&lt;p&gt;Go to an empty directory and use Node 20 (I’ll add this validation, I promise you 😉)&lt;/p&gt;

&lt;p&gt;Go to library if you want to skip this lecture &lt;a href="https://www.npmjs.com/package/@ideascol/cli-maker" rel="noopener noreferrer"&gt;npm @ideascol/cli-maker&lt;/a&gt;&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;npx&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ideascol&lt;/span&gt;&lt;span class="sr"&gt;/cli-make&lt;/span&gt;&lt;span class="err"&gt;r
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it, you will see the usual installation process. Please be patient 😊.&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%2Fbih2g2mru1rjmmmhk0w3.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%2Fbih2g2mru1rjmmmhk0w3.png" alt=" " width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trust me, proceed… 😉&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%2Fob9wrrfg5v52bifihm42.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%2Fob9wrrfg5v52bifihm42.png" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For now, I just have one command—the only one needed for now. Please proceed in an empty folder and fill in the data 😊.&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%2Flatfcfx0xuv5cvd0dh2z.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%2Flatfcfx0xuv5cvd0dh2z.png" alt=" " width="584" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Right! Now, create your own CLI 🚀.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ideascol&lt;/span&gt;&lt;span class="sr"&gt;/cli-maker creat&lt;/span&gt;&lt;span class="err"&gt;e
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fddehp84u47lym9bp96fd.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%2Fddehp84u47lym9bp96fd.png" alt=" " width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill data&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%2F09e8k4cx7mfeed2jphzr.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%2F09e8k4cx7mfeed2jphzr.png" alt=" " width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If all was good, you’ll see this:&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%2F65urv2y82knriijuvou5.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%2F65urv2y82knriijuvou5.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me explain to you in the next article how we can extract the best from this simple library… 📚✨&lt;/p&gt;

&lt;p&gt;See you! 👋&lt;/p&gt;

&lt;p&gt;Check the next &lt;a href="https://dev.to/jairofernandez/-cli-maker-more-than-we-see-3gk4"&gt;cli-maker-more-than-we-see&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Has tu README realmente útil</title>
      <dc:creator>Jairo Fernández</dc:creator>
      <pubDate>Thu, 30 May 2024 02:13:42 +0000</pubDate>
      <link>https://dev.to/jairofernandez/has-tu-readme-realmente-util-49ea</link>
      <guid>https://dev.to/jairofernandez/has-tu-readme-realmente-util-49ea</guid>
      <description>&lt;h2&gt;
  
  
  Has tu README realmente útil
&lt;/h2&gt;

&lt;p&gt;Muchas veces, el readme se vuelve un poco tedioso, y en ocasiones he preferido usar y abusar de scripts bash, para automatizar procesos, sin embargo, a veces puede resultar un poco difícil mantener ambas cosas, sobre todo en proyectos donde el cambio está a la orden del día, entonces, me encontré con una herramienta que ayuda a convertir los files markdown en obras maestras, muy similar a como usaríamos un Jupyter notebook!&lt;/p&gt;

&lt;h3&gt;
  
  
  manos a la obra,
&lt;/h3&gt;

&lt;p&gt;La herramienta se llama &lt;a href="https://runme.dev/" rel="noopener noreferrer"&gt;runme&lt;/a&gt;, y básicamente tiene 4 modos de uso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Con tu editor, por ahora solo con Vscode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vía terminal, donde puedes directamente ejecutar un comando de tu README (ya lo veremos!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vía terminal pero abriendo un servidor web, que “oh sorpresa”, es un Vscode corriendo en tu navegador.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vía extensión web.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Veamos un ejemplo
&lt;/h3&gt;

&lt;p&gt;Usando la extensión de Vscode: &lt;a href="https://marketplace.visualstudio.com/items?itemName=stateful.runme" rel="noopener noreferrer"&gt;Runme DevOps Notebooks&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%2Fwxaumyjbgchvuk6acjy9.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%2Fwxaumyjbgchvuk6acjy9.png" alt="start" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al presionar allí empezarás a ver la magia&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%2Fh8i9o97uzxvik6dxnkmb.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%2Fh8i9o97uzxvik6dxnkmb.png" alt="Magic" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notarás que al acercar el mouse a una celda (sí, cada sección se llama celda como en los Jupyter notebooks)&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%2Ffetp1ev66mjslal8104i.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%2Ffetp1ev66mjslal8104i.png" alt="button section" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En nuestro caso, vamos a empezar con algo sencillo, escribiremos el comando&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uname -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Y al ejecutar veremos como la salida de la terminal queda directamente en nuestro README&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%2Fkb2w6vh5c9c4y68wvm6h.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%2Fkb2w6vh5c9c4y68wvm6h.png" alt="execution" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veamos todo junto con un ejemplo más grande como se ejecuta&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%2Frnuq4j74uzxq1acy4h3w.gif" 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%2Frnuq4j74uzxq1acy4h3w.gif" alt="all" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando su extensión
&lt;/h2&gt;

&lt;p&gt;Sigue las instrucciones para instalarla [aquí], y si vas al repositorio donde tengo el código del ejemplo anterior,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jairoFernandez/articles/tree/main/readme-powers" rel="noopener noreferrer"&gt;https://github.com/jairoFernandez/articles/tree/main/readme-powers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verás un botón que te dará un link de esta forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://runme.dev/api/runme?repository=https%3A%2F%2Fgithub.com%2FjairoFernandez%2Farticles.git&amp;amp;fileToOpen=readme-powers%2FREADME.md" rel="noopener noreferrer"&gt;https://runme.dev/api/runme?repository=https%3A%2F%2Fgithub.com%2FjairoFernandez%2Farticles.git&amp;amp;fileToOpen=readme-powers%2FREADME.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto abrirá tu vscode y te permitirá ejecutar el Readme.&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>markdown</category>
      <category>documentation</category>
      <category>runme</category>
    </item>
  </channel>
</rss>
