<?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: eLabFTW</title>
    <description>The latest articles on DEV Community by eLabFTW (@elabftw).</description>
    <link>https://dev.to/elabftw</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%2F34660%2Fcafd5dcf-9448-4e41-a3d8-a0ddcea42c64.png</url>
      <title>DEV Community: eLabFTW</title>
      <link>https://dev.to/elabftw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elabftw"/>
    <language>en</language>
    <item>
      <title>Getting back that precious disk space</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Mon, 18 May 2020 20:33:55 +0000</pubDate>
      <link>https://dev.to/elabftw/getting-back-that-precious-disk-space-4p28</link>
      <guid>https://dev.to/elabftw/getting-back-that-precious-disk-space-4p28</guid>
      <description>&lt;p&gt;Hello devs,&lt;/p&gt;

&lt;p&gt;I you're like me and you like to try things out, work on several projects in several languages, chances are that you've been cluttering your computer with gigabytes of files that are not worth keeping.&lt;/p&gt;

&lt;p&gt;I'm talking about all the cached packages from package managers, old docker images, and containers you started without the &lt;code&gt;--rm&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;This post is an attempt at regrouping the commands to clear that space. It's written for GNU+Linux users and will probably work for Mac. Some of the commands will also work on Windows (but then if you're doing dev on Windows I'm deeply sorry for you).&lt;/p&gt;

&lt;p&gt;If you want to go along and execute the commands, start by checking your disk usage with &lt;code&gt;df -h&lt;/code&gt; first so you know how much space you'll get back :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: we're going to delete files here! It shouldn't cause any issue because it's only cached files that you can easily get back, but be careful about following a random blog post on the internets telling you to run a bunch of &lt;code&gt;rm -rf&lt;/code&gt; commands ;) I shall not be held responsible for any damage caused by executing the commands described below.&lt;/p&gt;

&lt;p&gt;I'm starting this article with 94 Gb free on &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  npm (javascript)
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;npm cache clean --force&lt;/code&gt;&lt;br&gt;
&lt;code&gt;yarn cache clean&lt;/code&gt;&lt;br&gt;
&lt;code&gt;rm -r ~/.cache/typescript/*&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  composer (php)
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;composer clear-cache&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  cargo (rust)
&lt;/h1&gt;

&lt;p&gt;There is no baked in command for that. See &lt;a href="https://github.com/rust-lang/cargo/issues/3289"&gt;GitHub issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -rf ~/.cargo/git ~/.cargo/registry&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We don't delete the whole &lt;code&gt;~/.cargo&lt;/code&gt; folder as it might contain useful binaries in &lt;code&gt;bin/&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  docker
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;docker system prune -a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I like this command because it tells you how much disk space you got back after running it, and it really removes everything not currently in use. If you've been using docker for while and never used it, you might get as much as 40 Gb or more back! (yes images take up space!)&lt;/p&gt;

&lt;h1&gt;
  
  
  pip/pipenv (python)
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;rm -r ~/.cache/pip{,env}&lt;/code&gt;&lt;br&gt;
&lt;code&gt;rm -r ~/.local/share/{virtualenvs,jupyter}&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  go
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;go clean -cache -modcache -i -r&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The -i flag causes clean to remove the corresponding installed archive or binary (what 'go install' would create). The -r flag causes clean to be applied recursively to all the dependencies of the packages named by the import paths.&lt;/p&gt;

&lt;h1&gt;
  
  
  css
&lt;/h1&gt;

&lt;p&gt;Nope, just kidding.&lt;/p&gt;

&lt;h1&gt;
  
  
  some non-dev stuff
&lt;/h1&gt;

&lt;p&gt;While we're at it...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -r ~/.cache/{mozilla,chromium,thumbnails}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You might want to have a look into this folder, as it's quite possible that a game you played 20 minutes in 2011 is taking up 3 Gb... &lt;code&gt;du -sh ~/.cache/*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's not forget the package managers!&lt;/p&gt;

&lt;p&gt;Archlinux commands (BTW, I use Arch!):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pacman -Sc&lt;/code&gt; (add another &lt;code&gt;c&lt;/code&gt; to really remove everything)&lt;br&gt;
&lt;code&gt;yay -Sc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For Debian/Ubuntu/Mint users:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt-get clean&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo apt-get autoclean&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For Fedora/CentOS users:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dnf clean all&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Please let me know in the comments how much disk space you got back! I had 94 Gb free at the beginning, now it's showing 128 Gb! That's 34 Gb back from the dead!! :)&lt;/p&gt;

&lt;p&gt;Header image "GrandPerspective disk map" by Lars Plougmann is licensed under CC BY-SA 2.0&lt;/p&gt;

</description>
      <category>cleanup</category>
    </item>
    <item>
      <title>10 steps for securing a PHP app</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Mon, 14 Oct 2019 14:49:21 +0000</pubDate>
      <link>https://dev.to/elabftw/10-steps-for-securing-a-php-app-5fnp</link>
      <guid>https://dev.to/elabftw/10-steps-for-securing-a-php-app-5fnp</guid>
      <description>&lt;p&gt;Hello PHP devs. In this post, I'll try and provide you with some concrete steps you can make to improve the security of your PHP app. I'm focusing on the PHP configuration itself, so we won't talk about SQL injections, HTTPS or other non PHP related issues.&lt;/p&gt;

&lt;p&gt;I'll illustrate examples with bash lines from my &lt;code&gt;docker-entrypoint.sh&lt;/code&gt; script, but of course you can apply it to a non docker environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use longer session id length
&lt;/h3&gt;

&lt;p&gt;Increasing the session id length will make it harder for an attacker to guess it (via bruteforce or more likely side-channel attacks). Session ID length can be between 22 to 256 characters. The default is 32.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/session.sid_length = 26/session.sid_length = 42/"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(don't ask me why it's 26 on Alpine Linux...)&lt;/p&gt;

&lt;p&gt;You might also want to look at session.sid_bits_per_character.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a custom session save path with restrictive permissions
&lt;/h3&gt;

&lt;p&gt;Only nginx/php needs to access the sessions, so let's put them in a special folder with restrictive permissions.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s:;session.save_path = &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;/tmp&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:session.save_path = &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;/sessions&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:"&lt;/span&gt; /etc/php7/php.ini
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /sessions
&lt;span class="nb"&gt;chown &lt;/span&gt;nginx:nginx /sessions
&lt;span class="nb"&gt;chmod &lt;/span&gt;700 /sessions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course, if you use Redis to handle sessions, you don't care about this part ;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure session cookies
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly"&gt;session.cookie_httponly&lt;/a&gt; to prevent javascript from accessing them. &lt;a href="https://blog.codinghorror.com/protecting-your-cookies-httponly/"&gt;More info&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/session.cookie_httponly.*/session.cookie_httponly = true/"&lt;/span&gt; /etc/php7/php.ini
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/;session.cookie_secure.*/session.cookie_secure = true/"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-secure"&gt;session.cookie_secure&lt;/a&gt; to prevent your cookie traveling on cleartext HTTP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-samesite"&gt;session.cookie_samesite&lt;/a&gt; to prevent Cross-Site attacks. Only for recent PHP/browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use strict mode
&lt;/h3&gt;

&lt;p&gt;Due to the cookie specification, attackers are capable to place non removable session ID cookies by locally setting a cookie database or JavaScript injections. &lt;a href="https://www.php.net/manual/en/session.configuration.php#ini.session.use-strict-mode"&gt;session.use_strict_mode&lt;/a&gt; can prevent an attacker initialized session ID of being used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restrict lifetime
&lt;/h3&gt;

