⭐ Unlock your productivity with my Vim For Developers book (15% off in Jan'24)

Vim for JavaScript and React in 2019

October 28, 2018

Last Updated: 27 September 2019.

In this article, I’d like to share my setup and some of the Vim plugins that will transform your Vim into a perfect IDE for JavaScript and React (step back, VS Code!).

Obviously, you don't have to use everything. Feel free to copy things that work for your setup and your style of work.

Here's How My Vim Looks Like
Here's How My Vim Looks Like

Essentials

Here some important ones (they are all of a general-purpose).

  • Plug plugin manager used in this article
  • NERDTree to navigate the file tree
  • FZF let's you fuzzy search through the files in project (and much more, really)
  • jiangmiao/auto-pairs inserts quotes and parenthesis in pairs as you type
  • tpope/vim-commentary press gcc to comment out a line or gc to comment a selection in visual mode

You can read more about the essential plugins here.

Syntax highlighting

Vim is doing pretty well with syntax JavaScript highlighting out of the box. But it's not ideal.

Many of the old syntax plugins for JavaScript have troubles with some modern features like arrow functions or async/await.

Here are some plugins that will help to fix it.

Also, this color scheme called OceanicNext is real nice. It is a little bit like Sublime. You can see it on the first screenshot for this article.

Formatting

In Vim, there is a special gq (:help format) command that formats the code. By default, it's not very useful, but we can set up it to use an external program to format the code.

I use prettier for almost everything.

Don't forget to install it first (or make sure you have the latest version),

npm install -g prettier

Then put this into Vim's settings:

" FORMATTERS
au FileType javascript setlocal formatprg=prettier
au FileType javascript.jsx setlocal formatprg=prettier
au FileType typescript setlocal formatprg=prettier\ --parser\ typescript
au FileType html setlocal formatprg=js-beautify\ --type\ html
au FileType scss setlocal formatprg=prettier\ --parser\ css
au FileType css setlocal formatprg=prettier\ --parser\ css

gq is quite handy as it can be combined with the text objects:

  • gqgq format current line
  • gqip format paragraph
  • gggqG format the whole file

The last one is something I use quite often, so I have a mapping for it:

nnoremap <F5> mzgggqG`z

Linting

A linter is a binary that can analyze your code and tell you something about possible errors or formatting issues. Vim can use the linters and show the warnings with help of a plugin (there are multiple variants really).

Since the release of Vim 8 many people swapped the old Syntastic plugin with the new ALE plugin which is fast, easily customizable and asynchronous. The last thing means that your editor won’t freeze anymore as the linting happening. It also supports so many different languages, linters, and fixers that you won’t need to think about it anymore.

By default, it will just try to use as many linters as it is able to find in the system. I'd like to be a bit stricter about that. Here’s how I have it customized to associate specific linters with the file types:

let g:ale_linters = {
\   'python': ['flake8', 'pylint'],
\   'javascript': ['eslint'],
\   'vue': ['eslint']
\}

Many of the linters (like eslint) can also fix your code, which is very handy.

let g:ale_fixers = {
  \    'javascript': ['eslint'],
  \    'typescript': ['prettier', 'tslint'],
  \    'vue': ['eslint'],
  \    'scss': ['prettier'],
  \    'html': ['prettier'],
  \    'reason': ['refmt']
\}
let g:ale_fix_on_save = 1

The last option will make ALE auto-fix your file every time you save it. And this is really neat.

Another useful feature is navigating to the next / previous error with ]r / [r.

nnoremap ]r :ALENextWrap<CR>     " move to the next ALE warning / error
nnoremap [r :ALEPreviousWrap<CR> " move to the previous ALE warning / error

Autocompletion

For the autocomplete in Vim there are multiple options. I use Deoplete, mostly because it just works with my current setup (I usually use Neovim).

Deoplete is an engine, so it doesn't provide any autocomplete itself, it merely aggregates all possible autocompletion-s into a friendly interface.

Language Server

I'm a big fan of Language Server Protocol which is a relatively new thing that got popularized by Microsoft with TypeScript. Basically, it's a separate server process that runs in the background and analyzes your codebase. Then any editor (including Vim) can act as a client to get some important information and even send commands.

By integrating with a Language Server, your editor can support features like autocompletion, going to the definition, and so on. There are multiple language servers for different languages, and of cause there's a good one for JavaScript.

You can install it with npm:

npm install -g javascript-typescript-langserver

ALE described in the previous section has some capabilities to work as a Language Client but I was unable to set up it properly for pure JavaScript. So instead I use a separate plugin.

Plug 'autozimu/LanguageClient-neovim', {
    \ 'branch': 'next',
    \ 'do': 'bash install.sh',
    \ }

The Language Client can start the server in background for you, but we need to specify which server (binary) we want to use for a specific file type.

let g:LanguageClient_serverCommands = {
    \ 'javascript': ['javascript-typescript-stdio']
    \ 'ruby': ['~/.rbenv/shims/solargraph', 'stdio'],
    \ }

Alright, now that we all set up you can restart Vim and you should be able to run all those nice commands. I'd suggest the following mappings:

nnoremap <leader>l :call LanguageClient_contextMenu()<CR>
nnoremap K :call LanguageClient#textDocument_hover()<CR>
nnoremap gd :call LanguageClient#textDocument_definition()<CR>
nnoremap <leader>r :call LanguageClient#textDocument_rename()<CR>

Now, <leader>l opens a menu showing all possible things you can do with language server.

The other ones are my mostly used commands:

  • K shows the available documentation when possible
  • gd jumps to where the symbol under the cursor has been first defined
  • <leader>r rename the symbol under cursor

Laguage servers are really neat and they can do more interesting things. For references and for a table of supported languages refer to the official website.

What's next?

  • I try to keep this article up-to-date with the latest trends and the sharpest plugins, so feel free to get back here from time to time.
  • For TypeScript support, there a separate article
  • If you know any other useful plugins I need to include in this article, please let me know!
Vim For Developers

Vim For Developers

Learn Vim and upgrade your productivity to the next level by building the IDE of your dreams.

LEARN MORE