Open-source project
dart-lang/dart-vim-plugin avatar
dart-lang/dart-vim-plugin

dart-vim-plugin and the line between syntax highlighting and an actual Dart IDE

Syntax highlighting for Dart in Vim

653 stars52 forksVim ScriptBSD-3-Clause

At a glance

What is it?
The Dart plugin for Vim provides filetype detection, syntax highlighting and indentation for Dart files, and the README is careful to point you elsewhere for completion, diagnostics and jump to definition, which are delegated to a Language Server Protocol plugin running the Dart analysis server.
Who is it for?
dart-vim-plugin fits a Vim user who wants Dart files to look and indent correctly, especially in a Flutter codebase, and who is content to add a separate LSP plugin for anything beyond that. It is the wrong choice if you want completion, diagnostics and jump to definition from one plugin, because the README sends you to vim-lsc and vim-lsc-dart for that, and it is the wrong choice if your formatting must match dart format exactly.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 139 days ago.
What is it written in?
Mainly Vim Script, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Three jobs, and an explicit boundary around them

The plugin provides filetype detection, syntax highlighting and indentation for Dart code in Vim. That is the whole scope, and the README is unusually clear about where it stops.

If you are looking for auto-complete, diagnostics as you type, jump to definition and other intellisense features, the README tells you to try a Vim plugin for the Language Server Protocol such as vim-lsc, configured to start the Dart analysis server with the --lsp flag. If you want an IDE experience, it points at the Dart Tools page.

So this is a syntax layer, and the analysis layer is a separate installation. The reason is structural rather than an omission. The Dart SDK ships an analysis server that can be run in LSP mode, and the plugin's own job is the part that a language server does not cover, which is highlighting and indentation of text as you type it. The analysis server knows what a class means; it does not decide what colour an identifier should be.

The repository layout reflects that division. There is a syntax directory for the highlighting definitions, an indent directory for the indentation rules, an ftdetect directory for filetype detection, an ftplugin directory for the per-filetype plugin, an autoload directory, a plugin directory, a doc directory for the Vim help files, and an AUTHORS file and a CHANGELOG.md. The primary language is Vim script, and the licence is BSD-3-Clause with the LICENSE file at the repository root.

The default branch is master, the repository is not archived, and the last push was on 2026-06-05. There are no GitHub releases, so there is no version number to pin, and the CHANGELOG.md is where the history lives.

Installing it with Vim's own package system

The installation section says to install it as a typical vim plugin using your favourite approach, and if you have no preference it offers Vim's built-in package support, which takes two commands:

sh
mkdir -p ~/.vim/pack/dart-lang/start
git clone https://github.com/dart-lang/dart-vim-plugin ~/.vim/pack/dart-lang/start/dart-vim-plugin

The directory layout matters here. The pack/dart-lang/start convention is how Vim's own package mechanism discovers plugins, and the start subdirectory is the one that loads automatically. This is a git clone into a conventional path, with no plugin manager involved, and it is the shortest route for someone who does not already have a manager.

If you do have one, the README points at examples for vim-plug, pathogen and vundle on the installation wiki. Those are the three older managers that are named specifically, and the wiki is where the concrete configuration lives rather than the README, which keeps the main file short.

The one thing the README does not spell out is what the plugin does on load, because that is what filetype detection is for. Dropping the plugin in place and opening a .dart file is the entire first use. There is no command to run and no server to start, which is precisely the point of a syntax plugin and the reason it is worth having alongside an LSP plugin rather than instead of one.

The configuration options are all global variables

Everything the plugin exposes is a global variable, and the set is small enough to read in one sitting.

To enable HTML syntax highlighting inside Dart strings there is g:dart_html_in_string, set to v:true, with the default being false. Highlighting for specific syntax groups can be disabled by defining custom highlight group links, and the help tag :help dart-syntax covers the syntax definitions in the doc directory.

For indentation, g:dart_style_guide is set to a number, with the example being 2, which enables Dart style guide syntax such as two space indentation. Formatting on save is g:dart_format_on_save, set to v:true, and the options passed to the formatter are g:dartfmt_options, which you can discover with dart format -h. The formatting command itself can be replaced with g:dartfmt_command.

