<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[pnpm - Medium]]></title>
        <description><![CDATA[About the pnpm JavaScript package manager - Medium]]></description>
        <link>https://medium.com/pnpm?source=rss----ec106fa1e865---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>pnpm - Medium</title>
            <link>https://medium.com/pnpm?source=rss----ec106fa1e865---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 17:01:45 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/pnpm" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[pnpm v4.9 comes with command completion!]]></title>
            <link>https://medium.com/pnpm/pnpm-v4-9-comes-with-command-completion-a411715260b4?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/a411715260b4</guid>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Fri, 31 Jan 2020 21:35:22 GMT</pubDate>
            <atom:updated>2020-01-31T21:35:22.042Z</atom:updated>
            <content:encoded><![CDATA[<p>Command completion in bash, zsh, fish is awesome! Unfortunately, even though there are thousands of great command-line tools in the npm registry, I cannot recall any (except the npm CLI) that comes with command completion.</p><p>A few weeks ago <a href="https://github.com/nikoladev">nikoladev</a> suggested to <a href="https://github.com/pnpm/pnpm/issues/2229">implement autompletion in pnpm</a>. After a brief investigation, I have found a brilliant tool that helps with autocompletion of CLI apps written in Node.js. This tool is called <a href="https://github.com/mklabs/tabtab">tabtab</a> and is currently not maintained, so I <a href="https://github.com/pnpm/tabtab">forked it</a> and added autocompletions to pnpm👌.</p><p>To set up autocompletion, just update pnpm to v4.9 and run pnpm install-completion.</p><p>Let’s see what you can do with it.</p><p>Type pnpm &lt;tab-tab&gt; and see all the available commands:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*I7kdDgVQJniKGmgg.png" /></figure><p>Type pnpm remove &lt;tab-tab&gt; and see the list of dependencies currently installed. This also works with pnpm update and pnpm outdated.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*Qyl-X1iFSYtPWqb7.png" /></figure><p>Type pnpm --filter &lt;tab-tab&gt; and see the list of projects in the workspace:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*Fj3uGOxtiBGETTdt.png" /></figure><p>Type pnpm run &lt;tab-tab&gt; and see the list of available scripts:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*-dFVj_M9F231PKDt.png" /></figure><p>Type any command, type tab-tab and see the list of supported options:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*l6OOgYrXmLpCaR4v.png" /></figure><p>Type an option and see the possible values:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/0*2D7o2GK3US_r_P6-.png" /></figure><p>And these are just a few examples! Happy tabbing😃</p><p>In a future version of pnpm we will also add descriptions to completions😍</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a411715260b4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpm-v4-9-comes-with-command-completion-a411715260b4">pnpm v4.9 comes with command completion!</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pnpm vs Yarn: monorepo node_modules]]></title>
            <link>https://medium.com/pnpm/pnpm-vs-yarn-monorepo-node-modules-6c025d50b9bd?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/6c025d50b9bd</guid>
            <category><![CDATA[yarn]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[monorepo]]></category>
            <category><![CDATA[pnpm]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Sun, 04 Nov 2018 20:21:35 GMT</pubDate>
            <atom:updated>2018-11-04T20:21:34.538Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cBYJtpTyJfwOmiCdlQu4xg.png" /></figure><p>Both <a href="https://pnpm.js.org/">pnpm</a> (as of v2.17) and <a href="https://yarnpkg.com/en/">Yarn</a> (as of v1.12) support fast, concurrent installations in monorepos. However, there is a big difference between how they store dependencies in monorepos. Yarn tries to hoist all dependencies from all workspace packages into the root node_modules of the monorepo, which means that packages have access to dependencies of other packages in the workspace. This is described in the <a href="https://yarnpkg.com/lang/en/docs/workspaces/#toc-limitations-caveats">Yarn docs</a>:</p><blockquote><em>Be careful when publishing packages in a workspace. If you are preparing your next release and you decided to use a new dependency but forgot to declare it in the package.json file, your tests might still pass locally if another package already downloaded that dependency into the workspace root. However, it will be broken for consumers that pull it from a registry, since the dependency list is now incomplete so they have no way to download the new dependency. Currently, there is no way to throw a warning in this scenario.</em></blockquote><p>Like Yarn, pnpm hoists all packages to the root. However, pnpm stores all dependencies in a hidden folder and only links the direct dependencies of every package into their node_modules.</p><p>Let’s see how Yarn and pnpm work on a simple example:</p><ul><li>there is a small monorepo with two packages: foo and bar</li><li>foo has is-negative@1.0.0 as a dependency</li><li>bar has is-positive@1.0.0 as a dependency</li></ul><h3>Yarn in action</h3><p>To make this repo work with Yarn, there should be a package.json in the root of the repo with the following content:</p><pre>{<br> &quot;private&quot;: true,<br> &quot;workspaces&quot;: [&quot;foo&quot;, &quot;bar&quot;]<br>}</pre><p>To install all dependencies of all workspace packages, you should run yarn install.</p><blockquote><em>See results </em><a href="https://github.com/zkochan/comparing-monorepo-node-modules/tree/master/yarn-example"><em>here</em></a></blockquote><p>In this case, Yarn will create a single node_modules in the root of the repo with both is-negative and is-positive. It means that both foo and bar will have access to the dependencies of each other.</p><h3>pnpm in action</h3><p>To make pnpm install dependencies in this repo, you’ll need to create a pnpm-workspace.yaml in the root of the repo (it can be empty) and a .npmrc file with the following content:</p><pre>shared-workspace-shrinkwrap = true<br>link-workspace-packages = true</pre><p>To install all dependencies of all workspace packages with pnpm, you should run pnpm multi install (or just pnpm m i).</p><blockquote><em>See results </em><a href="https://github.com/zkochan/comparing-monorepo-node-modules/tree/master/pnpm-example"><em>here</em></a></blockquote><p>Like Yarn, pnpm creates a node_modules in the root of the repo. However, if you open that folder, you&#39;ll see that all directories and files are hidden there:</p><pre>node_modules<br>+ .registry.npmjs.org<br>+ .modules.yaml<br>+ .shrinkwrap.yaml</pre><p>This node_modules stores all the dependencies but they are hidden in .registry.npmjs.org. Node&#39;s resolution algorithm will not find them.</p><p>Now if you check the <a href="https://github.com/zkochan/comparing-monorepo-node-modules/tree/master/pnpm-example/foo">directory of bar</a>, you’ll see a node_modules there as well, with a single symlink called is-negative. This symlink is pointing at ../../node_modules/.registry.npmjs.org/is-negative/1.0.0/node_modules/is-negative. Likewise, there is a symlink to is-positive in the node_modules directory of foo. So foo is able to resolve only is-positive and bar is only able to resolve is-negative 🎉😊</p><p>As you can see, pnpm is strict <a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">not only when used with a single </a><a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">package.json</a> but also in a multi-package repository.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6c025d50b9bd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpm-vs-yarn-monorepo-node-modules-6c025d50b9bd">pnpm vs Yarn: monorepo node_modules</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pnpm vs Lerna: filtering in a multi-package repository]]></title>
            <link>https://medium.com/pnpm/pnpm-vs-lerna-filtering-in-a-multi-package-repository-1f68bc644d6a?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/1f68bc644d6a</guid>
            <category><![CDATA[pnpm]]></category>
            <category><![CDATA[monorepo]]></category>
            <category><![CDATA[npm]]></category>
            <category><![CDATA[lerna]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Sun, 02 Sep 2018 14:10:41 GMT</pubDate>
            <atom:updated>2019-08-31T00:23:20.119Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IxfhYOCmmeBnYIhQpNwRKw.png" /></figure><p>Everyone heard about <a href="https://github.com/lerna/lerna/">Lerna</a>, which is “A tool for managing JavaScript projects with multiple packages.” A lot fewer devs heard about <a href="https://github.com/pnpm/pnpm">pnpm</a>, which is a fast, disk space efficient package manager for JavaScript. Both Lerna and pnpm try to improve tooling for multi-package repositories (MPR). For Lerna it was the reason for creation. For pnpm, MPR support is a nice bonus feature that is implemented via a set of commands called <a href="https://pnpm.js.org/en/cli/recursive">recursive</a>. Of course, there are many differences between how Lerna manages a multi-package repo vs pnpm. In this article, I want to compare one seemingly simple aspect: filtering.</p><p>Filtering in an MPR is important because, during development, changes are mainly made inside one or two packages. It wouldn’t make sense to run commands on the whole repository if only a few packages were modified.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*Yd-UNRDWmLAUQQg4zY4wSg.png" /></figure><h3>Filtering in Lerna</h3><p>Filtering in Lerna (as of v3.2.1) is achieved by the following flags:</p><ul><li>scope - Include only packages with names matching the given glob.</li><li>include-filtered-dependents - Include all transitive dependents when running a command regardless of --scope, --ignore, or --since.</li><li>include-filtered-dependencies - Include all transitive dependencies when running a command regardless of --scope, --ignore, or --since.</li><li>ignore - Exclude packages with names matching the given glob.</li><li>private - Include private packages. Pass --no-private to exclude private packages.</li><li>since - Only include packages that have been updated since the specified [ref]. If no ref is passed, it defaults to the most recent tag.</li></ul><p>These flags make filtering in Lerna quite powerful. However, they are pretty hard to type. Let’s say you downloaded a repository and want to work only on login-page component. You&#39;d want to run installation for login-pageand any of its dependencies:</p><pre>lerna bootstrap --scope login-page --include-filtered-dependencies</pre><p>Or maybe you changed a component called site-header and would like to run tests on all the dependent packages:</p><pre>lerna run test --scope site-header --include-filtered-dependents</pre><p>These flags are not only hard to type but also hard to remember and easy to mix up.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1012/1*Llzyz7QvwoWasbQ6AbFbSg.png" /></figure><h3>Filtering in pnpm</h3><p>Unlike Lerna, pnpm uses a special package selector syntax to restrict its commands. So instead of memorizing a set of long flag names, you should only remember a very easy-to-remember selector syntax.</p><p>As of version 2.15.0, these are the selectors that pnpm supports:</p><ul><li>&lt;pattern&gt; - Restricts the scope to package names matching the given pattern. E.g.: foo, @bar/*</li><li>&lt;pattern&gt;... - Includes all direct and indirect dependencies of the matched packages. E.g.: foo...</li><li>...&lt;pattern&gt; - Includes all direct and indirect dependents of the matched packages. E.g.: ...foo, ...@bar/*</li><li>./&lt;directory&gt; - Includes all packages that are inside a given subdirectory. E.g.: ./components</li><li>. - Includes all packages that are under the current working directory.</li></ul><p>These filters may be specified either via the --filter flag or after a --at the end of the command.</p><blockquote><em>Note: as of </em><em>v2.15.0, filters after </em><em>-- are not supported by </em><em>run, </em><em>exec, </em><em>test</em></blockquote><p>So if you want to bootstrap login-page and all of its dependencies, this is the way to do it with pnpm:</p><pre>pnpm recursive install -- login-page...</pre><p>And if you want to run tests of site-header and all of its dependents, use the ...&lt;pattern&gt; selector:</p><pre>pnpm recursive test --filter ...site-header</pre><p>Of course, you can combine as many selectors as you’d like:</p><pre>pnpm recursive update -- ...site-header login-page... ./utils @style/*</pre><p>The command above updates dependencies in:</p><ul><li>site-header</li><li>dependents of site-header</li><li>login-page</li><li>dependencies of login-page</li><li>all packages that are located in the utils directory</li><li>all packages from the @style scope</li></ul><p>pnpm might not have yet all the features that Lerna provides but for many users it might be enough already.</p><p>If you haven’t heard about pnpm yet, I recommend reading also <a href="https://medium.com/pnpm/flat-node-modules-is-not-the-only-way-d2e40f7296a3">Flat node_modules is not the only way</a> which explains the unique node_modules structure created by pnpm.</p><h3>Cheatsheet</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0e9d39dff83e7be56ed88723b7ef4769/href">https://medium.com/media/0e9d39dff83e7be56ed88723b7ef4769/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1f68bc644d6a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpm-vs-lerna-filtering-in-a-multi-package-repository-1f68bc644d6a">pnpm vs Lerna: filtering in a multi-package repository</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The not fancy CLI output of pnpm]]></title>
            <link>https://medium.com/pnpm/the-not-fancy-cli-output-of-pnpm-5bd4398716ce?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/5bd4398716ce</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[pnpm]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Sun, 26 Aug 2018 21:33:12 GMT</pubDate>
            <atom:updated>2018-08-26T21:33:12.470Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://github.com/pnpm/pnpm">pnpm</a> is a JavaScript package manager that differs from npm and Yarn in many ways. If you haven’t heard about it yet, I recommend checking it out. In this article, I would love to write about the design system that we use to report during installation.</p><p>When I first started contributing to pnpm (around v0.15), this is how an installation was reported:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/638/0*4cpmejMmrBW_db5y.gif" /></figure><p>It wasn’t really useful but some users of pnpm liked it. They thought it was beautiful. But then as we started adding more features, we realized that it is very important to print the right amount of information in a nice readable format.</p><p>So let’s see how pnpm has evolved and how it reports in different scenarios as of v2.13.6.</p><h3>Reporting installation in a single project</h3><p>When you first install pnpm and you run pnpm install in a project, you&#39;ll see an output like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/0*kVzFSjrL5h7L_QsG.png" /></figure><p>Unlike the old output, this one is very static and minimalistic but it contains a lot more useful information.</p><p>We see that:</p><ol><li>one of the installed packages is deprecated</li><li>117 new packages were added to node_modules</li><li>Installation slowed down a bit because the huge typescript tarball was being downloaded</li><li>0 packages were available in the store, so all 117 packages were downloaded (pnpm saves one version of a package only ever once on a disk, so when a package is available in the store, it is just hard linked to the node_modules)</li><li>express@4.16.0 was added as a production dependency</li><li>a newer version of express is available in the registry</li><li>babel-preset-es2015@6.24.1 and typescript@3.0.1 were added as dev dependencies</li></ol><p>Now lets update express to the latest version and see what we get:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/458/0*3Q7760TwOwAAzjjT.png" /></figure><ol><li>5 packages were removed from node_modules</li><li>5 packages were added to node_modules</li><li>all 5 packages were downloaded from the registry</li><li>the newest express was added to the project</li></ol><h3>Reporting installation in a multi-package repository</h3><p>pnpm has a set of commands for working with multi-package repositories (MPR). When installing dependencies in an MPR, the amount of information that is being processed is so big that printing all of it would just make an unreadable mess. In order to provide some basic information anyway, we came out with the concept of zoomed-out reporting. A zoomed-out reporting contains just the most important pieces of information.</p><p>Every package in the MPR is printed with the number of added/removed packages (inspired by Git):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/684/0*g7z7c7IRBY3DfXcB.png" /></figure><p>Zoomed-out reporting also prints warnings (only warnings, no info messages):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/711/0*utGsoItGbSXVzFbE.png" /></figure><p>When we came out with the concept of zoomed-out reporting for the <a href="https://pnpm.js.org/docs/en/pnpm-recursive.html">recursive commands</a>, we realized that there are other scenarios in which they are useful. For instance, when packages are linked in, it should be a mixture of zoomed-out and zoomed-in reporting. Packages that are linked in should be reported briefly and the package in the current working directory should be in focus:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/821/0*8uZg9gCdv7gCpXol.png" /></figure><h3>Implementation details</h3><p>Although the output seems minimalistic and simple, it is produced by a very complex system. pnpm consists of many components and many operations may happen in random order (this is one of the reasons pnpm is <a href="https://github.com/pnpm/node-package-manager-benchmark#readme">so fast</a>). That is why reporting is performed by a specialized part of pnpm called “reporter” (<a href="https://github.com/pnpm/pnpm/tree/master/packages/default-reporter">code</a>).</p><p>The reporter is a package that listens for logs, filters them, combines and forms an output from them. pnpm uses <a href="https://github.com/rvagg/bole">bole</a> to pass the logs from the loggers to the reporter. This modularization is great because we can mock the logs and cover reporting with tests!</p><p>For printing the output to the console, we use <a href="https://github.com/mafintosh/ansi-diff">ansi-diff</a>. ansi-diff is great because it accepts &quot;frames&quot; of output and it updates only those parts of the console that are changed (and it is fast). Before we switched to ansi-diff, we used another popular library for updating the console output but it was doing the update with noticeable flickering.</p><h3>P.S.</h3><p>It is very hard to implement good CLI reporting. But good reporting allows developers to focus on the important things and possibly notice issues earlier.</p><p>Of course, pnpm’s reporting can improved a lot and we have many <a href="https://github.com/pnpm/pnpm/issues?q=is%3Aissue+is%3Aopen+label%3A%22area%3A+reporting%22">open issues</a> in that area. Give pnpm a try and don’t hesitate to let us know if there are things that can be improved further.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5bd4398716ce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/the-not-fancy-cli-output-of-pnpm-5bd4398716ce">The not fancy CLI output of pnpm</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Flat node_modules is not the only way]]></title>
            <link>https://medium.com/pnpm/flat-node-modules-is-not-the-only-way-d2e40f7296a3?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/d2e40f7296a3</guid>
            <category><![CDATA[pnpm]]></category>
            <category><![CDATA[node-package-manager]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Thu, 28 Jun 2018 18:43:30 GMT</pubDate>
            <atom:updated>2020-05-27T20:23:33.789Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>This article covers an old version of pnpm. For an updated version of the article &gt;</strong><a href="https://pnpm.js.org/blog/2020/05/27/flat-node-modules-is-not-the-only-way"><strong>go here</strong></a><strong>&lt;.</strong></p><p>New users of <a href="https://pnpm.js.org/">pnpm</a> frequently ask me about the weird structure of node_modules that pnpm creates. Why is it not flat? Where are all the sub-dependencies?</p><blockquote>I am going to assume that readers of the article are already familiar with flat node_modules created by npm and Yarn. If you don’t understand why npm 3 had to start using flat node_modules in v3, you can find some prehistory in <a href="https://www.kochan.io/nodejs/why-should-we-use-pnpm.html">Why should we use pnpm?</a>.</blockquote><p>So why is pnpm’s node_modules unusual? Let’s create two directories and run npm install express in one of them and pnpm install express in the other one. Here’s the top of what you get in the first directory’s node_modules:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/166/1*WxJx5ldgAXI6lQxf-DMACQ.png" /><figcaption>You can see the whole directory <a href="https://github.com/zkochan/comparing-node-modules/tree/master/npm-example/node_modules">here</a></figcaption></figure><p>And this is what you get in the node_modules created by pnpm:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/176/1*WJ-lOXOUmMjuFP0BRnhhIg.png" /><figcaption>You can check it <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm-example/node_modules">here</a></figcaption></figure><p>So where are all the dependencies? There is only one folder in the node_modules called .registry.npmjs.org and a symlink called express. Well, we installed only express, so that is the only package that your application has to have access to.</p><blockquote>Read more about why pnpm’s strictness is a good thing <a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">here</a></blockquote><p>Let’s see what is inside express:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/154/1*noDudS-tFrATx-cY9cq2Pg.png" /></figure><p>express has no node_modules? Where are all the dependencies of express?</p><p>The trick is that express is just a symlink. When Node.js resolves dependencies, it uses their real locations, so it does not preserve symlinks. But where is the real location of express, you might ask?</p><p>Here: <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm-example/node_modules/.registry.npmjs.org/express/4.16.3/node_modules/express">node_modules/.registry.npmjs.org/express/4.16.3/node_modules/express</a></p><p>OK, so now we know the purpose of the .registry.npmjs.org/ folder. .registry.npmjs.org/ stores all the packages in a flat folder structure, so every package can be found in a folder named by this pattern:</p><pre>.registry.npmjs.org/&lt;name&gt;/&lt;version&gt;/node_modules/&lt;name&gt;</pre><p>This flat structure avoids the long path issues that were caused by the nested node_modules created by npm v2 but keeps packages isolated unlike the flat node_modules created by npm v3,4,5,6.</p><p>Now let’s look into the real location of express:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/121/1*E51LbmsguElPgwOalsAYEA.png" /></figure><p>Is it a scam? It still lacks node_modules! The second trick of pnpm’s node_modules structure is that the dependencies of packages are on the same directory level on which the real location of the dependent package. So dependencies of express are not in /express/4.16.4/node_modules/express/node_modules/ but in <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm-example/node_modules/.registry.npmjs.org/express/4.16.3/node_modules">/express/4.16.4/node_modules/</a>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/173/1*CvlMEiXlThDPm62BmyupHA.png" /></figure><p>All the dependencies of express are symlinks to appropriate directories in node_modules/.registry.npmjs.org/. Placing dependencies of express one level up allows avoiding circular symlinks.</p><p>So as you can see, even though pnpm’s node_modules structure seems unusual at first</p><p>1. it is completely Node.js compatible<br>2. packages are nicely grouped with their dependencies</p><p>The structure is a little bit <a href="https://pnpm.js.org/docs/en/how-peers-are-resolved.html">more complex</a> for packages with peer dependencies but the idea is the same: using symlinks to create a nesting with a flat directory structure.</p><p>If you’d like to try out <a href="https://github.com/pnpm/pnpm/">pnpm</a>, you can easily install it with npm: npm i -g pnpm. Then just run it instead of npm when you need to install something: pnpm install foo bar.</p><p><em>This article was originally posted on </em><a href="https://dev.to/zkochan/flat-nodemodules-is-not-the-only-way-mo2"><em>dev.to</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d2e40f7296a3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/flat-node-modules-is-not-the-only-way-d2e40f7296a3">Flat node_modules is not the only way</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pnpm version 2 is out!]]></title>
            <link>https://medium.com/pnpm/pnpm-version-2-is-out-a015268254d5?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/a015268254d5</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Wed, 23 May 2018 03:52:59 GMT</pubDate>
            <atom:updated>2018-06-06T16:20:25.491Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VmOHbQGrHlg_N7iS4jW4Mw.jpeg" /><figcaption>Didn’t give pnpm a chance yet? No problem! v2 is out, with more features and battle-tested on <a href="https://pnpm.js.org/en/users.html">huge projects</a>. Photo by <a href="https://unsplash.com/photos/UA3R3P479i8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Franck V.</a></figcaption></figure><p>Last week v2.0 of <a href="https://github.com/pnpm/pnpm">pnpm</a> was released. It’s been almost a year since version 1.0 came out and we were busy implementing new features (v1 had 43 minor versions). So let’s see what awesome new features were added to pnpm since v1.0 and what are the breaking changes of v2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/525/1*TZiJ2Dz3Ag3PoXxoNA2kAg.gif" /></figure><h3>So what’s new in pnpm since v1.0?</h3><h4>The store server</h4><p>We added the store server to pnpm in v1.30. The store server is an app that can run in a separate process and handle all the store manipulations, reducing the number of tasks that pnpm install should do. With a store server, installations are faster and concurrent installations may run using the same store.</p><p>To start a store server, open a new tab in your console and run: <a href="https://pnpm.js.org/docs/en/pnpm-server.html">pnpm server start</a>. Or run installation with the <a href="https://pnpm.js.org/docs/en/pnpm-install.html#use-store-server">--use-store-server</a> flag: pnpm install --use-store-server. Or set the use-store-server config to true: pnpm set use-store-server true.</p><p>In the future, we plan to make installation with a running store server the default behavior. An always running store server will allow us to make really interesting features, like supporting a decentralized registry or keeping the store always hot.</p><h4>The recursive commands</h4><p>Everyone seems to like multi-package repositories lately but managing a multi-package repo is hard. In v1.24 of pnpm, we implemented our first <a href="https://pnpm.js.org/docs/en/pnpm-recursive.html">recursive commands</a>: pnpm recursive install and pnpm recursive update.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/684/1*6YOcX5PaWLYimVl7CY2U9Q.png" /><figcaption>The output of running `pnpm recursive link`</figcaption></figure><p>The pnpm recursive commands are implementations of the traditional pnpm commands for multi-package repositories. So for instance, the recursive install command is installing dependencies of every project in every subdirectory of the current working directory. Installation is performed concurrently by a single run of pnpm, so it is <em>a lot faster</em> than separate executions of pnpm for each package in the repo.</p><p>For a performance comparison of pnpm recursive with npm, you can read: <a href="https://www.justanswer.com/blog/engineering/pnpm-on-justanswer-multi-package-repository">Trying pnpm on the JustAnswer multi-package repository</a></p><p>As of now, there are 4 recursive commands: install/update/link/unlink. But soon there will be more because we converted the pnpm repo into a monorepo and we are actively dogfooding these commands.</p><h4>The ability to create flat node_modules</h4><p>As you may know, one of the great features of pnpm is that it creates a non-flat node_modules (you can read more about why this is a great feature in <a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">this</a> article). However, we discovered that many packages in the ecosystem are broken, they use dependencies that are not declared in their package.json. When we see such packages, we try to submit pull requests and fix them. It takes time though, to discipline the ecosystem, that is why <a href="https://medium.com/u/1e8957a625a0">Emanuele Tamponi</a> has implemented the <a href="https://pnpm.js.org/docs/en/pnpm-install.html#shamefully-flatten">shamefully-flatten</a> config in version 1.34.</p><p>If your tooling has issues with pnpm, you can create a .npmrc file in the root of your project and set shamefully-flatten = true. But be aware that this is a hack and the right solution is to find the issue and fix it.</p><h4>Headless installation</h4><p>The most complex part of the installation is the resolution stage. After the resolution stage pnpm knows what should be installed where. But when a project already has a shrinkwrap.yaml, there is no need to repeat the resolution stage. That’s why we created a dedicated package (<a href="https://www.npmjs.com/package/@pnpm/headless">@pnpm/headless</a>) that can install really fast but only using information from a shrinkwrap.yaml.</p><p>This is basically what the npm team did with the npm ci command but we did it with the regular install command. No actions are required to enjoy the speed improvement, headless installation will be used instead of regular installation when the shrinkwrap file is up-to-date with the package.json (for better results, you should always commit your shrinkwrap.yaml file).</p><p><strong>Pro tip.</strong> You can use the <a href="https://pnpm.js.org/docs/en/pnpm-install.html#frozen-shrinkwrap">--frozen-shrinkwrap</a> flag to force a headless install. This flag is good for CI usage. But be aware, if you run pnpm install --frozen-shrinkwrap then an out-of-date lockfile will cause an installation failure.</p><h4>And many more…</h4><p>TBH, there were so many new features and improvements that I didn’t even mention them all, like side effects caching, better console reporting and new ways to import packages from the store. So just open our <a href="https://pnpm.js.org/docs/en/pnpm-install.html">docs</a> and read the descriptions of all the different commands… or just give pnpm a try on your project! (<a href="https://pnpm.js.org/docs/en/installation.html">how to install pnpm</a>)</p><h3>Breaking changes</h3><h4>Node.js 4 is not supported anymore</h4><p>End of life of Node.js 4 was on <a href="https://twitter.com/nodejs/status/990951154099113984">April 30th</a>. This was the main reason we needed to make a major version bump. A lot of our dependencies started to drop Node.js 4 support months before its end of life, so we had to make the same as soon as possible.</p><h4>Non-deprecated versions are preferred during resolution</h4><p>This is a breaking change that npm v6 did as well. If a semver range can be resolved by a deprecated and non-deprecated version of a package, then the non-deprecated version is used even if it is a smaller version than the deprecated one.</p><p>Example. If a package depends on rimraf@2 and rimraf@2.0.1 is deprecated then rimraf@2.0.0 is going to be installed (if v2.0.0 is not deprecated).</p><h4>`pnpm unlink` is an alias of `pnpm dislink`</h4><p>In version 1, pnpm unlink was an alias of the pnpm uninstall command. However, we wanted a command that would remove a linked package created by pnpm link and install it from the registry, so we create pnpm dislink. In order to avoid confusion, now we’ve made pnpm unlink an alias of pnpm dislink.</p><h3>Try it</h3><p>Just install pnpm via npm: npm install -g pnpm. And use it instead of npm whenever you want to install something: pnpm i foo.</p><p>Also, you can read more info at the <a href="https://github.com/pnpm/pnpm">pnpm GitHub repo</a>. You can follow <a href="https://twitter.com/pnpmjs">pnpm on Twitter</a> or ask for help at the <a href="https://gitter.im/pnpm/pnpm">pnpm Gitter Chat Room</a>.</p><p><em>If you were afraid to use pnpm in the past because it was not used by big teams/projects then it is not the case anymore. Check out </em><a href="https://pnpm.js.org/en/users.html"><em>who’s using pnpm</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a015268254d5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpm-version-2-is-out-a015268254d5">pnpm version 2 is out!</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Never ever forget to install a dependency]]></title>
            <link>https://medium.com/pnpm/never-ever-forget-to-install-a-dependency-1c39dd3bbb37?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/1c39dd3bbb37</guid>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Thu, 08 Mar 2018 16:14:17 GMT</pubDate>
            <atom:updated>2018-03-08T16:14:16.925Z</atom:updated>
            <content:encoded><![CDATA[<p>How many times have you published version 1.0.0 of your new fancy package and it didn&#39;t work when you installed it as a dependency?</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F12WjSnRGVC79EA%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fgiphy.com%2Fgifs%2Ffail-epic-absurd-12WjSnRGVC79EA&amp;image=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F12WjSnRGVC79EA%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="580" frameborder="0" scrolling="no"><a href="https://medium.com/media/6bf77f15a6d27d068f9f6e80d7129e03/href">https://medium.com/media/6bf77f15a6d27d068f9f6e80d7129e03/href</a></iframe><p>It happened to me a lot! One of the frequent issues is that I started to use a dev dependency but didn’t change it to a prod dependency. This is even a bigger issue when you use npm or Yarn because they create flat node_module. In a flat node_modules, your code has access even to sub-dependencies of your dev dependencies! The later cannot happen when you use <a href="https://github.com/pnpm/pnpm">pnpm</a> because pnpm creates a <a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">strict, non-flat node_modules folder</a>. However, even when you use pnpm, your code will have access to dev dependencies during development.</p><h3>Workaround</h3><p>This issue bothered me a lot and my first solution was to create a separate package for my tests. So there was a package.json file in the test/ folder that contained all the dependencies needed by tests. Test dependencies were installed to test/node_modules and they were not accessible by prod code.</p><p>However, there are also other issues that may be detected only after a package has been published:</p><ul><li>a file needed by the package is not added to the <a href="https://docs.npmjs.com/files/package.json#files">files</a> field of package.json.</li><li>installation lifecycle scripts fail</li><li>bins are incorrectly declared</li><li>the main file is not specified correctly</li></ul><h3>package-preview</h3><p>So I created a package that helps to detect these issues during running the tests of your project: <a href="https://github.com/zkochan/package-preview">package-preview</a> 🎉✨</p><blockquote>package-preview packs your project and installs it the way it’s going to be installed as a dependency, so you can test the exact same package content that is going to be installed by Node.js package managers.</blockquote><p>All you have to do is to install package-preview as a dev dependency:</p><p>pnpm i -D package-preview</p><p>…and run preview before running your tests</p><pre>{<br>  &quot;name&quot;: &quot;awesome&quot;,<br>  &quot;version&quot;: &quot;1.0.0&quot;,<br>  &quot;scripts&quot;: {<br>    &quot;test&quot;: &quot;preview &amp;&amp; tape test.js&quot;<br>  }<br>}</pre><p>package-preview is going to create the preview version of your package and link it to your project&#39;s node_modules. So in your tests, you can require awesome and test the production version of your package:</p><pre>// Instead of require(&#39;.&#39;)<br>const awesome = require(&#39;awesome&#39;)<br><br>assert(awesome() === &#39;Awesome stuff!&#39;)</pre><h3>P.S.</h3><p>Under the hood, package-preview uses <a href="https://github.com/pnpm/pnpm">pnpm,</a> so as a bonus, you will also catch errors that you would miss with npm/Yarn’s flat node_modules. If you did not yet try pnpm, check it out, you won’t be disappointed. It is fast, reliable and saves you lots of disk space!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c39dd3bbb37" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/never-ever-forget-to-install-a-dependency-1c39dd3bbb37">Never ever forget to install a dependency</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why package managers need hook systems]]></title>
            <link>https://medium.com/pnpm/why-package-managers-need-hook-systems-b8125d8b3dc7?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/b8125d8b3dc7</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Sat, 02 Sep 2017 13:54:01 GMT</pubDate>
            <atom:updated>2017-09-16T11:52:33.296Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<p>We introduced hooks to pnpm in <a href="https://github.com/pnpm/pnpm/releases/tag/v1.12.0">version 1.12</a>. In this article I want to write about why we think package managers (PMs) need hooks.</p><h3>Why would we want to hook into `node_modules`?</h3><p>When installing dependencies of a Node-project, the node_modules structure is 100% controlled by the package.json files of the dependencies (a.k.a. manifests). So if your project depends on foo@1.0.0 which depends on bar@2.0.0 then you’ll be going to have two dependencies installed in your node_modules. While you can change your project’s dependency set, you don’t have control over the manifests of your dependencies.</p><p>A typical dependency tree is huge and you have no ownership over the majority of your dependencies. Just analyze any of your dependencies at <a href="http://npm.anvaka.com/">npm.anvaka.com</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*HIEmSy7PaNBd6mhs8-Gddg.png" /><figcaption>The dependency graph of browserify</figcaption></figure><p>What to do if there is a bug in one of the packages inside your node_modules? If the issue is in a root dependency, then you have 3 options:</p><ol><li>find an alternative, more reliable package</li><li>submit a pull request (PR) that fixes the issue</li><li>create your own package and use it instead of the buggy one</li></ol><p>The 2nd option seems to be the correct one and I encourage everyone to contribute as frequently as possible. However, submitting a PR doesn’t mean that your changes will be merged/published. Even if they will be merged and published, it won’t happen immediately, you might have to wait for years. Here are some frequent issues:</p><ul><li>the project is unmaintained/poorly maintained</li><li>you did breaking changes and the author doesn’t like bumping major versions. The author will wait for several breaking changes to come in, before publishing a major version</li><li>the author thinks the bug is not a bug</li></ul><p>If the problematic package is a root dependency, then you can easily switch to another package or to your fork. The problem is match harder to solve if the package is a sub-dependency. In that case, your options are:</p><ol><li>submit a PR that fixes the issue</li><li>submit many PRs to packages that depend on the buggy package</li></ol><p>With hooks though, you can have a third option: create a fork and install it instead of the problematic package. So if you have foo@1.0.0 that depends on bar@2.0.0 you can have a hook that will override the dependency.</p><p>Let’s say there is a bug in bar@2.0.0 and you submitted a PR with a fix. However, the maintainer of bar is on vacation. You can use a hook to make pnpm install bar from your PR branch instead of bar@2.0.0 from the npm registry.</p><h3>Why hooks are important for pnpm’s survival</h3><p>Hooks are nice to have in any PM but for pnpm they are especially important. As you may know already, pnpm creates a strict symlinked node_modules structure. You can read more about it in:</p><p><a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">pnpm’s strictness helps to avoid silly bugs</a></p><p>Although the node_modules structure created by pnpm is Node.js-compatible, many packages have bugs that show up only when installed via pnpm. As a consequence, pnpm has issues with some popular frameworks and tools.</p><p>Of course, we try to solve these issues via PRs (I want to give a shout out to <a href="https://github.com/aecz">aecz</a> who managed to fix many such issues in Angular). But besides the usual issues, some of the maintainers are hostile and refuse to accept PRs just because they don’t like pnpm or believe that the flat node_modules created by npm/Yarn is a feature (it is not).</p><p>In the end, we have two options to fix the ecosystem for the strict pnpm:</p><ol><li>make pnpm popular enough. In that case, authors of frameworks/toolings will be testing their product with pnpm as well as npm and Yarn.</li><li>make a hook system to temporarily substitute the buggy packages that don’t work with pnpm.</li></ol><p>IMHO, the 1st scenario is pretty much impossible. pnpm can’t become popular without being a drop-in replacement for npm.</p><h3>Real-life example</h3><p>There is a popular package called <a href="https://github.com/browserify/resolve">resolve</a> for resolving dependencies from node_modules (1,3K dependents, 765K downloads a day). Unfortunately for pnpm, resolve preserves symlinks when resolving modules. This is an issue on resolve’s end as Node.js does not preserve symlinks during resolution. I did a <a href="https://github.com/browserify/resolve/pull/131">PR</a> to fix this issue and now resolve from version 1.4 has an option to not preserve symlinks.</p><p>This does not solve the problem for pnpm though. We can’t submit PRs to the 1.3K dependent packages to update resolve and pass preserverSymlink: false to it. The lead maintainer of resolve agreed to switch the option’s default value in the next major version. So I hoped Greenkeeper would create the PRs for us and most of the packages would update resolve to version 2.</p><p>I created another <a href="https://github.com/browserify/resolve/pull/135">PR</a> with the breaking change but resolve’s maintainer wants to wait for more breaking changes before changing resolve to version 2.</p><p>I realized that we cannot change the world but we can change pnpm, so I released the readPackage hook. My changes to resolve are available via my fork on GitHub, so all we have to do is to tell pnpm to install resolve from the fork. This can be done by declaring the hook in a file called pnpmfile.js:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/faaee4208a92f9cc42fe42bc7a656e28/href">https://medium.com/media/faaee4208a92f9cc42fe42bc7a656e28/href</a></iframe><p>During installation, pnpm will pass every package.json to this hook first and use the version of the package.json returned by the hook. So it won’t matter on which version of resolve the package depends, my fork will be installed instead and the project will work fine with pnpm.</p><h3>Summary</h3><p>I did not describe all the use cases when the readPackage can be useful. It is a really powerful tool and I think we’ll learn how to use it smartly.</p><p>Also, I want to say thanks to <a href="https://medium.com/u/334c14ed4bfc">Andrei Neculau</a>, who convinced me that this hook-system was a good idea.</p><p>To make it a little bit interactive, check how many unresolved PRs you have on GitHub and post the number in the comments section. You can use <a href="https://github.com/pulls">this link</a> to see all your open PRs.</p><h3>Do you want to give pnpm a try?</h3><p>Just install pnpm via npm: npm install -g pnpm. And use it instead of npm whenever you want to install something: pnpm i foo.</p><p>Also, you can read more info at the <a href="https://github.com/pnpm/pnpm">pnpm GitHub repo</a> or <a href="https://pnpm.js.org/">pnpm.js.org</a>. You can follow <a href="https://twitter.com/pnpmjs">pnpm on Twitter</a> or ask for help at the <a href="https://gitter.im/pnpm/pnpm">pnpm Gitter Chat Room</a>.</p><p><em>This post was originally published on </em><a href="https://www.kochan.io/nodejs/why-package-managers-need-hook-systems.html"><em>kochan.io</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b8125d8b3dc7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/why-package-managers-need-hook-systems-b8125d8b3dc7">Why package managers need hook systems</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pnpm version 1 is out!]]></title>
            <link>https://medium.com/pnpm/pnpm-version-1-is-out-935a07af914?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/935a07af914</guid>
            <category><![CDATA[pnpm]]></category>
            <category><![CDATA[npm]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[package-manager]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Wed, 28 Jun 2017 08:00:23 GMT</pubDate>
            <atom:updated>2017-06-28T09:45:46.140Z</atom:updated>
            <content:encoded><![CDATA[<p>Today we’re excited to announce the release of <a href="https://github.com/pnpm/pnpm">pnpm</a> 1!</p><p>Why only now? The initial commit to pnpm was made by <a href="https://medium.com/u/ff5ebab653a9">Rico Sta. Cruz</a> on <a href="https://github.com/pnpm/pnpm/commit/4b42e5fcc402310d028ac54ba8fe979f7c4470af">Jan 27, 2016</a>. It was based on the ideas of <a href="https://github.com/alexanderGugel/ied">ied</a> by <a href="https://twitter.com/alexanderGugel">Alexander Gugel</a> with initial commit on <a href="https://github.com/alexanderGugel/ied/commit/d8bae2d63750030b019e9653ce9ea71de93be5c7">Aug 6, 2015</a>!</p><p>Unlike <em>Yarn</em>, which has decided to use the same <strong>node_modules</strong> structure that <em>npm </em>creates, <em>pnpm </em>uses a completely new approach (about which you can read more in <a href="https://medium.com/pnpm/why-should-we-use-pnpm-75ca4bfe7d93">this</a> article). It was <em>really </em>hard to make a symlinked <strong>node_modules</strong> structure work with most of the existing npm packages! All the different problems that we have encountered and the dozens of breaking changes we had to make, deserves a post of its own. Finally, almost 2 years since the idea of a symlinked <strong>node_modules</strong> structure has born, we can tell with confidence: it is possible and <strong>it does work</strong>.</p><h3>So what does version 1 mean?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/160/1*96oyHPobt0cjBqQQay8rDQ.png" /></figure><p>Version 1 means that:</p><ul><li>The <a href="https://github.com/pnpm/pnpm/blob/master/docs/about-the-package-store.md">store structure</a> that pnpm uses since <a href="https://github.com/pnpm/pnpm/releases/tag/v0.70.0">version 0.70</a> is reliable enough and we are confident that there will be no need in breaking changes in its structure.</li><li><a href="https://github.com/pnpm/pnpm/blob/master/docs/symlinked-node-modules-structure.md">The <strong>node_modules</strong> layout</a> that pnpm creates works with most of the ecosystem.<br><em>pnpm@1</em> also ships with an experimental <strong>node_modules </strong>layout that can be turned on with the <a href="https://github.com/pnpm/pnpm#independent-leaves">independent-leaves</a> config. The experimental layout boosts installation speed by 8% and works almost with all projects. However, we were not confident enough to make it the default yet.</li><li>The format of the <strong>shrinkwrap.yaml</strong> file, which is pnpm’s lockfile, is good enough for being committed to VCS.</li><li>When possible, <em>pnpm@1</em> works the way <em>npm@5</em> does.</li></ul><p>You can rely on these things and they won’t get breaking changes in version 1.</p><h3>What’s next?</h3><p><strong>Even faster!</strong> The goal is to make installations<em> subsecond fast</em>. So fast that it would run on every Git operation. Maybe one day it would be even integrated to Git?!</p><p>As of now, pnpm is faster than Yarn when installing with cold cache but may be a bit slower in different scenarios. For a detailed comparison of npm/pnpm/Yarn speed, see “<a href="https://intoli.com/blog/node-package-manager-benchmarks/">Why I still don’t use Yarn</a>”. However, there is no reason for pnpm to be slower than Yarn or npm. So we’ll have to find the issues and make pnpm faster.</p><p><strong>Simpler codebase.</strong> pnpm is currently very hard to contribute to, so it will have to be split into separate packages. The first step will probably be separation of the installation engine.</p><p><strong>PR.</strong> Although pnpm is public for a longer period of time than Yarn, it is far less popular. So more articles, more documentation, and more interesting tools will be created to promote pnpm. Let’s make our <a href="https://github.com/pnpm/awesome-pnpm">awesome list</a> huge!</p><h3>Try it</h3><p>Just install pnpm via npm: npm install -g pnpm. And use it instead of npm whenever you want to install something: pnpm i foo.</p><p>Also, you can read more info at the <a href="https://github.com/pnpm/pnpm">pnpm GitHub repo</a>. You can follow <a href="https://twitter.com/pnpmjs">pnpm on Twitter</a> or ask for help at the <a href="https://gitter.im/pnpm/pnpm">pnpm Gitter Chat Room</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=935a07af914" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpm-version-1-is-out-935a07af914">pnpm version 1 is out!</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pnpm’s strictness helps to avoid silly bugs]]></title>
            <link>https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308?source=rss----ec106fa1e865---4</link>
            <guid isPermaLink="false">https://medium.com/p/9a15fb306308</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[package-manager]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[pnpm]]></category>
            <dc:creator><![CDATA[Zoltan Kochan]]></dc:creator>
            <pubDate>Wed, 07 Jun 2017 19:07:13 GMT</pubDate>
            <atom:updated>2018-03-30T08:35:03.877Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://github.com/pnpm/pnpm">pnpm</a> is a package manager for Node.js. I have written an article earlier about <a href="https://www.kochan.io/nodejs/why-should-we-use-pnpm.html">why should we use pnpm</a>. In this article I want to demonstrate how using pnpm helps in preventing some silly bugs.</p><p>When using npm, you have access to packages that you don’t reference in your project’s package.json. This is possible because npm creates a flat node_modules folder.</p><p>Let me explain this by an example.</p><ul><li>create an empty project: mkdir project &amp;&amp; npm init -y</li><li>run npm install express --save</li><li>go to the node_modules folder that was created</li><li>run ls -1</li></ul><p>You’ll get an output similar to this one:</p><pre>accepts<br>array-flatten<br>content-disposition<br>content-type<br>cookie<br>cookie-signature<br>debug<br>depd<br>destroy<br>ee-first<br>encodeurl<br>escape-html<br>etag<br>express<br>finalhandler<br>forwarded<br>fresh<br>http-errors<br>inherits<br>ipaddr.js<br>media-typer<br>merge-descriptors<br>methods<br>mime<br>mime-db<br>mime-types<br>ms<br>negotiator<br>on-finished<br>parseurl<br>path-to-regexp<br>proxy-addr<br>qs<br>range-parser<br>send<br>serve-static<br>setprototypeof<br>statuses<br>type-is<br>unpipe<br>utils-merge<br>vary</pre><p>As you can see, even though you installed only express, a lot more packages are available in the node_modules folder. Node.js doesn’t care what is in your package.json file, you will have access to all the packages that are in the root of node_modules. So you can start using all those packages without even installing them explicitly.</p><p>Let’s say you need debug in your project. You can start using it and forget to add it to package.json. Your project will work fine. You will commit your changes and publish it to production. It will work well even in production. However, after a few weeks or months, one of two things can very likely happen:</p><ol><li>a new major version of debug with a new API can get published. Your code was written for debug@1 and it needs some updates to work with debug@2. You are safe until express uses debug@1 because debug@1 is installed to the root of node_modules. However, express can update its dependency in any moment, fix all usages of debug and publish a new patch (a patch, because express didn’t have any breaking changes). Next time you do npm install, express will be updated and debug@2 installed into the root of your node_modules. The project will break, even though you did not make any changes!</li><li>another possibility is that express stops using debug. It can just remove it from dependencies and publish a new version. When you’ll update express, your code will break because the debug package won’t be in node_modulesanymore.</li></ol><p>Now imagine that your project is not a web app but a package used by many other people. If you don’t include a package used in code into the package.json, your package is a <strong>timed bomb</strong>. Do you remember <a href="https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/">left-pad</a>? I can imagine a similar catastrophe happening in the future because of a forgotten dependency.</p><h3>How does pnpm help with avoiding these type of bugs?</h3><p>Unlike npm, pnpm does not try to move everything to the root of node_modules. If you remove the node_modules folder created by npm in the previous example and run pnpm install express, you’ll see that ls -1 will print only one symlink in the node_modules folder: express. No debug!</p><p>On next run, your app will immediately fail, because it won’t be able to find debug. Which is the way it should be! To fix the project, you’ll just run pnpm install debug and debug will be added to your package.json (pnpm saves packages to package.json by default, even when the --save parameter is not passed). With debug in your package.json, you can be sure that it will always be installed into node_modules and it will work with your code as expected.</p><p>pnpm gets a lot of issues opened because some packages/toolings don’t work. These issues are mostly happening because the packages/toolings have package.jsons that miss dependencies. Some developers even think that it is fine to not include dependencies in package.json because “it works with npm/yarn”. It is not OK! It might work today but it will break tomorrow.</p><p>You might not use pnpm. But please, publish valid packages. If you don’t use pnpm, use some tooling like <a href="https://www.npmjs.com/package/dependency-check">dependency-check</a> to validate your package before publishing it to the registry.</p><h3>npm’s global style installation</h3><p>A month later after publishing this article, I have found out that it is possible to avoid these kind of bugs with npm as well! It is not the default behavior but npm can install <strong>node_modules </strong>in a different layout, in which</p><blockquote>Only your direct dependencies will show in <strong>node_modules</strong> and everything they depend on will be flattened in their <strong>node_modules</strong> folders.</blockquote><p>To achieve this, just run npm with the <a href="https://docs.npmjs.com/misc/config#global-style">--global-style</a> option or change its value in the configs via npm c set global-style true.</p><h3>Do you want to give pnpm a try?</h3><p>Just install pnpm via npm: npm install -g pnpm. And use it instead of npm whenever you want to install something: pnpm i foo.</p><p>Also you can read more info at the <a href="https://github.com/pnpm/pnpm">pnpm GitHub repo</a> or <a href="https://pnpm.js.org/">pnpm.js.org</a>. You can follow <a href="https://twitter.com/pnpmjs">pnpm on Twitter</a> or ask for help at the <a href="https://gitter.im/pnpm/pnpm">pnpm Gitter Chat Room</a>.</p><p>(This article was originally posted on <a href="https://www.kochan.io/nodejs/pnpms-strictness-helps-to-avoid-silly-bugs.html">https://www.kochan.io/nodejs/pnpms-strictness-helps-to-avoid-silly-bugs.html</a>)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a15fb306308" width="1" height="1" alt=""><hr><p><a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308">pnpm’s strictness helps to avoid silly bugs</a> was originally published in <a href="https://medium.com/pnpm">pnpm</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>