Choosing Between Vuepress, Storybook, and Vuestyleguidist

A comparison of the 3 most used, modern UI documentation tools in the Vue ecosystem

Why are we doing this

Internal documentation is often a challenge for engineering teams, we all know that excellent documentation is an investment, but at the same time it is very expensive to write, incredibly hard to maintain and it clashes with the speed of development that is required in a fast-moving, agile company. In this fast-pacing environment, some might even argue that by the time you write and curate the documentation you have to refactor everything, thus voiding the documentation itself.

In the past, we reached a point where documentation in frontend projects was pretty much absent. People come and people go and with time, parts of the codebase became legacy because no one knew how they behave and, worse, how they should behave.

This can lead to frustration, a lot of spent time on some bug fixing that would have been trivial with documentation and also to longer onboarding times for newcomers.

Legacy code: the code that no one wants to maintain

We have reached a point of (more) stability and the needs of easing the onboarding of new developers and to create a solid and comprehensive test suite are pushing us to improve our current documentation for the frontend components (mainly js) development

Our requirements

We need documentation for different libraries, often with different scopes. One library might be responsible for HTTP requests, another one is a js helper, another one is a component library… and so on.

We have no strict requirements, we just want our documentation to be pretty, efficient (the required information must be available easily, thus a search would be great) and not too hard to maintain, automatic tools would be great.

One plus for component library documentation is to have the possibility to create interactive examples (quickly test the result on the doc page) to let the user feel and use the components immediately.

What we’ve done so far

As we said, we have now multiple “common libraries” and especially for these common ones, the need for good docs is huge.

For this objective, we’ve separated the libraries in two groups, one for libraries that have UI and one for the remaining ones: a library doing HTTP requests is in the latter group.

We think having consistency across docs is great, but efficiency and maintainability are better, so we are not forcing ourselves to choose only one tool.

We first explored tools for the non-UI libraries. There are many tools for this kind of purpose, but we immediately choose one because we already had experience with it and it worked like a charm.

Documentation.js

This is a great tool because it automatically parses jsdoc and creates markdown or HTML files from it. The default output is not the best looking one but it gets the job done.

For the libraries that expose UI components, we evaluated some tools based on our tech stack. Since we use Vue, we focused on these three libraries that compete for being the best one: Storybook, Vue Styleguidist, and VuePress.

This is the summary of our decision outcome:

STORYBOOK

As its website states:

Storybook is an open source tool for developing UI components in isolation for React, Vue, and Angular. It makes building stunning UIs organized and efficient.

It’s getting more and more attention from the community and it deserves it. It’s a great tool able to solve (probably) all the use cases.

PROS

interactive : by default, it lets the user “play” with components. This is a huge plus because not only the user/developer can read the component APIs but it lets them also see the component, change the properties and experience the immediate effect.

: by default, it lets the user “play” with components. This is a huge plus because not only the user/developer can read the component APIs but it lets them also see the component, change the properties and experience the immediate effect. super extensive: it offers a huge amount of plugins and some of them are amazing, like storyshot to run test suites for the components inside the documentation itself.

CONS:

not the prettiest by default : there is some work needed to make it “pretty looking” (there are themes but still, work to do).

: there is some work needed to make it “pretty looking” (there are themes but still, work to do). time-consuming: more time expensive compared to the other two tools to have the first full documentation up and running

VUESTYLEGUIDIST

This is another tool specific to create component documentation. This time for Vue components (it was born as a fork from react styleguidist so if you are a react user you might have that one).

It generates documentation based on the comments (an extension of jsdoc language) in your source code declarations and markdown files.

PROS:

automatic : it generates automatic docs by parsing jsdoc-like comment. Due to this, it’s the tool to pick if you want to get a nice documentation in the minimum amount of time, because you are going to just need a good documentation inside the definitions of the components.

: it generates automatic docs by parsing jsdoc-like comment. Due to this, it’s the tool to pick if you want to get a nice documentation in the minimum amount of time, because you are going to just need a good documentation inside the definitions of the components. Vue ecosystem: not one of the most known Vue official libraries, but it’s one of them, so probably a good support is expected over time.

CONS:

flexibility : it does a lot of things automatically, this is a good thing but also a bad one, it looks very hard to do something custom and we fear that over time this can be an issue for us.

: it does a lot of things automatically, this is a good thing but also a bad one, it looks very hard to do something custom and we fear that over time this can be an issue for us. a bit buggy : using it we found some bugs, the maintainer support was great, but still, not perfect.

: using it we found some bugs, the maintainer support was great, but still, not perfect. limited: we had a hard time documenting directives (there is not an official way to do it) and mixins, so you still end up writing different parts yourself.

VUEPRESS

Vue-powered Static Site Generator

This one is not a documentation tool, it’s just a static site generator.

It’s created by Evan You (Vue.js creator) and its main goal is to be simple and performant, creating a website given markdown and Vue files.