&lt;p&gt;Sessions should close with the browser. So set &lt;a href="https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime"&gt;session.cookie_lifetime&lt;/a&gt; to 0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open_basedir
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.php.net/manual/en/ini.core.php#ini.open-basedir"&gt;open_basedir&lt;/a&gt; is a &lt;code&gt;php.ini&lt;/code&gt; config option that allows you to restrict the files/directories that can be accessed by PHP.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s#;open_basedir =#open_basedir = /elabftw/:/tmp/:/usr/bin/unzip#"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here I have added unzip as it is used by composer. &lt;code&gt;/elabftw&lt;/code&gt; is where all the source php files are located. And I don't remember why &lt;code&gt;/tmp&lt;/code&gt; is here but there is surely a reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disable functions
&lt;/h2&gt;

&lt;p&gt;Be careful with this, as you can very easily mess up an app. But this is definitely something to look into. Let's say an attacker somehow managed to upload a webshell, with this correctly in place, the webshell won't really work as &lt;code&gt;shell_exec&lt;/code&gt; and friends will be disabled. I'm providing a list that works for &lt;a href="https://github.com/elabftw/elabftw"&gt;elabftw&lt;/a&gt; but it's not 100% complete.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/disable_functions =/disable_functions = php_uname, getmyuid, getmypid, passthru, leak, listen, diskfreespace, tmpfile, link, ignore_user_abort, shell_exec, dl, system, highlight_file, source, show_source, fpaththru, virtual, posix_ctermid, posix_getcwd, posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups, posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getpwnam, posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo, posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times, posix_ttyname, posix_uname, phpinfo/"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Disable url_fopen
&lt;/h2&gt;

&lt;p&gt;The option &lt;a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen"&gt;allow_url_fopen&lt;/a&gt; is dangerous. Disable it. More info &lt;a href="https://security.stackexchange.com/questions/103427/what-are-php-allow-url-fopen-security-risk"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/allow_url_fopen = On/allow_url_fopen = Off/"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Disable cgi.fix_pathinfo
&lt;/h2&gt;

&lt;p&gt;You don't want to allow non PHP files to be executed as PHP files, right? Then disable this. &lt;a href="https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/"&gt;More info&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Hide PHP version
&lt;/h2&gt;

&lt;p&gt;To finish, a nobrainer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/expose_php = On/expose_php = Off/g"&lt;/span&gt; /etc/php7/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it for now. I hope you'll find this post useful and improve your configurations ;)&lt;/p&gt;

&lt;p&gt;Let me know in the comments if I've missed something important!&lt;/p&gt;

&lt;p&gt;~Nico&lt;/p&gt;

</description>
      <category>php</category>
      <category>security</category>
    </item>
    <item>
      <title>Optimizing your PHP app speed</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Thu, 14 Mar 2019 13:08:54 +0000</pubDate>
      <link>https://dev.to/elabftw/optimizing-your-php-app-speed-3hd4</link>
      <guid>https://dev.to/elabftw/optimizing-your-php-app-speed-3hd4</guid>
      <description>&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%2Flhwwrhpgx7kx0eq3xtjr.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%2Flhwwrhpgx7kx0eq3xtjr.jpg" alt="speedy gonzales"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is intended for PHP devs. I'll show you four ways to improve the speed of your PHP app easily. I'll skip the part where I tell you to use PHP 7, you must know by now that the speed improvement is dramatic… (and PHP 5.x is EOL anyway so…)&lt;/p&gt;

&lt;p&gt;TL;DR: -a flag for composer, use opcache, use template engine cache, use fully qualified function names.&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Use Composer optimization
&lt;/h2&gt;

&lt;p&gt;The prod and dev environments are a little bit different. It shouldn't be a surprise to you if I tell you that you should not install the dev dependencies in prod, right?&lt;/p&gt;

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

composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's basic. But did you know you can optimize the autoloader? Because the classes won't be changing once it's deployed, you can add a flag to composer (&lt;strong&gt;-a&lt;/strong&gt;) that will improve the speed of autoloading:&lt;/p&gt;

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

composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Ok, but what does it do you'll ask?&lt;/p&gt;

&lt;p&gt;From the &lt;a href="https://getcomposer.org/doc/06-config.md#classmap-authoritative" rel="noopener noreferrer"&gt;help&lt;/a&gt; it says: "the Composer autoloader will only load classes from the classmap". It also implies "&lt;a href="https://getcomposer.org/doc/06-config.md#optimize-autoloader" rel="noopener noreferrer"&gt;optimize-autoloader&lt;/a&gt;" so you don't have to add it too. You can see it as a way to say "hey, no more classes will be added so you don't need to scan the filesystem for a new class, just use the ones in the autoloader".&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Use opcache
&lt;/h2&gt;

&lt;p&gt;When a PHP file is read, it is converted in opcode, and then executed by the engine. Because in prod your PHP files won't change, you don't want to convert them to opcode every single time. Enter opcache.&lt;/p&gt;

&lt;p&gt;Using opcache can dramatically increase the speed of your PHP application. Make sure that &lt;code&gt;opcache_enable=1&lt;/code&gt; is uncommented in your &lt;code&gt;php.ini&lt;/code&gt; file. It will store the opcode for the executed files.&lt;/p&gt;

&lt;p&gt;But don't enable it in your dev environment ;) (unless you enable &lt;code&gt;opcache.validate_timestamps&lt;/code&gt; and set &lt;code&gt;opcache.revalidate_freq&lt;/code&gt; to 0 (thx u/iluuu))&lt;/p&gt;

&lt;p&gt;I recommend the &lt;a href="https://github.com/rlerdorf/opcache-status" rel="noopener noreferrer"&gt;opcache-status&lt;/a&gt; tool to monitor the use of opcache (at least in the beginning).&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%2Feee5algy9w72l0ea7j3x.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%2Feee5algy9w72l0ea7j3x.png" alt="opcache-status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use a template engine with cache
&lt;/h2&gt;

&lt;p&gt;Templating engines like &lt;a href="https://github.com/twigphp/Twig" rel="noopener noreferrer"&gt;Twig&lt;/a&gt; can create a cache of the generated PHP code. The speed gain here can be dramatic. Again, you only want to cache the templates in prod, not in dev. But make sure that the cache is setup. For Twig see the &lt;a href="https://twig.symfony.com/doc/2.x/api.html#compilation-cache" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Qualify standard functions
&lt;/h2&gt;

&lt;p&gt;Normally your code is namespaced (right?). So what happens when you call a function from the standard PHP library? The "compiler" (opcode producer) will look into the current namespace, then go up, and eventually use the global namespace. This means that if you add a "\" in front of standard functions (so effectively namespacing it in the global namespace explicitely), it will result in less opcode instructions, and that means faster code execution. Think it's one of those useless micro-optimization like the use of single vs. double quotes? You're correct, your app won't suddenly be faster (only very marginally), but if we can save CPU cycles, why not do it?&lt;/p&gt;

&lt;p&gt;Note also that I prefer to add &lt;code&gt;use function count;&lt;/code&gt; (for the &lt;code&gt;count()&lt;/code&gt; function) in the &lt;code&gt;use&lt;/code&gt; block, it's prettier than using &lt;code&gt;\&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;The little things I'm showing in this post won't make your app faster, at best it'll improve marginally. You can consider them as "good practice" because why not take some speed gains if you can, but if you want to get serious about optimizing your PHP app, get a profiler and optimize your SQL queries, because that's what is causing an issue, not the few milliseconds you might get with this kind of things ;)&lt;/p&gt;

&lt;p&gt;That's all folks, have fun coding!&lt;/p&gt;

