A guide to setting up Vim for JavaScript development
Tags: vim, javascript
Published: 2019-05-10 08:57:27

---
title: A guide to setting up Vim for JavaScript development
published: false
tags: vim,javascript
canonical_url: https://freshman.tech/vim-javascript/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/nuhxdketafrt3ie0qqws.jpg
published: true
---

I’ve been using Vim for close to two years now, and do all my JavaScript development work in it. In the process, I’ve tweaked my configuration several times until I finally achieved a setup that I can say I’m really happy with. So, in this article, I want to talk about some of the plugins and tools that I’ve taken advantage of to make writing JavaScript a more pleasurable experience in Vim.

All the plugins and settings were tested, and confirmed to work on Vim 8.1 and Neovim 0.4.0, the latest versions at the time of writing. As this post mainly deals with installing and configuring plugins for Vim, I recommend that you adopt [vim-plug](https://github.com/junegunn/vim-plug) as your plugin manager if you don’t use one already.

## Syntax highlighting

Vim supports basic syntax highlighting for JavaScript but I found it suboptimal especially when it comes to modern ES2015+ syntax, and it doesn’t support JSX when working with React. I found that [vim-javascript](https://github.com/pangloss/vim-javascript) and [vim-jsx](https://github.com/mxw/vim-jsx) solved my problems in both instances.

![React code in Neovim](https://thepracticaldev.s3.amazonaws.com/i/1qdnhekd2t4tej2r9vup.png)

However, I later replaced those two with [vim-polyglot](https://github.com/sheerun/vim-polyglot) which is a plugin that bundles several other syntax plugins for over 100 languages, and loads them on demand so that performance is not affected.

So, instead of having to add another plugin to provide syntax highlighting for `.vue` files for example, `vim-polyglot` takes care of that without much fuss. This means I’m covered when switching between different JavaScript frameworks as well as other programming languages.

## Linting your code with ESLint

Code linting helps you identify potential errors in your code without having to run the code. It also helps you avoid problematic patterns or code that doesn’t adhere to certain style guidelines. [ESLint](https://eslint.org/) has become the dominant linting tool for JavaScript developers due to it’s comprehensive support for all the modern features of the language, and also its easy extensibility.

If you’re not using ESLint already, follow [this guide](https://eslint.org/docs/user-guide/getting-started) to set it up in your JavaScript project. In order for ESLint to work, you need to configure it with specific [rules](https://eslint.org/docs/rules/). You can use the recommended configuration which only addresses common problems, or check out [Airbnb’s style guide](https://www.npmjs.com/package/eslint-config-airbnb-base) if you want a more comprehensive [set of rules](https://github.com/airbnb/javascript).

While ESLint was built to be used via the command line, many people (myself included) prefer to integrate it into their code editor to get live feedback on code as it is being written. Bringing ESLint integration into Vim is pretty easy with [ALE](https://github.com/w0rp/ale).

Once you [install ALE](https://github.com/w0rp/ale#installation), open up Vim in a JavaScript project that has been configured to use ESLint, and try to create an error on purpose. It should work straightaway without further configuration.

![Linting JavaScript with ALE in Neovim](https://thepracticaldev.s3.amazonaws.com/i/65ywuc2mlm5jqongkorn.png)

As you can see, indicators for errors and warnings appear next to the problematic lines as the code is written, and the reason for the error is printed at the bottom of the screen when the cursor is on the line where is error is found. In this case, ESLint is warning me that about unused variables and also about the `console` statement.

Additionally, you can open the location list to view all the errors in a file and jump to each error using `:lnext` (or `:lne`) to navigate to the next item and `:lprevious` (or `:lpr`) to navigate to the previous item.

![Jump between ESLint errors via the location list](https://thepracticaldev.s3.amazonaws.com/i/z9q203kdt5v5crufop54.png)

An easier way to [jump between linting errors quickly](https://github.com/w0rp/ale#5ix-how-can-i-navigate-between-errors-quickly) is to use the `<Plug>` keybindings shown below. You can change `[c` and `]c` to your preferred key combination.

```
nmap <silent> [c <Plug>(ale_previous_wrap)
nmap <silent> ]c <Plug>(ale_next_wrap)
```

By the way, I’m not a fan of the default indicators used by ALE for errors and warnings, so I changed them to something that’s aesthetically more pleasing using the following configuration:

```
let g:ale_sign_error = '❌'
let g:ale_sign_warning = '⚠️'
```

![New indicators in ALE](https://thepracticaldev.s3.amazonaws.com/i/rmtl5jd0ga149snbvwzg.png)

## Code formatting with Prettier

[Prettier](https://prettier.io/) is a code formatting tool that has gained huge momentum in the JavaScript ecosystem since coming on the scene around early 2017. It basically ensures that a codebase complies to a set code style guide regardless of the number of developers working on the project.

It works by formatting a file (or many files) according to the [options](https://prettier.io/docs/en/options.html) specified in its configuration file. As such, all files formatted by Prettier adhere to the same guidelines for indendation, quote style, spacing, line width, and several other stylistic concerns.

To use Prettier, you need to [add it to your project](https://prettier.io/docs/en/install.html). You can use Prettier’s [CLI](https://prettier.io/docs/en/cli.html), or configure it as a [pre-commit hook](https://prettier.io/docs/en/precommit.html), but I prefer the instant feedback of having it format my code immediately I save a file.

ESLint also has some code fixing capabilities, but some of these conflict with Prettier’s methods. It is better to have ESLint take care of code quality concerns, while leaving Prettier to focus on code formatting concerns.

To achieve this, you need to disable the ESLint rules that conflict with Prettier with [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) while adding Prettier’s code fixing capabilities to ESLint using [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier). To do so, run the following command in your project directory:

```
$ yarn add eslint-config-prettier eslint-plugin-prettier -D
```

Then add the following to your ESLint configuration file. This configures both `eslint-plugin-prettier` and `eslint-config-prettier` in a single step.

```
{
  "extends": ["plugin:prettier/recommended"]
}
```

That’s all you need to do to integrate Prettier with ESLint. The next step is to configure Vim so that all JavaScript code is formatted nicely as soon as a file is saved. ALE solves this nicely for us!

In addition to supporting linters that report errors, ALE can also run fixers to format the code in a Vim buffer. All you need to do is specify `eslint` as a fixer for JavaScript in your `.vimrc` as shown below:

```
let g:ale_fixers['javascript'] = ['eslint']

" Fix files automatically on save
let g:ale_fix_on_save = 1
```

At this point, linting and formatting errors will be annotated by ESLint, while Prettier formats the code on save.

![Prettier in action](https://thepracticaldev.s3.amazonaws.com/i/xb6zzcbdnuieq2f7000l.gif)

You can also format the code on demand using the `:ALEFix` command. The easiest way to use it is to create a key mapping in your Vim configuration file.

```
nmap <F6> <Plug>(ale_fix)
```

## Super fast fuzzy file search

File searching is important in any editor, and while Vim supports this via the `:find` command, it’s very basic and doesn’t support fuzzy finding as far as I can tell. There are a couple of tools out there that bring fuzzy file search to vim. After using [CtrlP](https://github.com/ctrlpvim/ctrlp.vim) for a while, I switched to [Fzf.vim](https://github.com/junegunn/fzf.vim#installation) which is a wrapper for the command line fuzzy finder with the same name, [Fzf](https://github.com/junegunn/fzf).

Fzf looks like a simple tool on the surface, but it’s actually very powerful. Here’s a few ways I take advantage of it on a daily basis:

### Fuzzy file finder

My primary use of Fzf is to search files in a project. This is achieved using the `:Files` command which I heartily bound to <kbd>Ctrl-P</kbd> in my Vim config. I also modified the `$FZF_DEFAULT_COMMAND` variable to use [Ripgrep](https://github.com/BurntSushi/ripgrep) for listing the files. After installing Ripgrep, put this in your `.bashrc` or `.zshrc` to search for all files except those in hidden directorys (like `.git`) or those that have been ignored in your `.gitignore` file:

```
export FZF_DEFAULT_COMMAND='rg --files --follow --hidden'

# Fish syntax
# set -gx FZF_DEFAULT_COMMAND 'rg --files --follow --hidden'
```

Additonally, Fzf provides the `:Buffers` amd `:History` commands for searching open buffers and your buffer history. I have mapped these to `<Leader>b` and `<Leader>h` respectively.

```
nnoremap <C-p> :Files<CR>
nnoremap <Leader>b :Buffers<CR>
nnoremap <Leader>h :History<CR>
```

Similarly to CtrlP, once Fzf is open, you can hit the <kbd>Enter</kbd> key to open the selected file in the current window, or use <kbd>Ctrl-T</kbd>, <kbd>Ctrl-X</kbd> or <kbd>Ctrl-V</kbd> to open selected files in a in new tab, horizontal split, or vertical split respectively.

![FZF in Vim](https://thepracticaldev.s3.amazonaws.com/i/qvoor4km791wme0hrx8x.png)

### Searching for tags

Fzf provides two main commands for searching tags in a project. The first one`:BTags` allows you to search for tags in the current buffer. It doesn’t require a tags file, and is great for jumping between methods quickly.

![Btags demo](https://thepracticaldev.s3.amazonaws.com/i/s496elc84sz9sd5h9sek.png)

The second one, `:Tags`, allows you to perform project wide search for tags, but it does require a tags file. You can use [Universal Ctags](https://github.com/universal-ctags/ctags) to generate a tags file for your project and combine it with [Gutentags](https://github.com/ludovicchabant/vim-gutentags) to automate the creation and updating of tags in the background.

![Using the Fzf :Tags command](https://thepracticaldev.s3.amazonaws.com/i/nsqdrzpu9wxxtqftxjn1.png)

I have mapped both commands mapped to `<Leader>t` and `<Leader>T` respectively.

```
nnoremap <Leader>t :BTags<CR>
nnoremap <Leader>T :Tags<CR>
```

## Project-wide search

The `:Rg` command provided by Fzf uses Ripgrep to find all occurrences of a pattern across an entire project, so you can search for a specific string, select the matches and navigate the results using the quickfix list. I often use it to check for where a method is used in my codebase, and I found it incredibly helpful in a recent project I was refactoring.

When using `:Rg`, you can narrow down the results and hit <kbd>Enter</kbd> on the selected result to open the file in the current window. This will skip the quickfix list altogether. To select multiple results, just use the<kbd>Tab</kbd> key on each file you want to select or <kbd>Alt-A</kbd> to select all results and then <kbd>Enter</kbd> to populate the quickfix list which you can navigate with `:cnext` and `:cprev`.

![Project-wide search with :Rg](https://thepracticaldev.s3.amazonaws.com/i/g4fjaqclnlgzp6xmywgf.png)

There is so much more that can be done with Fzf. For example you can navigate Vim’s `:help` documentation with `:Helptags`, search for Snippets (`:Snippets`), Git Commits (`:Commits`), Command history (`:History:`), and more. Use `:h fzf-vim-commands` to find out all the options available to you.

## Intelligent code completion

For most people, having a good code completion experience is pivotal to having a modern development setup. Vim supports some basic functionality out of the box through `omnicomplete`, but we’re going to replace that with something much more powerful.

Since I started using Vim, I’ve tried an few plugins for auto-completion, including [Deoplete](https://github.com/Shougo/deoplete.nvim) and [YouCompleteMe](https://github.com/Valloric/YouCompleteMe) but neither provided the experience I desired.

I discovered [Coc.nvim](https://dev.to/scottw/coc-nvim-1a7f) recently and it’s been great! It brings several IDE-like features to Vim and is easy to set up. It’s built upon the concept of [language servers](https://langserver.org/), which power features like auto-completion, go-to-definition, hover tooltips, and more in modern editors.

Follow the [installation guide](https://github.com/neoclide/coc.nvim/wiki/Install-coc.nvim) to get Coc.nvim up and running. Once Coc.nvim has been installed, you need to install some language server extensions to provide intellisense support for JavaScript and Typescript projects. You can so so with `:CocInstall`.

```
:CocInstall coc-tsserver coc-json
```

With [coc-tsserver](https://github.com/neoclide/coc-tsserver), you get so many [features](https://github.com/neoclide/coc-tsserver#features) that make writing, debugging and refactoring JavaScript or Typescript a breeze. Without configuring anything, auto-completion should just work and you can see function signatures and relevant suggestions as you type.

![Code completion with Coc.nvim](https://thepracticaldev.s3.amazonaws.com/i/9b3m84q8efvkz8036txn.png)

You can even replace ALE’s linting and code formatting capabilities with the help of [coc-eslint](https://github.com/neoclide/coc-eslint) and [coc-prettier](https://github.com/neoclide/coc-prettier), but as I’m already happy with my setup, I have opted not to do so at this time.

## Wrap up

This post has covered several plugins that can help you get more utility from Vim when it comes to JavaScript development. While you don’t have to use any of this stuff to be productive with Vim, it can certainly help you avoid bugs, and speed up the development process.

I hope you’ve found this article useful. If you have any questions, or experience any troubles while configuring a plugin, do leave a comment below and I’ll get back to you. If you’re curious about my personal configuration, you can check out [my dotfiles](https://github.com/ayoisaiah/dotfiles/tree/master/vim) or [send me a message on Twitter](https://twitter.com/@ayisaiah).

Thanks for reading!