The formatter is the reason the plugin has a command at all. The README documents a single command, :DartFmt, with a linked animated capture of it running. The model is that the plugin is the Vim-side integration and the Dart SDK's own dart format binary does the work, which is why g:dartfmt_options and g:dartfmt_command exist as configuration points.

So the plugin is a thin, well-scoped layer: detection, colouring, indentation rules, and a command that shells out to the official formatter with options you control.

The trailing comma is where the plugin and dart format disagree

The FAQ answers the question every Dart user eventually asks, and the answer is honest about a limitation rather than papering over it.

The question is why the plugin does not indent identically to dart format. The answer is that the indentation capabilities within Vim are limited, and it is not easy to fully express the indentation behaviour of dart format.

The specific difference is function arguments when using a trailing comma in the argument list. When using a trailing comma, as is common in Flutter widget code, dart format uses 2 space indent for argument parameters. In all other indentation following an open parenthesis, such as argument lists without a trailing comma and multi-line assert statements, dart format uses 4 space indent. The plugin uses 4 space indent by default.

So the fix for a Flutter codebase is one line, g:dart_trailing_comma_indent set to v:true, which switches the default to 2 space indent.

This is worth understanding because it is a real, recurring source of diff noise. A repository formatted by dart format, where every widget call ends with a trailing comma, will be indented two spaces, and the plugin will indent it four. Every file you touch in Vim and every file you do not touch will disagree, and the commit diff will show whitespace changes on lines that had nothing to do with your edit.

The design decision here is to default to the general case and let the Flutter user opt in. That is a defensible choice, but it is worth knowing about before the first commit rather than after.

Running the Dart analysis server over LSP

The second FAQ entry is the practical recipe for getting the analysis features, and the README gives the exact command.

The Dart SDK comes with an analysis server that can be run in LSP mode, and the server ships with the SDK. Assuming the bin directory of the SDK is at $DART_SDK, the full command to run the analysis server in LSP mode is:

The command is `$DART_SDK/dart $DART_SDK/snapshots/analysis_server.dart.snapshot --lsp`.

There is a detail about scope in the next sentence that affects behaviour. If you will be opening files outside of the rootUri sent by your LSP client, which is usually cwd, you may want to pass onlyAnalyzeProjectsWithOpenFiles: true in the initializationOptions. Whether you want that depends on how the client is configured, and the README says to see your LSP client's documentation for how to configure initialization options.

The command names the snapshot file directly, which is what makes it fast to start. The analysis server snapshot is the compiled form shipped in the SDK, so you are not paying for a Dart VM startup and a source compile on every editor launch.

For the vim-lsc route there is an additional plugin, vim-lsc-dart, which can configure everything for you. The minimal configuration the README gives for a good default experience with vim-plug is short:

vimscript
call plug#begin()
Plug 'dart-lang/dart-vim-plugin'
Plug 'natebosch/vim-lsc'
Plug 'natebosch/vim-lsc-dart'
call plug#end()

let g:lsc_auto_map = v:true

Note that the syntax plugin is one of the three entries, not a replacement for the other two. The whole arrangement is a two plugin setup for editing Dart in Vim, and this one is the highlighting half.

Where the dart-vim-plugin is the wrong tool

The first wrong case is a developer who wants one plugin to do everything. The README sends you to a Language Server Protocol plugin for completion, diagnostics and jump to definition, and to the Dart Tools page for a full IDE. If your requirement is a single install that gives you an IDE experience in Vim, this is the wrong repository, and the LSP route is a different dependency graph with its own configuration surface.

The second wrong case is a codebase where formatting must be identical to dart format in every case. The plugin admits it is not, and the trailing comma case is not an edge case, it is the default in Flutter code. The opt-in variable fixes the common case, but the general statement that Vim's indentation cannot fully express the formatter's behaviour still holds, and a team that runs dart format in CI will hit disagreements that the variable does not cover.

The third wrong case is a team that has standardised on a different editor tooling model, where LSP is provided by a single client that already handles the language server, and the highlighting comes from the server's semantic tokens. In that arrangement, this plugin duplicates work rather than adding it.