&lt;p&gt;And if you like PHP, I'm always happy with contributions on the &lt;a href="https://github.com/elabftw/elabftw" rel="noopener noreferrer"&gt;eLabFTW project&lt;/a&gt;, an open source electronic lab notebook. =)&lt;/p&gt;

</description>
      <category>php</category>
      <category>composer</category>
      <category>twig</category>
      <category>speed</category>
    </item>
    <item>
      <title>Dependencies management in 2019: a review</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Sun, 03 Mar 2019 22:58:09 +0000</pubDate>
      <link>https://dev.to/elabftw/dependencies-management-in-2019-a-review-33nn</link>
      <guid>https://dev.to/elabftw/dependencies-management-in-2019-a-review-33nn</guid>
      <description>&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%2Fzl8baqn5rd8625irs1ep.jpg" 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%2Fzl8baqn5rd8625irs1ep.jpg" alt="dependencies" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello folks,&lt;/p&gt;

&lt;p&gt;The aim of this post is to make a (mostly) complete and accurate view of the different solutions available to you when you produce code and want to manage your dependencies like a boss, for different languages. We'll see how languages have different approaches to dependency management.&lt;/p&gt;

&lt;p&gt;I'll be writing about these 9 languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;Elixir&lt;/li&gt;
&lt;li&gt;Nim&lt;/li&gt;
&lt;li&gt;C#&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Let's start with an easy one: &lt;strong&gt;PHP&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Composer
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/composer" rel="noopener noreferrer"&gt;
        composer
      &lt;/a&gt; / &lt;a href="https://github.com/composer/composer" rel="noopener noreferrer"&gt;
        composer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Dependency Manager for PHP
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
    &lt;a href="https://getcomposer.org" rel="nofollow noopener noreferrer"&gt;
        &lt;img src="https://camo.githubusercontent.com/69545b92555ae5b2ca37c7ad5dfa5f60d72d24c70341b05f819a40d5523a3181/68747470733a2f2f676574636f6d706f7365722e6f72672f696d672f6c6f676f2d636f6d706f7365722d7472616e73706172656e742e706e67" alt="Composer"&gt;
    &lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Dependency Management for PHP&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Composer helps you declare, manage, and install dependencies of PHP projects.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://getcomposer.org/" rel="nofollow noopener noreferrer"&gt;https://getcomposer.org/&lt;/a&gt; for more information and documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/composer/composer/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/composer/composer/workflows/Continuous%20Integration/badge.svg?branch=main" alt="Continuous Integration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation / Usage&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Download and install Composer by following the &lt;a href="https://getcomposer.org/download/" rel="nofollow noopener noreferrer"&gt;official instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For usage, see &lt;a href="https://getcomposer.org/doc/" rel="nofollow noopener noreferrer"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Packages&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Find public packages on &lt;a href="https://packagist.org" rel="nofollow noopener noreferrer"&gt;Packagist.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For private package hosting take a look at &lt;a href="https://packagist.com" rel="nofollow noopener noreferrer"&gt;Private Packagist&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Community&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Follow &lt;a href="https://twitter.com/packagist" rel="nofollow noopener noreferrer"&gt;@packagist&lt;/a&gt; or &lt;a href="https://twitter.com/seldaek" rel="nofollow noopener noreferrer"&gt;@seldaek&lt;/a&gt; on Twitter for announcements, or check the &lt;a href="https://twitter.com/search?q=%23composerphp&amp;amp;src=typed_query&amp;amp;f=live" rel="nofollow noopener noreferrer"&gt;#composerphp&lt;/a&gt; hashtag.&lt;/p&gt;

&lt;p&gt;For support, Stack Overflow offers a good collection of
&lt;a href="https://stackoverflow.com/questions/tagged/composer-php" rel="nofollow noopener noreferrer"&gt;Composer related questions&lt;/a&gt;, or you can use the &lt;a href="https://github.com/composer/composer/discussions" rel="noopener noreferrer"&gt;GitHub discussions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please note that this project is released with a
&lt;a href="https://www.contributor-covenant.org/version/1/4/code-of-conduct/" rel="nofollow noopener noreferrer"&gt;Contributor Code of Conduct&lt;/a&gt;.
By participating in this project and its community you agree to abide by those terms.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Latest Composer&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;PHP 7.2.5 or above for the latest version.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Composer 2.2 LTS (Long Term Support)&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;PHP versions 5.3.2 - 8.1 are still supported via the…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/composer/composer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Composer is the &lt;em&gt;de facto&lt;/em&gt; standard for dependencies management in PHP. It's very hard today to get anything done in PHP without it. I recommend reading &lt;a href="https://medium.com/@tfidry/managing-your-dependencies-in-php-321d584441ab" rel="noopener noreferrer"&gt;this article&lt;/a&gt; from &lt;a href="https://medium.com/@tfidry" rel="noopener noreferrer"&gt;Théo Fidry&lt;/a&gt; if you want to know more about the limitations of composer and the workarounds (like using PHARs).&lt;/p&gt;

&lt;h2&gt;
  
  
  PEAR
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pear" rel="noopener noreferrer"&gt;
        pear
      &lt;/a&gt; / &lt;a href="https://github.com/pear/pear-core" rel="noopener noreferrer"&gt;
        pear-core
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is the definitive source of PEAR's core files.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="rst"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;PEAR - The PEAR Installer&lt;/h1&gt;
&lt;/div&gt;
&lt;a href="https://travis-ci.org/pear/pear-core" rel="nofollow noopener noreferrer"&gt;&lt;img alt="https://travis-ci.org/pear/pear-core.svg?branch=stable" src="https://camo.githubusercontent.com/2ced4818d132eb665c383b06664ab022440804017014a510b9b30eebe2ea791b/68747470733a2f2f7472617669732d63692e6f72672f706561722f706561722d636f72652e7376673f6272616e63683d737461626c65"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is the PEAR Installer? What is PEAR?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;PEAR is the PHP Extension and Application Repository, found at
&lt;a href="http://pear.php.net" rel="nofollow noopener noreferrer"&gt;http://pear.php.net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;PEAR Installer&lt;/strong&gt; is this software, which contains executable
files and PHP code that is used to &lt;strong&gt;download and install&lt;/strong&gt; PEAR code
from pear.php.net.&lt;/p&gt;
&lt;p&gt;PEAR contains useful &lt;strong&gt;software libraries and applications&lt;/strong&gt; such as
MDB2 (database abstraction), HTML_QuickForm (HTML forms management),
PhpDocumentor (auto-documentation generator), DB_DataObject
(Data Access Abstraction), and many hundreds more.
Browse all available packages at &lt;a href="http://pear.php.net" rel="nofollow noopener noreferrer"&gt;http://pear.php.net&lt;/a&gt;, the list is
constantly growing and updating to reflect improvements in the PHP language.&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;Warning&lt;/p&gt;
&lt;p&gt;Do not run PEAR without installing it - if you downloaded this
tarball manually, you MUST install it.  Read the instructions in INSTALL
prior to use.&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Documentation for PEAR can be found at &lt;a href="http://pear.php.net/manual/" rel="nofollow noopener noreferrer"&gt;http://pear.php.net/manual/&lt;/a&gt;.
Installation documentation can be found in the INSTALL file included
in this tarball.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Tests&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Run the…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pear/pear-core" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This is the old school player. It installs dependencies to the system. Only use it if your distribution is not shipping the extension in a package already. Note that you can use composer to install a PEAR package, see &lt;a href="https://phptherightway.com/#pear" rel="noopener noreferrer"&gt;this part&lt;/a&gt; of phptherightway for more.&lt;/p&gt;

