<?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: Mohamed ELIDRISSI</title>
    <description>The latest articles on DEV Community by Mohamed ELIDRISSI (@elidrissidev).</description>
    <link>https://dev.to/elidrissidev</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%2F634304%2F8f805f85-7c0d-4793-9e36-672fd3eaeab2.jpeg</url>
      <title>DEV Community: Mohamed ELIDRISSI</title>
      <link>https://dev.to/elidrissidev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elidrissidev"/>
    <language>en</language>
    <item>
      <title>Exploring the Most Commonly Used Folder Names in Popular NPM Packages</title>
      <dc:creator>Mohamed ELIDRISSI</dc:creator>
      <pubDate>Thu, 23 Feb 2023 13:33:50 +0000</pubDate>
      <link>https://dev.to/elidrissidev/exploring-the-most-commonly-used-folder-names-in-popular-npm-packages-4332</link>
      <guid>https://dev.to/elidrissidev/exploring-the-most-commonly-used-folder-names-in-popular-npm-packages-4332</guid>
      <description>&lt;p&gt;I was listening to &lt;a href="https://syntax.fm/show/575/save-us-from-config-file-hell" rel="noopener noreferrer"&gt;Episode 575 of Syntax podcast&lt;/a&gt; last week &lt;br&gt;
when I heard Wes talk about an idea he had for the show. It was about writing a script that will fetch 8000 repos and analyze &lt;br&gt;
the most common directories and then explain the purpose of each one. I thought it would be interesting to try this with NPM packages and share the result, so here it is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Collecting the data
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🏗️ Building a list of the most popular NPM packages
&lt;/h3&gt;

&lt;p&gt;The first step is to gather the data from a significant number of NPM packages, this seemed easy at first because I was planning to use the &lt;a href="https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get-v1search" rel="noopener noreferrer"&gt;NPM Registry API&lt;/a&gt; &lt;br&gt;
to get this information, but it doesn't seem to allow searching by popularity alone. So I'm going to have to use a &lt;a href="https://gist.github.com/elidrissidev/36e17a5f1206a656848eff086a3519e4#file-packages-json" rel="noopener noreferrer"&gt;manually curated list of popular packages&lt;/a&gt; for this purpose 🤷‍♂️.&lt;/p&gt;
&lt;h3&gt;
  
  
  📁 Fetching the folder structure of each package
&lt;/h3&gt;

&lt;p&gt;Now that we have the list of packages, we will need the repository URL of each one to get their directory structure. To accomplish this, I'm going to hit the NPM Registry API to retrieve the data about each package which should contain the repository URL, then I will request the GitHub REST API to get the contents of the root folder:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;packages&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./packages.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;json&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;NPM_REGISTRY_API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://registry.npmjs.com&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;GITHUB_API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.github.com&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;pkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;packages&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="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&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;NPM_REGISTRY_API_URL&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="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;repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;pkgs&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;pkg&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;githubUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;repoNamespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;githubUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;git$/i&lt;/span&gt;&lt;span class="p"&gt;,&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="nf"&gt;fetch&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;GITHUB_API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/repos&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;repoNamespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/contents`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="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;
  
  
  📊 Counting the directories
&lt;/h3&gt;