The alternative worth naming is the dedicated IDE tooling the README links on its Dart Tools page, and the difference in approach is exactly the split the plugin itself describes. An IDE ships the analysis server, the formatter, the debugger and the refactoring tools integrated, with a consistent keymap and a consistent view of the project, and it costs you an editor you did not choose. Vim plus this plugin plus vim-lsc gives you a terminal-native workflow with the analysis features layered on, and it costs you the integration work and the fact that the highlighting and the analysis can disagree about what the code means. If the team is happy in a terminal and wants Vim's editing model, that is the trade the plugin exists to enable, and for anyone who wants the analysis features to be the source of truth, the IDE is the answer.

Maintenance, licensing and what a language-specific plugin inherits

The repository is not archived, and the last push was on 2026-06-05, with no GitHub releases and the CHANGELOG.md as the only version history. The CHANGELOG is the file to watch for a plugin like this, because breaking changes in a filetype plugin show up as indentation or highlighting changes rather than as an error.

The licence is BSD-3-Clause, with the LICENSE file in the repository root..

What a language-specific Vim plugin inherits is the language's own churn. A syntax file encodes the grammar of a language at a point in time, and when the language adds a keyword or a new syntax form, the highlighting is stale until someone updates it. The escape hatch the README documents is the highlight group link mechanism, so a user can adjust a specific group's highlighting without waiting for an upstream change, and the syntax file can be pointed at a local copy.

There is a pleasant detail in the structure. The plugin lives under the dart-lang organisation rather than a personal one, so it is maintained with the language rather than by a single individual, and the repository has a CONTRIBUTING.md and an AUTHORS file, which is the norm for a project that is part of a language's official tooling. That does not guarantee that every Dart release is supported the day it lands, but it does mean there is somewhere to send a patch, and the project is set up to receive one.

Editorial conclusion

dart-vim-plugin fits a Vim user who wants Dart files to look and indent correctly, especially in a Flutter codebase, and who is content to add a separate LSP plugin for anything beyond that. It is the wrong choice if you want completion, diagnostics and jump to definition from one plugin, because the README sends you to vim-lsc and vim-lsc-dart for that, and it is the wrong choice if your formatting must match dart format exactly. Before you adopt it, read the trailing comma indentation note, because the plugin defaults to four space indent where dart format uses two after a trailing comma, and set g:dart_trailing_comma_indent if that matters to you.

Frequently asked questions

How do I install the Dart plugin for Vim?

Clone it into Vim's own package directory with mkdir -p ~/.vim/pack/dart-lang/start followed by a git clone of the repository into that path. The README also points at examples for vim-plug, pathogen and vundle on the installation wiki.

Does dart-vim-plugin provide autocompletion and diagnostics?

No. The plugin covers filetype detection, syntax highlighting and indentation. The README directs you to a Language Server Protocol plugin such as vim-lsc, configured to start the Dart analysis server with the --lsp flag, for completion, diagnostics as you type and jump to definition.

How do I make the plugin indent the same way as dart format?

It does not by default. dart format uses two space indent for arguments after a trailing comma, while the plugin uses four, so set g:dart_trailing_comma_indent to v:true to switch the default to two space indent.

What options does the Dart Vim plugin expose?

g:dart_html_in_string to highlight HTML inside Dart strings, g:dart_style_guide to enable style guide syntax such as two space indentation, g:dart_format_on_save to run DartFmt on save, g:dartfmt_options for the formatter options and g:dartfmt_command to override the formatting command.

How do I run the Dart analysis server in LSP mode?

The Dart SDK ships the analysis server, and with the SDK bin directory at $DART_SDK the command is $DART_SDK/dart $DART_SDK/snapshots/analysis_server.dart.snapshot --lsp. The vim-lsc-dart plugin can configure this for you.

Official sources

  1. dart-lang/dart-vim-plugin on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dart-lang-dart-vim-plugin.svg)](https://hysenlabs.com/projects/dart-lang-dart-vim-plugin)

Was this useful?