Writing Vue.js Components with Flow

Published on March 12, 2017
Default avatar

By Joshua Bemenderfer

Writing Vue.js Components with Flow

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Type checking is a tricky concept in Vue. While it’s easy to do in plain script files, Vue single-file components are a much trickier beast to get working. While some choose TypeScript, perhaps for class-based components, others find TypeScript’s heavyweight nature and difficulty to integrate with common tools to not be worth the effort. Facebook’s Flow is a typechecker that fits much better into a standard webpack + babel + eslint toolchain, and is commonly used in React projects. Once you get it set up, it just works!

Getting Flow to work with Vue is a bit tricky as it involves several dependencies and minor configuration tweaks to make them all work properly together, so let’s start out by installing those first.


Starting from vue-cli’s webpack-simple template, there are nine extra dependencies to install. Here’s what each of them does:


  • babel-plugin-syntax-flow - Adds support for flow syntax in Babel.
  • babel-plugin-transform-class-properties - Adds support for class properties and static methods
  • babel-plugin-transform-flow-strip-types - Removes type annotations from source files before transpiling with Babel.

Eslint: (optional)

  • eslint - Eslint. It’s pretty much the de-facto linter for JS, with integrations for a variety of editors and IDEs as well. If you’re not using this now, you’ll want to start using it.
  • babel-eslint - Patches Eslint to use Babel’s parser for parsing source files.
  • eslint-plugin-html - Allows Eslint to handle HTML files. (ie. Only lints stuff inside script tags.)
  • eslint-plugin-flowtype-errors - Passes flow errors through Eslint, and to your editor’s eslint plugin if you have one.
  • eslint-plugin-vue - Opinionated utilities for Eslint with Vue.
  • eslint-config-vue - Opinionated config for Eslint with Vue.


  • flow-bin - The Flow typechecker.

Install via Yarn or NPM:

# Yarn
$ yarn add \
  babel-plugin-syntax-flow \
  babel-plugin-transform-class-properties \
  babel-plugin-transform-flow-strip-types \
  eslint \
  babel-eslint \
  eslint-plugin-html \
  eslint-plugin-flowtype-errors \
  eslint-plugin-vue \
  eslint-config-vue \
  flow-bin \

$ npm install \
  babel-plugin-syntax-flow \
  babel-plugin-transform-class-properties \
  babel-plugin-transform-flow-strip-types \
  eslint \
  babel-eslint \
  eslint-plugin-html \
  eslint-plugin-flowtype-errors \
  eslint-plugin-vue \
  eslint-config-vue \
  flow-bin \



Add the babel plugins to the end of your .babelrc file.

  "plugins": [


Set up your .eslintrc file like so:

  "parser": "babel-eslint",

  "plugins": [

  "extends": [

  "rules": {
    "flowtype-errors/show-errors": 2


And finally, create a .flowconfig file in your project root directory. It can be empty, just make sure it’s present.


You can now use Flow in your .js files or .vue single-file components just by adding the /* @flow */ annotation to the top of each file or script section.

Assuming your editor or IDE has the proper eslint packages installed, you should now have real-time error checking and positional annotations whenever there is an error or warning.

/* @flow */

const doSomethingStupid(stringArg) {
  // Flow should show an error here, "The operand of an arithmetic operation must be a number."
  return stringArg * 3109;

console.log(doSomethingStupid(`I'm stringy`))
  <p>I'm made with Flow!</p>

/* @flow */

const randomThing: string = 'Boop!'

export default {
  created() {

And there you have it! Nothing else in your toolchain has to change.

There’s plenty more to learn about Flow. If you’re not familiar with it already, a great next step would be the Flow Docs. Enjoy!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us

About the authors
Default avatar
Joshua Bemenderfer


Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel