Vim is definitely one of the most venerated text editors in the Unix world. Although its learning curve can be pretty steep when accustomed to more traditional text editors, its usage can dramatically improve productivity. A lot of plugins are available for the editor; almost always their source code is hosted on Github or similar platforms based on Git. To manage such plugins, several third-party plugin managers were developed in time, such as Pathogen or Vim-Plug, but since version 8 of the editor, a native way to manage plugins was introduced.
In this tutorial we are going to see how to manage Vim plugins natively using Packages.
In this tutorial you will learn:
- How to check Vim version
- How to manage plugins natively
- How to load plugins automatically
- How to load plugins on demand

Software requirements and conventions used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Distribution-independent |
Software | Vim >= 8 |
Other | None |
Conventions | # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux-commands to be executed as a regular non-privileged user |
Introduction
Vim needs no introductions: it is based on the classical Vi editor (Vim literally stands for V-IMproved), and is one of the most iconic text editors in the Unix world. There is a lot Vim can do out of the box (we covered the editor basics in this tutorial), but its functionalities can be extended further via plugins. Several plugins are available for Vim; most of the time their source code is hosted on Github, and their development is managed via the Git version control system. To better organize and integrate them into the editor, several “plugin managers” were created, such as Pathogen or Vim-plugged. Some of them, like the former, are very simple: what they do is basically to allow us hosting each plugin in its dedicated directory, which is added to the Vim runtime path; others, like the latter, are more complex, and are able to manage plugins similarly to how package managers handle software packages on Linux distributions.
Since version 8 was released, a native way to organize plugins was introduced and integrated into Vim. Its approach is similar to the one used by Pathogen. Let’s see how it works.
Checking if Vim supports packages
Support for Packages (that is how the feature is called), as we already said, was introduced starting from version 8 of Vim. The functionality must be enabled when the editor is compiled from source and almost certainly the Vim binary available in the repositories of our favorite Linux distribution was built this way. How can verify it?
To get information about the version of Vim we are using and the flags it was compiled with, all we have to do is to launch the following command:
$ vim --version
In the output of the command we can easily spot the available features, since they are preceded by a “+” (the missing ones are preceded by a “-“, instead). What we want to check, in this case, is the status of the “packages” flag. As you can see, in this case, the version of Vim I am using is 8.2, and the feature is enabled:
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Apr 22 2022 00:00:00) Included patches: 1-4804 Modified by <bugzilla@redhat.com> Compiled by <bugzilla@redhat.com> Huge version without GUI. Features included (+) or not (-): +acl +file_in_path +mouse_urxvt -tag_any_white +arabic +find_in_path +mouse_xterm -tcl +autocmd +float +multi_byte +termguicolors +autochdir +folding +multi_lang +terminal -autoservername -footer -mzscheme +terminfo -balloon_eval +fork() +netbeans_intg +termresponse +balloon_eval_term +gettext +num64 +textobjects -browse -hangul_input +packages +textprop ++builtin_terms +iconv +path_extra +timers +byte_offset +insert_expand +perl/dyn +title +channel +ipv6 +persistent_undo -toolbar +cindent +job +popupwin +user_commands -clientserver +jumplist +postscript +vartabs -clipboard +keymap +printer +vertsplit +cmdline_compl +lambda +profile +vim9script +cmdline_hist +langmap -python +viminfo +cmdline_info +libcall +python3/dyn +virtualedit +comments +linebreak +quickfix +visual +conceal +lispindent +reltime +visualextra +cryptv +listcmds +rightleft +vreplace +cscope +localmap +ruby/dyn +wildignore +cursorbind +lua/dyn +scrollbind +wildmenu +cursorshape +menu +signs +windows +dialog_con +mksession +smartindent +writebackup +diff +modify_fname +sodium -X11 +digraphs +mouse -sound -xfontset -dnd -mouseshape +spell -xim -ebcdic +mouse_dec +startuptime -xpm +emacs_tags +mouse_gpm +statusline -xsmp +eval -mouse_jsbterm -sun_workshop -xterm_clipboard +ex_extra +mouse_netterm +syntax -xterm_save +extra_search +mouse_sgr +tag_binary -farsi -mouse_sysmouse -tag_old_static
Packages organization
The directory which is used as root for Vim packages on Unix/Linux systems is ~/.vim/pack
. The directory doesn’t exist by default, so it must be created manually:
$ mkdir -p ~/.vim/pack
Plugins must not be directly put inside this root directory: inside each directory found under ~/.vim/pack
, Vim looks for a start
and an opt
subdirectory. Plugins found under the former are loaded automatically; those inside the opt directory, instead, must be loaded manually.
Knowing this, we can organize our plugins in “categories”. I, for example, tend to organize them in three main categories: “colorschemes”, “syntax”, and “others”, so what I do, is to create the corresponding directories (and sub-directories):
$ mkdir -p ~/.vim/pack/{colorschemes,syntax,others}/{start,opt}
The directory structure created by the command above is the following:
/home/egdoc/.vim/pack ├── colorschemes │ ├── opt │ └── start ├── others │ ├── opt │ └── start └── syntax ├── opt └── start
The configuration we used in the example is completely arbitrary. You can organize plugins as you wish, perhaps you can create a single directory under ~/.vim/pack
and put all the plugins under its “start” or “opt” sub-directories.
Loading packages automatically
Let’s see an example: suppose we want to add the nerdree plugin to Vim (this plugins adds a very handy filesystem explorer to the editor). All we have to do is to clone the plugin repository inside the directory we want to use as destination. Using the setup created in the previous example, since we want the plugin to be loaded automatically, we can clone it under the ~/.vim/pack/others/start
directory:
$ git -C ~/.vim/pack/others/start clone https://github.com/preservim/nerdtree
In the example above we ran git with the
-C
option, in order to move into the specified directory before executing the “clone” command. That’s all we have to do! The plugin will be automatically loaded when vim starts, after ~/.vimrc
is parsed. To launch the file explorer, we can enter the editor command mode and run:
:NERDTreeToggle
Load packages on demand
Sometimes we may want to load certain plugins only on specific cases. To accomplish said task, all we have to do is to put the plugin code inside an “opt” sub-directory. Sticking to our previous example, if we wanted the “nerdtree” plugin to be loaded on demand, instead of cloning the repository inside the ~/.vim/pack/others/start
directory, we would have cloned inside ~/.vim/pack/others/opt
:
$ git -C ~/.vim/pack/others/opt clone https://github.com/preservim/nerdtree
With the plugin in place, to load it inside of vim we need to use the packadd
command, and pass the name of the directory containing the plugin we want to load as argument. In our case, in Vim command mode, we would run:
:packadd nerdtree
As an alternative we could “script” the load of the package when a certain condition is met in our Vim configuration file. As a trivial example, imagine we want to load the plugin only when using Vim on Linux:
if has('linux') packadd! nerdree endif
In the above example you can see how, using the Vim scripting language, we used the
has()
built-in function to test if a feature is available. In case the function returns 1, it means the specified feature is available. In this case we tested if running the Linux version of vim: if it is the case, we load the “nerdtree” plugin using the packadd
command. Why we used an !
after the command in the example above? While generally on Vim plugins are loaded after the configuration file is parsed, when we execute the “packadd” command, the specified plugin is loaded immediately. To delay the loading of the plugin, we can use the exclamation mark as we did above, so that the plugin directory is added to the vim runtime path, but the plugin itself is loaded during initialization, like it would normally happen.
Conclusions
Vim can be extended by the use of plugins which, in the majority of cases are hosted on Github. Although several plugin managers are available, since version 8, Vim supports a native way to manage them, which is called “packages”. The editor supports loading plugins automatically or on demand. In this tutorial we saw how to take advantage of this functionality.