I’ve created a few posts on here about writing JavaScript with Vim, this is because it’s what I do all day (and night) long, I’ve refined my editor to make writing this slightly questionable language as easy as possible. I’ve now hit a point, once again, where I feel like I should share my tooling for everyone else to take advantage of. You can find everything I’m going to talk about in my dotfiles under the Vim directory if you’re curious.

Plugin management

I’ve gone through a few different systems since starting to use Vim, I’ve finally settled on one that’ll be tough to beat: vim-plug. A good plugin manager is essential to any good Vim configuration, in my opinion. It allows me to easily add, remove and update plugins as well as keep them in sync across machines. The parallel processing and optional deferred loading are excellent features.

My configuration is modularised by having bootstrap.vim load all files in my modules directory, one of these is plugins.vim which configures vim-plug and then loads the individual configuration files for each plugin from modules/plugins. This allows my actual plugin list to remain clean and concise. I recommend following a similar pattern to keep your configuration clean.

The point of this section being: Make sure you have a good plugin manager and a nice place to list your plugins as well as their configuration. It’ll help keep things clean. Feel free to copy my system exactly, in fact, I encourage it. Fork my dotfiles if you so wish.

Essential plugins

I’m going to list a fairly exhaustive list of every plugin I use that can help with JavaScript development. There’s going to be a lot here, but I’ll try to justify each one as best as I can. Adding all of them will have no impact on the performance of your editor (unless you’re on a Raspberry Pi for example) and vim-plug will fetch / update them incredibly quickly. I actually use a lot more than this, but these are some of the most relevant.

  • [.pl-s]#https://github.com/Lokaltog/vim-easymotion[Lokaltog/vim-easymotion] – The way to navigate a file quickly, regardless of language.

  • PeterRincker/vim-argumentative – Allows you to change the order of arguments with ease.

  • Raimondi/delimitMate – Automatically match pairs intelligently.

  • [.pl-s]#http://github.com/Valloric/YouCompleteMe[Valloric/YouCompleteMe] – The best completion engine I’ve found.

  • Olical/vim-enmasse – My own, allows you to edit your quickfix list and write the changes to their files. Like find and replace, but better.

  • ctrlpvim/ctrlp.vimThe way to jump around your code base by rough file names.

  • helino/vim-json – We work with a lot of it, show it some love.

  • junegunn/vim-easy-align – Makes those funny alignment issues trivial.

  • marijnh/tern_for_vim – Provides pretty good completion in JavaScript, works great with YouCompleteMe. Checkout the tern website for more information.

  • mhinz/vim-signify – Git info in the gutter.

  • pangloss/vim-javascript – My favourite JavaScript syntax plugin of them all so far. (has great conceal features which I’ll talk about below)

  • rking/ag.vim – We have to search for a lot of stuff across a lot of files, Ag does it best.

  • scrooloose/syntastic – Provides automatic JSHint linting. (among many other JavaScript linters, check the docs)

  • Too many to list from tpope, but honestly, I use almost all of these on a daily basis. Feel free to pick and choose any that sound cool, vim-sensible is a start and vim-surround is essential.

Project specific configuration

I use embear/vim-localvimrc to provide project specific functionality such as executing tests or running the build. Because this is something that isn’t universal, having a .lvimrc to hand is extremely useful. I have the following binding defined at the moment so I can just hit “<localleader>tt” (which is “|tt” right now for me) to test this file, it doesn’t matter if I’m in the source or test file, it just works.

command! Test Dispatch grunt test-dev --filter %:t:r
nnoremap <localleader>tt :Test<CR>

This is relying on vim-dispatch to make the whole thing asynchronous. It actually executes in a tmux split and pulls the results into my Vim quickfix list when done.

I also have my path set to some greedy globs and suffixesadd set to contain .js. This allows me to press gf (open file under cursor) on the following require statement, and it will actually take me to the source (if it exists)!

// Where httpService.js exists somewhere in this project.
// I press gf within the quotes and it will take me there.

var httpService = require('httpService');

And here’s the configuration I’m currently using for that particular bit of magic.

set path+=**/src/main/**,**
set suffixesadd+=.js


I use UltiSnips to manage my snippets, which is a fantastic tool. The key to snippets, however, is to not have too many. That is why I only have three at the time of writing. It’s pretty obvious what they’re for, the most used being fn. Having a few for your most common patterns is a good idea, but delete them if you find you’re not using them, keep your snippets clean.


Concealing is a neat (and relatively new) feature in Vim that allows you to mask a set of characters as a single character. It just so happens that vim-javascript has some excellent conceal configuration that’s easy to use and very effective. Here’s what I currently use, it’s pretty self explanatory.

" General conceal settings. Will keep things concealed
" even when your cursor is on top of them.
set conceallevel=1
set concealcursor=nvic

" vim-javascript conceal settings.
let g:javascript_conceal_function = "λ"
let g:javascript_conceal_this = "@"
let g:javascript_conceal_return = "<"
let g:javascript_conceal_prototype = "#"

This is all well and good, but it got me thinking, what if I could just press the @ key and have it expand to “this” but still show an @ through conceal? Essentially creating a cute little language on top of JavaScript within Vim that’s arguably easier to write and read.

Expanding and concealing

This is where my vim-syntax-expand plugin comes in. Here’s a quick demo to give you an idea of what I mean if my previous paragraph was not clear.


I can write concealed characters and see concealed characters, but it actually writes the real JavaScript to the file. It’s caused some people to be slightly confused when looking at my screen, but normal JavaScript is only a set conceallevel=0 away. And yes, it’s intelligent enough to not expand in comments or strings, so you can still type @ or # when required.

The < to “return” mapping uses a special rule that will only work if you’re at the beginning of a line, so you can still type “⇐”. Here’s my full configuration, which is also featured in the repository README.md.

" Map the conceal characters to their expanded forms.
inoremap <silent> @ <C-r>=syntax_expand#expand("@", "this")<CR>
inoremap <silent> # <C-r>=syntax_expand#expand("#", "prototype")<CR>
inoremap <silent> < <C-r>=syntax_expand#expand_head("<", "return")<CR>

" Keeps everything concealed at all times. Even when my cursor is on the word.
set conceallevel=1
set concealcursor=nvic

" JavaScript thanks to pangloss/vim-javascript
let g:javascript_conceal_function = "λ"
let g:javascript_conceal_this = "@"
let g:javascript_conceal_return = "<"
let g:javascript_conceal_prototype = "#"

I’ve been using it for around and week so far and it feels great. I guess I’m just yearning for a more concise functional language. I type fn, hit “<C-j>” and I get a lambda symbol and a block to write in. Then I can return true by typing “< true”.

This is the sort of thing Vim is amazing at, removing the cruft between you and your text, so you can edit without thinking and concentrate on the problem at hand. Yes it takes practice to use efficiently, but so does every good tool.

[#eow-title .watch-title]#This is Shia LaBeouf responding to your “should I give Vim a go?” thoughts.