&lt;p&gt;We now have a two-dimensional array representing the contents of every package, the last step is to filter out individual files and aggregate the result to count the occurence of every directory:&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;directories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&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;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;directories&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;dir&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;directories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&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;count&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;count&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've made the full code available in a &lt;a href="https://gist.github.com/elidrissidev/36e17a5f1206a656848eff086a3519e4" rel="noopener noreferrer"&gt;gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's time to take a look at the result!&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyzing the data
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwixzss16b7nl4tqnzhp6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwixzss16b7nl4tqnzhp6.jpg" alt="A Bar Chart that shows the mapping between the folder names and their count"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above chart is enough to give you an idea about the most common directories, but we're interested in more than just numbers, &lt;br&gt;
so let's dive deep and explain what's in each folder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;.github&lt;/code&gt;: With more than 60 occurrence, it's not surprising to see this folder on the top spot given that all of the analyzed packages are &lt;br&gt;
hosted on GitHub. &lt;code&gt;.github&lt;/code&gt; is a special folder that can contain a variety of config files and templates related to &lt;a href="https://docs.github.com/en/actions/using-workflows/about-workflows" rel="noopener noreferrer"&gt;GitHub Actions workflows&lt;/a&gt;, &lt;br&gt;
as well as other organizational files for a GitHub repository such as &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;, &lt;code&gt;CODE_OF_CONDUCT.md&lt;/code&gt;, &lt;code&gt;SECURITY.md&lt;/code&gt; and more. &lt;a href="https://github.com/axios/axios/tree/v1.x/.github" rel="noopener noreferrer"&gt;Example from &lt;code&gt;axios&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tests&lt;/code&gt;/&lt;code&gt;test&lt;/code&gt;/&lt;code&gt;__tests__&lt;/code&gt;: Writing tests is an important practice in software development, and in NPM packages you'll often see them &lt;br&gt;
stored in one of these folders. It can also be used to hold testing helpers and utility functions. &lt;a href="https://github.com/auth0/node-jsonwebtoken/tree/master/test" rel="noopener noreferrer"&gt;Example from &lt;code&gt;express&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;docs&lt;/code&gt;: Documentation is an essential part of any package, as it provides users with the information they need to understand how to use it &lt;br&gt;
and how it works. The documentation usually includes usage instructions, API documentation, and more. It can also be included directly &lt;br&gt;
in the repository's &lt;code&gt;README.md&lt;/code&gt; file, but it's often split into multiple files and stored in this folder for ease of navigation and maintenance. &lt;br&gt;
Although the documentation files can be in any format, the most common one is &lt;a href="https://en.wikipedia.org/wiki/Markdown" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt;. &lt;a href="https://github.com/node-fetch/node-fetch/tree/main/docs" rel="noopener noreferrer"&gt;Example from &lt;code&gt;node-fetch&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lib&lt;/code&gt;: The &lt;code&gt;lib&lt;/code&gt; folder, short for "library", is mostly used to store the actual source code of the package, but it can also be used to store &lt;br&gt;
third-party code, utilities and helpers. &lt;a href="https://github.com/jaredhanson/passport/tree/master/lib" rel="noopener noreferrer"&gt;Example from &lt;code&gt;passport&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;examples&lt;/code&gt;: Good documentation goes well with good examples, not only does it provide a practical demonstration on how to use the package, but it also &lt;br&gt;
allows developers to quickly get up to speed and start using the package in their own projects. &lt;a href="https://github.com/expressjs/express/tree/master/examples" rel="noopener noreferrer"&gt;Example from &lt;code&gt;express&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src&lt;/code&gt;: Similar to &lt;code&gt;lib&lt;/code&gt;, the &lt;code&gt;src&lt;/code&gt; folder is also used to organize code, allowing for easy access to the main codebase. &lt;a href="https://github.com/eemeli/yaml/tree/master/src" rel="noopener noreferrer"&gt;Example from &lt;code&gt;yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;scripts&lt;/code&gt;: Maintaining a package can be a lot of work, there's lots of repetitive tasks that need to be done often such as building the package for &lt;br&gt;
different targets, preparing a new release, etc. This is where automation scripts can help, and if a package has any, there's a good chance you'll find &lt;br&gt;
them in this folder. &lt;a href="https://github.com/remix-run/history/tree/dev/scripts" rel="noopener noreferrer"&gt;Example from &lt;code&gt;history&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;packages&lt;/code&gt;: If you see a directory with this name, you're most likely looking at a &lt;a href="https://en.wikipedia.org/wiki/Monorepo" rel="noopener noreferrer"&gt;monolithic repository&lt;/a&gt; &lt;br&gt;
(monorepo). Monorepos contain the code for different projects/sub-components within a single repository, this offers several benefits such as simplified &lt;br&gt;
dependency management, and improved code reusability to name a few.  &lt;a href="https://github.com/facebook/react/tree/main/packages" rel="noopener noreferrer"&gt;Example from &lt;code&gt;react&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;bin&lt;/code&gt;: Sometimes it may be desired or even crucial for a package to provide a command line interface, take a testing framework &lt;br&gt;
like &lt;code&gt;jest&lt;/code&gt; as an example. NPM allows packages to &lt;a href="https://docs.npmjs.com/cli/v9/configuring-npm/package-json?v=true#bin" rel="noopener noreferrer"&gt;publish&lt;/a&gt; executable binaries &lt;br&gt;
for this purpose, and as a convention they're usually placed in this directory. &lt;a href="https://github.com/ai/nanoid/tree/main/bin" rel="noopener noreferrer"&gt;Example from &lt;code&gt;nanoid&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;benchmarks&lt;/code&gt;: This directory contains benchmark tests that help measure the performance of the package's code, these tests can be are very useful &lt;br&gt;
when experimenting with performance optimizations, and to ensure no slowdowns are introduced between releases. &lt;a href="https://github.com/graphql/graphql-js/tree/main/benchmark" rel="noopener noreferrer"&gt;Example from &lt;code&gt;graphql&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;.husky&lt;/code&gt;: Git &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks" rel="noopener noreferrer"&gt;hooks&lt;/a&gt; are custom scripts that run in response to some event (e.g. before a &lt;br&gt;
commit is created), and they can choose to abort that event under certain conditions. One of their main drawbacks though is that they live inside &lt;br&gt;
the &lt;code&gt;.git&lt;/code&gt; folder, which means they cannot be directly versioned like the rest of the project. This folder is used by the popular &lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; &lt;br&gt;
package that makes it possible to include Git hooks with your project and it takes care of installing them to their appropriate location so they &lt;br&gt;
can be detected by Git. &lt;a href="https://github.com/uuidjs/uuid/tree/main/.husky" rel="noopener noreferrer"&gt;Example from &lt;code&gt;uuid&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;I hope this exploration helped you gain insights about the common naming practices and conventions used in the NPM ecosystem of packages, as well as highlight their importance in improving the accessibility and readability of your project. You can use this knowledge if you plan to build your own &lt;br&gt;
package, contribute to an existing one, or simply navigate your way around if you're browsing the source code.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git, A Look Under The Hood - Prologue</title>
      <dc:creator>Mohamed ELIDRISSI</dc:creator>
      <pubDate>Wed, 19 May 2021 20:16:03 +0000</pubDate>
      <link>https://dev.to/elidrissidev/git-a-look-under-the-hood-prologue-3c4m</link>
      <guid>https://dev.to/elidrissidev/git-a-look-under-the-hood-prologue-3c4m</guid>
      <description>&lt;p&gt;Git is a free and open-source Distributed Version Control System (DVCS) initially created by Linus Torvalds in 2005 following the &lt;a href="https://lwn.net/Articles/130746/" rel="noopener noreferrer"&gt;BitKeeper controversy&lt;/a&gt; after none of the existing systems met his needs. Because Linus intended to use it for the Linux Kernel development, Git was designed to take into account performance, distribution, and safeguards against data loss. Fast-forward 16 years later and it is the de facto Version Control System (VCS) for software and an indispensable tool for every Software Engineer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can never understand everything. But, you should push yourself to understand the system.&lt;/p&gt;