&lt;p&gt;That's it for PHP. I'm pretty sure there are no other PHP dependencies management applications out there, but if I'm wrong please let me know in the comments section.&lt;/p&gt;

&lt;h1&gt;
  
  
  Second language: &lt;strong&gt;Python&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Pip
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pypa" rel="noopener noreferrer"&gt;
        pypa
      &lt;/a&gt; / &lt;a href="https://github.com/pypa/pip" rel="noopener noreferrer"&gt;
        pip
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The Python package installer
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="rst"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;pip - The Python Package Installer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://pypi.org/project/pip/" rel="nofollow noopener noreferrer"&gt;&lt;img alt="PyPI" src="https://camo.githubusercontent.com/08b2323eca8d03dc78847012206c948114fdcfa0eea71a46bcc3ffd71ac45cc9/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f7069702e737667"&gt;
&lt;/a&gt; &lt;a href="https://pypi.org/project/pip" rel="nofollow noopener noreferrer"&gt;&lt;img alt="PyPI - Python Version" src="https://camo.githubusercontent.com/34a0cdf2c025171d774f4de4e3621daa69de6e50dd405095fda70415bdaaa2fd/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f706970"&gt;&lt;/a&gt; &lt;a href="https://pip.pypa.io/en/latest" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Documentation" src="https://camo.githubusercontent.com/770228a823e8d1f96adbd08d9a21f148a97415c948175fb03a07b32c6672be31/68747470733a2f2f72656164746865646f63732e6f72672f70726f6a656374732f7069702f62616467652f3f76657273696f6e3d6c6174657374"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;pip is the &lt;a href="https://packaging.python.org/guides/tool-recommendations/" rel="nofollow noopener noreferrer"&gt;package installer&lt;/a&gt; for Python. You can use pip to install packages from the &lt;a href="https://pypi.org" rel="nofollow noopener noreferrer"&gt;Python Package Index&lt;/a&gt; and other indexes.&lt;/p&gt;
&lt;p&gt;Please take a look at our documentation for how to install and use pip:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/stable/installation/" rel="nofollow noopener noreferrer"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/stable/" rel="nofollow noopener noreferrer"&gt;Usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We release updates regularly, with a new version every 3 months. Find more details in our documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/stable/news.html" rel="nofollow noopener noreferrer"&gt;Release notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/latest/development/release-process/" rel="nofollow noopener noreferrer"&gt;Release process&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pypa/pip/issues" rel="noopener noreferrer"&gt;Issue tracking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discuss.python.org/c/packaging" rel="nofollow noopener noreferrer"&gt;Discourse channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa" rel="nofollow noopener noreferrer"&gt;User IRC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pypa/pip" rel="noopener noreferrer"&gt;GitHub page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/latest/development" rel="nofollow noopener noreferrer"&gt;Development documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev" rel="nofollow noopener noreferrer"&gt;Development IRC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Code of Conduct&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Everyone interacting in the pip project's codebases, issue trackers, chat
rooms, and mailing lists is expected…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pypa/pip" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;pip is the goto package manager for python, it has its drawbacks but is a very popular tool to install Python dependencies. BTW, you should &lt;a href="https://dev.to/elabftw/stop-using-sudo-pip-install-52mn"&gt;Stop using sudo pip install&lt;/a&gt;. Use pip with moderation (and the &lt;code&gt;--user&lt;/code&gt; flag!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Venv
&lt;/h2&gt;

&lt;p&gt;The official module for managing your project's dependencies inside a virtual environment, thus not polluting the rest of the OS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtualenv
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pypa" rel="noopener noreferrer"&gt;
        pypa
      &lt;/a&gt; / &lt;a href="https://github.com/pypa/virtualenv" rel="noopener noreferrer"&gt;
        virtualenv
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Virtual Python Environment builder
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;virtualenv&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://pypi.org/project/virtualenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/60bd6e054fb67a8170c51e0f23d0593d8ce08462a63dc8f9155680ae99fa8a11/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f7669727475616c656e763f7374796c653d666c61742d737175617265" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/virtualenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cb8d46ad004772e19a22eb14f3c6db5d790b85e8d580c9814d5f5dc4ae658dca/68747470733a2f2f696d672e736869656c64732e696f2f707970692f696d706c656d656e746174696f6e2f7669727475616c656e763f7374796c653d666c61742d737175617265" alt="PyPI - Implementation"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/virtualenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8acbae04a29bf0336984705b669eb737496c440cf993d5aa304c98eacce04277/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f7669727475616c656e763f7374796c653d666c61742d737175617265" alt="PyPI - Python Version"&gt;&lt;/a&gt;
&lt;a href="http://virtualenv.pypa.io" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5fcf8271a4ace493af675598a928ec63507ec295f8e81d5d5c2d9b49d7f17960/68747470733a2f2f72656164746865646f63732e6f72672f70726f6a656374732f7669727475616c656e762f62616467652f3f76657273696f6e3d6c6174657374267374796c653d666c61742d737175617265" alt="Documentation"&gt;&lt;/a&gt;
&lt;a href="https://discord.gg/pypa" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b3c40baca3a37d232c92523ca450f624d39c5898f0e10c44d21523de0613fc22/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f383033303235313137353533373534313332" alt="Discord"&gt;&lt;/a&gt;
&lt;a href="https://pepy.tech/project/virtualenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1317ccdce597f9787cf0caade01082d132f0842c07378a9b20fbf8530226cc7f/68747470733a2f2f7374617469632e706570792e746563682f62616467652f7669727475616c656e762f6d6f6e7468" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5c8cd8ca877966595bc01e79fba551817c4d4e462142ecdaae914005e083a627/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f7669727475616c656e763f7374796c653d666c61742d737175617265" alt="PyPI - License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/pypa/virtualenv/actions/workflows/check.yaml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/pypa/virtualenv/actions/workflows/check.yaml/badge.svg" alt="check"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A tool for creating isolated &lt;code&gt;virtual&lt;/code&gt; python environments.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://virtualenv.pypa.io/en/latest/installation.html" rel="nofollow noopener noreferrer"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://virtualenv.pypa.io" rel="nofollow noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://virtualenv.pypa.io/en/latest/changelog.html" rel="nofollow noopener noreferrer"&gt;Changelog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pypa/virtualenv/issues" rel="noopener noreferrer"&gt;Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/virtualenv" rel="nofollow noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pypa/virtualenv" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Code of Conduct&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Everyone interacting in the virtualenv project's codebases, issue trackers, chat rooms, and mailing lists is expected to
follow the &lt;a href="https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;PSF Code of Conduct&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pypa/virtualenv" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;This project started in 2011 and is very useful to isolate dependencies for a project. Part of this project is now &lt;code&gt;venv&lt;/code&gt; in the standard python library. So you can think of &lt;code&gt;virtualvenv&lt;/code&gt; as a more feature complete &lt;code&gt;venv&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipenv
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pypa" rel="noopener noreferrer"&gt;
        pypa
      &lt;/a&gt; / &lt;a href="https://github.com/pypa/pipenv" rel="noopener noreferrer"&gt;
        pipenv
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
       Python Development Workflow for Humans.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pipenv: Python Development Workflow for Humans&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://python.org/pypi/pipenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2fa6af91beddb73b95ef8897fe1cdb43fe3c49cf018c2f20ad2fa1505becc37e/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f706970656e762e737667" alt="image"&gt;&lt;/a&gt;