PROS:

official : this is the tool used by the majority of open source libraries to write their documentation. Needless to say, it works well and it offers huge community support.

: this is the tool used by the majority of open source libraries to write their documentation. Needless to say, it works well and it offers huge community support. pretty : by default, it looks pretty. Also, it’s easy to do minor customization.

: by default, it looks pretty. Also, it’s easy to do minor customization. versatile: it parses MD files but inside them, you can also write HTML and Vue, so if you install your library as a plugin in a Vuepress’ Vue instance, you can use your components in the docs (other tools has similar capability too).

CONS:

not automatic : you have to write documentation in MD files, there is no jsdoc parsing or such things. Good thing is that you can use also HTML and Vue inside this markdowns;

: you have to write documentation in MD files, there is no jsdoc parsing or such things. Good thing is that you can use also HTML and Vue inside this markdowns; Server Side Rendered: to install and use your library in the documentation (for example to create interactive examples) it must be SSR friendly because Vuepress compiles everything into a static site, thus in a node.js environment.

Choice

We believe that Storybook is the most complete tool out there, but it is also the one that requires the largest amount of time to make the documentation reach a production-ready state.

VueStyleguidist is a very nice tool, great for most of the use cases but probably for some enterprises, it’s still not perfect yet.

In the end, we decided that Vuepress is the best choice for our needs, it stands as a mid-tier between the other two tools. It is just a static site with no automatic magic behind it, but its simplicity makes it very easy to customize in the future.

Cool parts

Do you remember that we said that we were not limiting us to just one tool because we wanted the best one for the different cases? We also said that it would be cool to have a common look and feel for all the documentation, it would provide a more uniform user experience.

We chose Documentation.js for the non-UI libraries and Vuepress for the UI ones, needless to say, these two tools don’t give similar outputs for the end-users.

Difference between documentation.js (above) and Vuepress (below)

Let’s see if there is something we can do about this.

We can try to style both outputs similarly. Like creating a theme for Vuepress and one for documentation.js or just create a documentation.js theme similar to the default one of Vuepress (because the latter is pretty already).

Documentation.js is not limited to exporting the result in HTML format only, it also gives you the option to get the output in markdown format. Vuepress takes markdown as input to create a static site… Do you see where I’m going?

The two tools match perfectly. We created a node script that launches the documenation.js creating the markdown and then builds the Vuepress static site starting from that source. This way we have a consistent style for libraries regardless of which tools we are using.

Output of a documentation of a non-UI library (above) and a UI one (below)

For the UI libraries, the documentation is still manual, but we also think that that type of documentation is “less boring” to create and the interactive examples are still going to be created on a case-by-case basis, so we think is an acceptable compromise.

Not so cool parts

For the UI component library, we wanted to create interactive examples to improve the user experience. We were not able to just install our library as a Vue plugin in the Vuepress’ Vue instance because our library is not SSR (Server Side Render) ready. This made us lose a bit of time by searching what we could do about it.

The best choice would be to modify the library to be SSR ready but this would be too much effort, we might plan to do it in the future.

Here’s what we did instead:

We create a small HTML page for each example we want to show, we put it in the .vuepress/public folder, so they are served automatically with the documentation. Then in the Vuepress markdown, we create an iframe (you can write HTML there) that points to the right example.

It might be not the most elegant solution but it works well enough and it also separates examples from the docs itself, so you don’t end up with a mix of the two (of course if the library was installed as a plugin you could achieve the same cleanliness by separating examples with ad-hoc components).

To make the dev life easier and to simplify the maintenance of the documentation for new-comers we created an HTML template for these examples that automatically installs everything’s necessary, we just have to fill 3 placeholders, one for style, one for template and one for the script.

The biggest downside of this approach, in my opinion, is that the iframes are slow and when you load the documentation you see the example popping out after all the other content. Probably not the greatest issue but it’s still not a pleasant experience for the end-user.

Example “appearing” at page load due to iframe being loaded after page render

We could not easily change the way the page is loaded and rendered, for this reason, we leveraged the end-user perception: we added a fade-in animation to the examples (the fade logic is built-in in the template just mentioned so there is nothing to do, it is being generated automatically for every example, ensuring future ones will have it too)

Example loading with a fade animation on page load, end-user perception is much better

This whole iframe solution is working well enough.

This is the code for the example template:

HTML template for examples

And this is the script we import, that handles plugin installation and the fade animation:

javascript file imported by example to add fade

OUTCOME

We are very happy with the results, using the same tech for all the libraries gives a consistent style improving the end-user experience.

We are using this solution to manage all our frontend documentation and we are very happy about the efficiency, the automation and the quality of output we have been able to achieve. All our new libraries follow this standard now.

What do you think about this? Would you have taken a different approach? We’re happy to hear your opinion, don’t hesitate to contact us or to write in the comment section below.