&lt;p&gt;- Ryan Dahl (Creator of Node.js)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Git has excellent documentation and even a &lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;free book&lt;/a&gt;, but most people don't bother learning about it and instead only try to memorize the commands they use in their day-to-day work or rely only on GUIs that make everything seem magical, this leads to them peeling their hair in frustration as they start facing all kind of issues (looking at you, merge conflicts!). While one can certainly use Git with just basic knowledge, knowing how it all works under the hood will give you extra confidence and will make you a distinguishable engineer.&lt;/p&gt;

&lt;p&gt;In this series, we will be going down the rabbit hole to try and demystify how Git works internally, and at the end, you'll come to know that &lt;strong&gt;Git is not magic&lt;/strong&gt;, its design model is what made it the powerful tool that we all love and hate (not anymore) today, so we must understand that before going any deeper.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: This is not a beginner's guide so a basic knowledge of Git is required&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Git is Distributed
&lt;/h2&gt;

&lt;p&gt;We hear about Git being a DVCS all the time, but do you really know what that means? Before we understand the meaning of distributed, let's first talk about Centralized VCSs (CVCS).&lt;/p&gt;

&lt;p&gt;In CVCSs, nothing is stored locally, so all actions depend on a single remote repository. To commit code, view the logs, or compare your changes with other people's, you'll need to be online. Being centralized also means having a single point of failure. If the repository is deleted by mistake or the disks on the server crash, everything will be lost.&lt;/p&gt;