&lt;a href="https://python.org/pypi/pipenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cecf98561bdcfe4e3c3a848221cc810dd7c9632b9a3e4f68e7b7c498f438c510/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f706970656e762e737667" alt="image"&gt;&lt;/a&gt;
&lt;a href="https://github.com/pypa/pipenv/actions/workflows/ci.yaml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/pypa/pipenv/actions/workflows/ci.yaml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://python.org/pypi/pipenv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/961fb6ccbdc851012989a652e5cad82259f35067774a21118b331e51d416a805/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f706970656e762e737667" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pipenv&lt;/strong&gt; is a Python virtualenv management tool that supports a multitude of systems and nicely bridges the gaps between pip, python (using system python, pyenv or asdf) and virtualenv
&lt;em&gt;Linux, macOS, and Windows are all first-class citizens in pipenv.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Pipenv automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your &lt;code&gt;Pipfile&lt;/code&gt; as you install/uninstall packages. It also generates a project &lt;code&gt;Pipfile.lock&lt;/code&gt;, which is used to produce deterministic builds.&lt;/p&gt;
&lt;p&gt;Pipenv is primarily meant to provide users and developers of applications with an easy method to arrive at a consistent working project environment.&lt;/p&gt;
&lt;p&gt;The problems that Pipenv seeks to solve are multi-faceted:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You no longer need to use &lt;code&gt;pip&lt;/code&gt; and &lt;code&gt;virtualenv&lt;/code&gt; separately: they work together.&lt;/li&gt;
&lt;li&gt;Managing a &lt;code&gt;requirements.txt&lt;/code&gt; file with package hashes can be problematic.  Pipenv uses &lt;code&gt;Pipfile&lt;/code&gt; and &lt;code&gt;Pipfile.lock&lt;/code&gt; to separate abstract dependency declarations from the last tested…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pypa/pipenv" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Pipenv started in early 2017 and was very quickly popular. It's my favorite, too. It works very similarly to &lt;code&gt;composer&lt;/code&gt; with a lockfile and all the dependencies are installed in a special folder. To run the script in the environment, you need to prepend &lt;code&gt;pipenv run&lt;/code&gt;. See &lt;a href="https://dev.to/elabftw/stop-using-sudo-pip-install-52mn"&gt;my previous post about it&lt;/a&gt;. Note that &lt;a href="https://packaging.python.org/tutorials/managing-dependencies/" rel="noopener noreferrer"&gt;the official Python doc&lt;/a&gt; is recommending &lt;code&gt;pipenv&lt;/code&gt; for managing dependencies.&lt;/p&gt;

&lt;p&gt;Something interesting to note, is that all of the above-mentioned projects are all hosted in the &lt;a href="https://github.com/pypa" rel="noopener noreferrer"&gt;github.com/pypa&lt;/a&gt; namespace, the &lt;a href="https://www.pypa.io/en/latest/" rel="noopener noreferrer"&gt;Python Package Authority&lt;/a&gt;, a group dedicated to maintaining the python packagers. I think it's nice to have this kind of "authority" for improving the ecosystem in Python.&lt;/p&gt;

&lt;h1&gt;
  
  
  The third language we'll talk about is: &lt;strong&gt;Rust&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Cargo
&lt;/h2&gt;

&lt;p&gt;Well, here it's a nobrainer, because (AFAIK) there is only one solution, and it's &lt;code&gt;Cargo&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rust-lang" rel="noopener noreferrer"&gt;
        rust-lang
      &lt;/a&gt; / &lt;a href="https://github.com/rust-lang/cargo" rel="noopener noreferrer"&gt;
        cargo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The Rust package manager
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Cargo&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Cargo downloads your Rust project’s dependencies and compiles your project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To start using Cargo&lt;/strong&gt;, learn more at &lt;a href="https://doc.rust-lang.org/cargo/" rel="nofollow noopener noreferrer"&gt;The Cargo Book&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To start developing Cargo itself&lt;/strong&gt;, read the &lt;a href="https://rust-lang.github.io/cargo/contrib/" rel="nofollow noopener noreferrer"&gt;Cargo Contributor Guide&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Cargo binary distributed through with Rust is maintained by the Cargo
team for use by the wider ecosystem
For all other uses of this crate (as a binary or library) this is maintained
by the Cargo team, primarily for use by Cargo and not intended for external
use (except as a transitive dependency). This crate may make major changes to
its APIs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Code Status&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/rust-lang/cargo/actions/workflows/main.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/rust-lang/cargo/actions/workflows/main.yml/badge.svg?branch=auto-cargo" alt="CI"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Code documentation: &lt;a href="https://doc.rust-lang.org/nightly/nightly-rustc/cargo/" rel="nofollow noopener noreferrer"&gt;https://doc.rust-lang.org/nightly/nightly-rustc/cargo/&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Compiling from Source&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Requirements&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Cargo requires the following tools and packages to build:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cargo&lt;/code&gt; and &lt;code&gt;rustc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A C compiler &lt;a href="https://github.com/rust-lang/cc-rs#compile-time-requirements" rel="noopener noreferrer"&gt;for your platform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git&lt;/code&gt; (to clone this repository)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Other requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The following are optional based on your platform and needs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;pkg-config&lt;/code&gt; — This is used to help locate…&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rust-lang/cargo" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Cargo is great. Cargo is shit. YMMV. Honestly, it's pretty cool to have one official tool for dependencies management, at least it saves you the time you would have spent choosing one! It installs dependencies per-project but can also be used for system-wide packages. Interestingly, it uses the &lt;a href="https://github.com/toml-lang/toml" rel="noopener noreferrer"&gt;TOML&lt;/a&gt; syntax for the configuration file, whereas other projects chose YAML or JSON.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's move on to the fourth language: &lt;strong&gt;Go&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;go get&lt;/code&gt; is is the way to install a dependency in Go. But the issue is that it'll be installed system-wide (in $GOPATH). Say hello to conflicts and breaking changes because you can only have one version of a lib…&lt;/p&gt;

&lt;p&gt;This led to other approaches like git submodules or project specific $GOPATH and a lot of developers being angry at Go.&lt;/p&gt;

&lt;p&gt;However, with Go version 1.11 (released in August 2018) there is now something called &lt;code&gt;modules&lt;/code&gt;. Check out the &lt;a href="https://github.com/golang/go/wiki/Modules" rel="noopener noreferrer"&gt;wiki page&lt;/a&gt; to know more about Go modules. I believe this will be the future of Go dependencies management, because fuck system-wide dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  What do I see? Is that the fifth language? Yep: &lt;strong&gt;Javascript&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Aaaaahhh, javascript and the dependencies, what a wonderful world! :)&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%2Fl6a5kicipp2mjm6cy3ld.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%2Fl6a5kicipp2mjm6cy3ld.png" alt="node_modules" width="500" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Npm
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/npm" rel="noopener noreferrer"&gt;
        npm
      &lt;/a&gt; / &lt;a href="https://github.com/npm/cli" rel="noopener noreferrer"&gt;
        cli
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      the package manager for JavaScript
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;npm - a JavaScript package manager&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Requirements&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;You should be running a currently supported version of &lt;a href="https://nodejs.org/en/download/" rel="nofollow noopener noreferrer"&gt;Node.js&lt;/a&gt; to run &lt;strong&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/strong&gt;.  For a list of which versions of Node.js are currently supported, please see the &lt;a href="https://nodejs.org/en/about/previous-releases" rel="nofollow noopener noreferrer"&gt;Node.js releases&lt;/a&gt; page.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/strong&gt; comes bundled with &lt;a href="https://nodejs.org/" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;&lt;code&gt;node&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;, &amp;amp; most third-party distributions, by default. Officially supported downloads/distributions can be found at: &lt;a href="https://nodejs.org/en/download" rel="nofollow noopener noreferrer"&gt;nodejs.org/en/download&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Direct Download&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;You can download &amp;amp; install &lt;strong&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/strong&gt; directly from &lt;a href="https://npmjs.com/" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;npmjs&lt;/strong&gt;.com&lt;/a&gt; using our custom &lt;code&gt;install.sh&lt;/code&gt; script:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;curl -qL https://www.npmjs.com/install.sh &lt;span class="pl-k"&gt;|&lt;/span&gt; sh&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Node Version Managers&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;If you're looking to manage multiple versions of &lt;strong&gt;&lt;code&gt;Node.js&lt;/code&gt;&lt;/strong&gt; &amp;amp;/or &lt;strong&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/strong&gt;, consider using a &lt;a href="https://github.com/search?q=node+version+manager+archived%3Afalse&amp;amp;type=repositories&amp;amp;ref=advsearch" rel="noopener noreferrer"&gt;node version manager&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Usage&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm &lt;span class="pl-k"&gt;&amp;lt;&lt;/span&gt;command&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Links &amp;amp; Resources&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.npmjs.com/" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/a&gt; - Official docs &amp;amp; how-tos for all things &lt;strong&gt;npm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Note: you can also search docs locally with &lt;code&gt;npm help-search &amp;lt;query&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/npm/cli/issues" rel="noopener noreferrer"&gt;&lt;strong&gt;Bug Tracker&lt;/strong&gt;&lt;/a&gt; - Search or submit bugs against the CLI&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/orgs/github/projects/4247/views/1?filterQuery=npm" rel="noopener noreferrer"&gt;&lt;strong&gt;Roadmap&lt;/strong&gt;&lt;/a&gt; - Track &amp;amp; follow along with our public…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/npm/cli" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Everyone knows &lt;code&gt;npm&lt;/code&gt;. You define your dependencies in a &lt;code&gt;package.json&lt;/code&gt; and install them in the &lt;code&gt;node_modules&lt;/code&gt; folder. Since version 5, there is a &lt;code&gt;package-lock.json&lt;/code&gt; allowing you to have reproducible builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yarn
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yarnpkg" rel="noopener noreferrer"&gt;
        yarnpkg
      &lt;/a&gt; / &lt;a href="https://github.com/yarnpkg/yarn" rel="noopener noreferrer"&gt;
        yarn
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The 1.x line is frozen - features and bugfixes now happen on https://github.com/yarnpkg/berry
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;ℹ️ Important note&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This repository holds the sources for Yarn 1.x (latest version at the time of this writing being 1.22). New releases (at this time the 3.2.3, although we're currently working on our next major) are tracked on the &lt;a href="https://github.com/yarnpkg/berry" rel="noopener noreferrer"&gt;yarnpkg/berry&lt;/a&gt; repository, this one here being mostly kept for historical purposes and the occasional hotfix we publish to make the migration from 1.x to later releases easier.&lt;/p&gt;
&lt;p&gt;If you hit bugs or issues with Yarn 1.x, we strongly suggest you &lt;a href="https://yarnpkg.com/getting-started/migration" rel="nofollow noopener noreferrer"&gt;migrate&lt;/a&gt; to the latest release - at this point they have been maintained longer than 1.x, and many classes of problems have already been addressed there. By using the &lt;a href="https://yarnpkg.com/configuration/yarnrc#nodeLinker" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;nodeLinker&lt;/code&gt; setting&lt;/a&gt; you'll also have the choice of how you want to install your packages: node_modules like npm, symlinks like pnpm, or manifest files via &lt;a href="https://yarnpkg.com/features/pnp" rel="nofollow noopener noreferrer"&gt;Yarn PnP&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
  Fast, reliable, and secure dependency management
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://circleci.com/gh/yarnpkg/yarn" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Circle Status" src="https://camo.githubusercontent.com/706225300151cff4c499419b130b9e1ac7781b3fb51acdea14e1491b0cfaf8a3/68747470733a2f2f636972636c6563692e636f6d2f67682f7961726e706b672f7961726e2e7376673f7374796c653d736869656c6426636972636c652d746f6b656e3d35663061373834373362306634343061666232313862663262383233323363633662336362343366"&gt;&lt;/a&gt;
  &lt;a href="https://ci.appveyor.com/project/kittens/yarn/branch/master" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Appveyor Status" src="https://camo.githubusercontent.com/237b6f64eb9015968faaccd6f2a816c805fbf529f754b62755677b8549b34389/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f307864763863687765326b6d6b3436333f7376673d74727565"&gt;&lt;/a&gt;
  &lt;a href="https://dev.azure.com/yarnpkg/yarn/_build" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Azure Pipelines status" src="https://camo.githubusercontent.com/9ad54075789225215442414927fb0b406636196f020a5c5a8b765f0ea13b9a4b/68747470733a2f2f6465762e617a7572652e636f6d2f7961726e706b672f7961726e2f5f617069732f6275696c642f7374617475732f5961726e253230416363657074616e63652532305465737473"&gt;&lt;/a&gt;
  &lt;a href="https://discord.gg/yarnpkg" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Discord Chat" src="https://camo.githubusercontent.com/28c515214e0a851d7a9d9638129ff4db4987a0515a7902c2b007b2e76b2cd8c7/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3232363739313430353538393233333636342e737667"&gt;&lt;/a&gt;
  &lt;a href="http://commitizen.github.io/cz-cli/" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Commitizen friendly" src="https://camo.githubusercontent.com/1d01d79de532fa2a8b9d3e1c29e2b5d6f700b6d36f108c8416faca472cb35b6f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6d6d6974697a656e2d667269656e646c792d627269676874677265656e2e737667"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Fast:&lt;/strong&gt; Yarn caches every package it has…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yarnpkg/yarn" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Yarn had reproducible builds well before &lt;code&gt;npm&lt;/code&gt;. It also doesn't suffer from the sometimes poor decisions taken by npm's project leaders. It's fast, works well. It's my tool of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bower
&lt;/h2&gt;

&lt;p&gt;Come on now! We said 2019 in the title! Forget about &lt;code&gt;bower&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will not talk about &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; or &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt; as these are bundlers, not package managers.&lt;/p&gt;

&lt;p&gt;Note that you can use either &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt; with the exact same &lt;code&gt;package.json&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;One thing to note about packages in javascript, is that it has become completely crazy, with micro libraries consisting of one line of code more or less, being used by hundred of thousands of other packages. For fun, go into a Javascript project and try this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls node_modules | grep '^is*'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;How fun is it to have &lt;code&gt;is-obj&lt;/code&gt;, &lt;code&gt;is-object&lt;/code&gt;, &lt;code&gt;is-plain-obj&lt;/code&gt;, &lt;code&gt;is-plain-object&lt;/code&gt; or things like &lt;code&gt;isarray&lt;/code&gt;, but also &lt;code&gt;is-arrayish&lt;/code&gt;… Do we really need a package &lt;code&gt;is-windows&lt;/code&gt; when all it does is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;return process &amp;amp;&amp;amp; (process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE));&lt;/code&gt; ?&lt;/p&gt;