&lt;p&gt;Now let's go back to DVCSs, when you do a &lt;code&gt;git clone&lt;/code&gt;, Git downloads the whole history of the repository and stores it in – its local database – the &lt;code&gt;.git&lt;/code&gt; folder. This means that you can still commit your work locally when you're on an airplane or when the internet is down and push it to a remote repository when you're back online, and essentially all developers who cloned this repository now have a backup in their machine. This also has the benefit of being extremely fast, as most operations don't need to reach for a server.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsuj3e2duqbw62m529gz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsuj3e2duqbw62m529gz.png" alt="Centralized vs. Decentralized Version Control Systems"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Takes Snapshots
&lt;/h2&gt;

&lt;p&gt;This is one of the key design differences between Git and other VCSs. These other systems store information as an initial file and the changes (diffs) made to it over time, Git follows a different approach and instead takes a snapshot (think a picture) of your whole files when you do a commit, now you might think that's expensive if you have a lot of files, but as we'll come to see in the next part, Git is smart enough to not store the same file twice if it hasn't changed and instead references the previous version of that file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptiux5owlbkcaqgaoj1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptiux5owlbkcaqgaoj1r.png" alt="How Git takes snapshots of your files on each commit (dashed lines represent a reference to the previous version of the file)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important point to get from this is that Git acts like a mini filesystem, but with superpowers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrity is Built-in
&lt;/h2&gt;

&lt;p&gt;Before Git stores any file, it computes a 40 character long hexadecimal string known as a hash that serves as an identifier. To accomplish this, Git uses a popular hashing algorithm called &lt;a href="https://en.wikipedia.org/wiki/SHA-1" rel="noopener noreferrer"&gt;SHA-1&lt;/a&gt;. We'll see how it does it in the next part, but it will look similar to this: &lt;code&gt;a0b65939670bc2c010f4d5d6a0b3e4e4590fb92b&lt;/code&gt;. This makes it impossible for your files to change or get corrupted without Git knowing about it. Note that SHA1 is considered insecure nowadays, especially after Google released &lt;a href="https://shattered.it" rel="noopener noreferrer"&gt;SHAttered&lt;/a&gt; –the first practical collision attack against SHA1– in 2017 and &lt;a href="https://github.com/git/git/blob/master/Documentation/technical/hash-function-transition.txt" rel="noopener noreferrer"&gt;Git is planning to transition to SHA-256&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  File States in Git
&lt;/h2&gt;

&lt;p&gt;All files in a Git repository can either be &lt;strong&gt;modified&lt;/strong&gt;, &lt;strong&gt;staged&lt;/strong&gt;, or &lt;strong&gt;committed&lt;/strong&gt;. Your files go into the first state when git detects that it has changed from the last version (remember the hash?) stored in its database. To save this change, you'll need to commit it, but first, you have to tell Git which changes you want to "prepare" for the next commit. This is accomplished by adding them to the staging area. Once committed, Git takes a snapshot of your files and saves it permanently in its database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhowfre4i0eqob431co6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhowfre4i0eqob431co6l.png" alt="Every file in a Git repository resides either in the working directory, the staging area, or the .git folder."&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This was a short introduction to this series where we will uncover the nitty-gritty details behind Git internals. We started by first understanding the key aspects of the Git design model. In the next part, we'll see how this all comes down together as we discuss Git Objects.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published in my personal blog: &lt;a href="https://www.elidrissi.dev" rel="noopener noreferrer"&gt;The Self-Taught Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