&lt;p&gt;And good luck if you want to look at the code of all of these libraries for your project. That lead to the &lt;a href="https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/" rel="noopener noreferrer"&gt;left-pad chaos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So my advice here is to think hard before installing a javascript dependency, as it might come with hundred of these little library, and one day, one of them will become malicious (see &lt;a href="https://www.npmjs.com/advisories" rel="noopener noreferrer"&gt;malicious packages on npmjs.com&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You can use &lt;a href="https://github.com/depcheck/depcheck" rel="noopener noreferrer"&gt;Depcheck&lt;/a&gt; to try and cleanup a bit your dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's talk about a more exciting language, like: &lt;strong&gt;Elixir&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Elixir is a bit like Rust when it comes to dependency management: one official tool that gets the job done: &lt;a href="https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html" rel="noopener noreferrer"&gt;Mix&lt;/a&gt; (or &lt;a href="https://hex.pm" rel="noopener noreferrer"&gt;Hex&lt;/a&gt; for Erlang). Nothing more to say here, it works well enough and lets you focus on other things.&lt;/p&gt;

&lt;p&gt;Okay so what do we have left? &lt;strong&gt;Nim&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nim-lang.org/" rel="noopener noreferrer"&gt;Nim&lt;/a&gt; is a pretty new and cool language, and the name of the package manager is sooooo cute &amp;lt;3: &lt;a href="https://github.com/nim-lang/nimble" rel="noopener noreferrer"&gt;Nimble&lt;/a&gt;. Which reminds me of this guy:&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%2Fu9r008dyo8hfp7w7ddqo.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%2Fu9r008dyo8hfp7w7ddqo.png" alt="Nibbler" width="373" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing to see here, just use the one provided and get coding!&lt;/p&gt;

&lt;h1&gt;
  
  
  The next language is &lt;strong&gt;C#&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Nuget
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NuGet" rel="noopener noreferrer"&gt;
        NuGet
      &lt;/a&gt; / &lt;a href="https://github.com/NuGet/NuGet.Client" rel="noopener noreferrer"&gt;
        NuGet.Client
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Client Tools for NuGet - including Visual Studio extensions, command line tools, and msbuild support. (Open issues on https://github.com/nuget/home/issues)
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/NuGet/Home/dev/meta/resources/nuget.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNuGet%2FHome%2Fdev%2Fmeta%2Fresources%2Fnuget.png" alt="NuGet logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;NuGet Client Tools&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;This repo contains the following clients:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/nuget/tools/nuget-exe-cli-reference" rel="nofollow noopener noreferrer"&gt;NuGet CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/nuget/tools/package-manager-ui" rel="nofollow noopener noreferrer"&gt;NuGet Package Manager for Visual Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/nuget/tools/powershell-reference" rel="nofollow noopener noreferrer"&gt;PowerShell CmdLets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet" rel="nofollow noopener noreferrer"&gt;NuGet functionality for dotnet.exe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Open Source Code of Conduct&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This project has adopted the &lt;a href="https://opensource.microsoft.com/codeofconduct/" rel="nofollow noopener noreferrer"&gt;Microsoft Open Source Code of Conduct&lt;/a&gt;. For more information see the &lt;a href="https://opensource.microsoft.com/codeofconduct/faq/" rel="nofollow noopener noreferrer"&gt;Code of Conduct FAQ&lt;/a&gt; or contact &lt;a href="https://github.com/NuGet/NuGet.Clientmailto:opencode@microsoft.com" rel="noopener noreferrer"&gt;opencode@microsoft.com&lt;/a&gt; with any additional questions or comments.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started guide&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;For how to contribute to this repo follow the &lt;a href="https://github.com/NuGet/NuGet.ClientCONTRIBUTING.md" rel="noopener noreferrer"&gt;Contributing doc&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;NuGet/Home repo&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The &lt;a href="https://github.com/nuget/Home" rel="noopener noreferrer"&gt;NuGet/Home&lt;/a&gt; repo is the starting point for all things NuGet. It has the &lt;a href="https://github.com/nuget/home/issues" rel="noopener noreferrer"&gt;issue tracker&lt;/a&gt; and &lt;a href="https://github.com/nuget/home" rel="noopener noreferrer"&gt;basic information&lt;/a&gt; about all things NuGet. Make sure to consult it before beginning your journey through NuGet code.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Feedback&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;File NuGet.Client bugs in the &lt;a href="https://github.com/nuget/home/issues" rel="noopener noreferrer"&gt;NuGet/Home&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Unless explicitly stated otherwise all files in this repository are licensed under the License in the root repository&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NuGet/NuGet.Client" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;This is the standard package manager that comes with Visual Studio. It exists since 2010 and is developed by the .NET foundation. I don't have much more to say about it because it's really windowsy and that's clearly not my platform of choice when it comes to anything vaguely related to computing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Last but not least: &lt;strong&gt;Ruby&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Rubygem
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rubygems" rel="noopener noreferrer"&gt;
        rubygems
      &lt;/a&gt; / &lt;a href="https://github.com/rubygems/rubygems" rel="noopener noreferrer"&gt;
        rubygems
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Library packaging and distribution for Ruby.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;RubyGems&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;RubyGems is a package management framework for Ruby.&lt;/p&gt;
&lt;p&gt;A package (also known as a library) contains a set of functionality that can be invoked by a Ruby program, such as reading and parsing an XML file
We call these packages "gems" and RubyGems is a tool to install, create, manage and load these packages in your Ruby environment.&lt;/p&gt;
&lt;p&gt;RubyGems is also a client for &lt;a href="https://rubygems.org" rel="nofollow noopener noreferrer"&gt;RubyGems.org&lt;/a&gt;, a public repository of Gems that allows you to publish a Gem
that can be shared and used by other developers. See our guide on publishing a Gem at &lt;a href="https://guides.rubygems.org/publishing/" rel="nofollow noopener noreferrer"&gt;guides.rubygems.org&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Installing and managing a Gem is done through the &lt;code&gt;gem&lt;/code&gt; command. To install a Gem such as &lt;a href="https://github.com/lostisland/faraday?tab=readme-ov-file" rel="noopener noreferrer"&gt;Faraday&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;gem install faraday&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;RubyGems will download the Faraday Gem from RubyGems.org and install it into your Ruby environment.&lt;/p&gt;
&lt;p&gt;Finally, inside your Ruby program, load the Faraday gem and start hacking:&lt;/p&gt;
&lt;div class="highlight highlight-source-ruby notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-en"&gt;require&lt;/span&gt; &lt;span class="pl-s"&gt;'faraday'&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rubygems/rubygems" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This is the standard way to get dependencies for a ruby project. It can be seen as &lt;code&gt;pip&lt;/code&gt; for ruby, because it installs packages system-wide. You can install them for your user with the &lt;code&gt;--user-install&lt;/code&gt; flag (better: add &lt;code&gt;gem: --user-install&lt;/code&gt; to &lt;code&gt;~/.gemrc&lt;/code&gt; to always install gems in your home).&lt;/p&gt;

&lt;p&gt;So what about managing dependencies per-project you'll ask?&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundler: a gem to bundle gems
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rubygems" rel="noopener noreferrer"&gt;
        rubygems
      &lt;/a&gt; / &lt;a href="https://github.com/rubygems/bundler" rel="noopener noreferrer"&gt;
        bundler
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Manage your Ruby application's gem dependencies
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;strong&gt;Bundler is now maintained in the &lt;a href="https://github.com/rubygems/rubygems" rel="noopener noreferrer"&gt;rubygems/rubygems&lt;/a&gt; repository.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rubygems.org/gems/bundler" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f9e95c0843a11208d31016c772fce2b5c39b6f7dcf4591777ddf33c33dea4a58/68747470733a2f2f696d672e736869656c64732e696f2f67656d2f762f62756e646c65722e7376673f7374796c653d666c6174" alt="Version     "&gt;&lt;/a&gt;
&lt;a href="https://inch-ci.org/github/rubygems/bundler" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/be45f3c4acf0697ca448a4738496692439d8315f85f2385b4b6a2aa3cc15879a/68747470733a2f2f696e63682d63692e6f72672f6769746875622f7275627967656d732f62756e646c65722e7376673f7374796c653d666c6174" alt="Inline docs "&gt;&lt;/a&gt;
&lt;a href="https://bundler-slackin.herokuapp.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/381d356f5cd6ac338650b417583a85c8fbf54e3384e8548c04e6674dd6ce0a50/68747470733a2f2f62756e646c65722d736c61636b696e2e6865726f6b756170702e636f6d2f62616467652e737667" alt="Slack       "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Bundler: a gem to bundle gems&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Bundler makes sure Ruby applications run the same code on every machine.&lt;/p&gt;
&lt;p&gt;It does this by managing the gems that the application depends on. Given a list of gems, it can automatically download and install those gems, as well as any other gems needed by the gems that are listed. Before installing gems, it checks the versions of every gem to make sure that they are compatible, and can all be loaded at the same time. After the gems have been installed, Bundler can help you update some or all of them when new versions become available. Finally, it records the exact versions that have been installed, so that others can install the exact same gems.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation and usage&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;To install (or update to the latest version):&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;gem install bundler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To install a prerelease version (if…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rubygems/bundler" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You get a &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;Gemfile.lock&lt;/code&gt; file, and you're sure the project will run everywhere with the same versions of gems.&lt;/p&gt;

&lt;p&gt;But there is something interesting about the ruby ecosystem: it exists a lot more projects to switch between different ruby versions (chruby, rbenv, rvm, uru) than to install dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As you can see, some languages have it all figured out for you (rust, nim), while for others you need to make a choice (python, javascript), and for some you have system-wide and project-wide solutions (python, ruby). I don't quite understand why Go, a "recent" language didn't do a better job at dependency management. But this fits well with the view that "Go was created like we were still in the 70's".&lt;/p&gt;

&lt;h1&gt;
  
  
  Take home messages
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install your dependencies per project with a reproducible build (lock down versions of packages) to avoid surprises and to get something portable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to avoid installing too many dependencies (javascript, I'm looking at you!).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't ship the dependencies with your project but ship the lockfile ;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's all folks, please leave a comment if you think I forgot something important or if I got something wrong ;)&lt;/p&gt;

&lt;p&gt;Have fun coding!&lt;/p&gt;

</description>
      <category>dependencies</category>
      <category>review</category>
      <category>programming</category>
    </item>
    <item>
      <title>Improving the python REPL (autoload modules and history)</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Wed, 24 Oct 2018 10:36:14 +0000</pubDate>
      <link>https://dev.to/elabftw/improving-the-python-repl-autoload-modules-and-history-21m1</link>
      <guid>https://dev.to/elabftw/improving-the-python-repl-autoload-modules-and-history-21m1</guid>
      <description>

&lt;p&gt;Hello to you dear reader,&lt;/p&gt;

&lt;p&gt;When doing python code, it might be useful to fire up the REPL (Read-Eval-Print-Loop) by simply typing &lt;code&gt;python&lt;/code&gt; in a terminal to test some expressions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://xkcd.com/353/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v7YYsAut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bp097fdsajiylou0ak7u.png" alt="python"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the problem is that it is very barebone. No history, no modules loaded by default. I don't know about you but 99% of the time I'll need to use &lt;code&gt;numpy&lt;/code&gt; and &lt;code&gt;pandas&lt;/code&gt; at the minimum. Probably &lt;code&gt;matplotlib&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who has time to type &lt;code&gt;import xyz&lt;/code&gt; every time? Not me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So here is how to autoload modules in python's REPL:&lt;/p&gt;

&lt;h2&gt;
  
  
  Start by creating a ~/.pystartup file
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;As you can see, this file will also configure the &lt;code&gt;~/.pyhistory&lt;/code&gt; file so python doesn't forget everything when you close the REPL.&lt;/p&gt;

&lt;p&gt;It is recommended to install these often used modules with &lt;code&gt;pip install --user module-name&lt;/code&gt;, see my previous post: &lt;a href="https://dev.to/elabftw/stop-using-sudo-pip-install-52mn"&gt;Stop using sudo pip install&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the PYTHONSTARTUP env var
&lt;/h2&gt;

&lt;p&gt;Add this to your ~/.zshrc, ~/.fishrc, ~/.bashrc or whatever you use:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Note that '~' is not expanded, so use the full path here&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PYTHONSTARTUP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/user/.pystartup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it, now try again to fire up &lt;code&gt;python&lt;/code&gt; and check that the modules are there.&lt;/p&gt;

&lt;p&gt;There you go :) Now go write so amazing code!&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
~Nico&lt;/p&gt;


</description>
      <category>python</category>
      <category>productivity</category>
      <category>tipsandtricks</category>
    </item>
    <item>
      <title>Stop using sudo pip install</title>
      <dc:creator>eLabFTW</dc:creator>
      <pubDate>Wed, 17 Oct 2018 21:23:48 +0000</pubDate>
      <link>https://dev.to/elabftw/stop-using-sudo-pip-install-52mn</link>
      <guid>https://dev.to/elabftw/stop-using-sudo-pip-install-52mn</guid>
      <description>&lt;p&gt;We've all done it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;numpy
&lt;span class="c"&gt;# run into permissions issues&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;numpy &lt;span class="c"&gt;# or "sudo !!" for the power users ;)&lt;/span&gt;
~~~&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt;

End of story, it works, it&lt;span class="s1"&gt;'s what is written in the README so what'&lt;/span&gt;s wrong with it?

You see, when you &lt;span class="nb"&gt;install &lt;/span&gt;a library through pip, you are executing &lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;setup.py&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt; with root permissions. This file could harbor malicious code. You are also messing with the system libraries and that invariably leads to issues down the line.

Relevant XKCD &lt;span class="o"&gt;(&lt;/span&gt;thx u/truh&lt;span class="o"&gt;)&lt;/span&gt;:

&lt;span class="o"&gt;![&lt;/span&gt;xkcd]&lt;span class="o"&gt;(&lt;/span&gt;https://imgs.xkcd.com/comics/python_environment.png&lt;span class="o"&gt;)&lt;/span&gt;

A much better and secure way would be:&lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;

~~~bash
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; numpy &lt;span class="c"&gt;# libs will be installed in ~/.local/lib&lt;/span&gt;
~~~&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt;

This is better, and can be used &lt;span class="k"&gt;for &lt;/span&gt;installing applications, but it doesn&lt;span class="s1"&gt;'t solve the problem of having different versions needs for different python projects. Enter [pipenv](https://pipenv.readthedocs.io/en/latest/). {% raw %}`pipenv` is to python what `composer` is to PHP. It lets you **easily** install and use libraries per project. It'&lt;/span&gt;s not the only tool allowing you to &lt;span class="k"&gt;do &lt;/span&gt;that, but it&lt;span class="s1"&gt;'s the one I use so it'&lt;/span&gt;s the one I&lt;span class="s1"&gt;'m gonna present you. Example:

~~~bash
pipenv install numpy matplotlib pandas
# to start your program
pipenv run ./crunch-data.py
# to install libs from another machine, after a git pull:
pipenv sync
# to get a shell in the env (like `source myenv/bin/activate` for venv)
pipenv shell
~~~

This allows a very reproducible environment for your program, without resorting to Docker and without messing up user or system libraries. Save yourself from future bugs and start using pipenv, venv, conda or virtualenv right away! It'&lt;/span&gt;s much better than &lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;requirements.txt&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt; + pip. :&lt;span class="o"&gt;)&lt;/span&gt;

Cheers,
~Nico
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>goodpractices</category>
      <category>dependencies</category>
    </item>
  </channel>
</rss>
