Options API vs Composition API: Choosing the Right Approach for Your Team

Rate this content

With the introduction of Composition API into the Vue ecosystem, many are curious as to what they should pick. Options API? Composition API? Which is best? What are the tradeoffs? In this talk, we'll examine the two approaches so that you can make the right decision for your app.

23 min
21 Oct, 2021


Sign in or register to post your comment.

AI Generated Video Summary

Today's Talk discusses the Options API and Composition API in Vue 3, highlighting the differences and considerations when choosing an approach. The Composition API offers more flexibility and integrates well with TypeScript, but may require more familiarity with JavaScript. Combining both APIs allows for structure and flexibility, with the ability to progressively enhance code. Team preferences and the level of TypeScript usage should be considered when choosing the right approach for a project.

1. Introduction to Options API and Composition API

Short description:

Today we're here to talk about both Options API and Composition API and how to choose the right approach for your team. I'm a staff developer experience engineer at Netlify, on the Vue core team, a Nuxt ambassador, Vue mastery instructor, and a Google developer expert. Before Vue 3, things were simpler with the Options API. With Vue 3's Composition API, it got more complicated. The Composition API uses the Setup method and provides a different way to structure data and methods.

What's up Vue London? How's it going? I'm excited today because I'm here to talk about something that, well, has been discussed quite a bit within the Vue community, and that's the whole idea between whether or not to use Options API or Composition API. So today we're here to talk about both and how to choose the right approach for your team.

For those who don't know me, my name is Ben Hong and you can find me under the Internet of Things under the username BenCodeZen. A little bit about me if you haven't encountered my work before. I'm a staff developer experience engineer at Netlify. I'm on the Vue core team spending most of my time primarily on docs as well as community-related activities and then I'm also a Nuxt ambassador which again if you haven't heard, very excited because Nuxt public beta is now out, so be sure to check that out. I'm also a Vue mastery instructor and a Google developer expert in web technologies and matplatform.

All right, so to kick things off let's face it, before vue 3s things were well simpler. Simpler how so? Well because there was only one way to write our components, so in other words this is what we have basically come to know as the options API. And so just to make sure we're all on the same page, here we have a component here that contains your standard Options API things. So what you have here at the very top here is a script block and then inside of here we're exporting a default object and then we have things like your data, your computed properties, as well as the methods that you're calling inside of this template which goes ahead and renders those things out or calls the appropriate methods. And so hence since we have these opinionated places for where you put your code, i.e. data, computed methods, this was the Options API. Well, with Vue 3 introducing the Composition API though, well it got a little bit more complicated because now let's go ahead and just, just in case people don't know what the Composition API is, let's do a quick overview of the difference. So here in our Options API we have very opinionated ways of how we put our data. Well the first thing you can tell when it comes to the Options API, or sorry, the first thing you can tell when it comes to the Composition API is that we're using the Setup method. So we'll shift everything down, you'll see that this setup function inside of our exported object. And inside of here what we're going to do, let's start moving things in to show you what it looks like in Composition API. So the first thing first is we'll take the data, the count property of zero, and we'll move that up and declare that with a const of count zero. And then we'll need to make that reactive for Vue to track that. So we'll go ahead and import the ref which makes it a reactive reference. And we wrap the value zero in it. And so now that count is basically a reactive reference of zero. And then computed becomes something that we can actually use as like a helper method similar to ref. So we'll import it here. And then what it similarly does is we declare a variable of double count, and it returns the count value the reactive reference times two. So it acts exactly the same way. And then finally, our methods here increment count. Again, just like normal JavaScript here, const increment count, it is a function. And what does it do? It increments the value of count plus plus.

2. Introduction to Script Setup and Options API

Short description:

Now we won't get into the details and sort of how ref and all this stuff works. But here you have a kind of high level of sort of a one to one of what happens when these things get moved into composition API. And because we're in the setup method of having everything exported at this point. One more piece that we need to have is we need to actually explicitly tell view, basically what we want to actually expose to the component, because sometimes certain things are more call it like private methods or private variables. And these are things that we want to expose to the template. And so we turn an object very similarly to the data property. For those of you who've been following closely, well, View 3.2 released yet another way to write components, although another should be put in quotes, because really it's a sort of an enhancement on as far as the developer experience on top of the composition API, and that is the new script setup syntax. And so let's talk about the three different approaches that I would say generally people have to choose between when it comes to this. The first of which is just pure options API. It's very easy to learn and provides a sense of consistency amongst the components. However, it is also opinionated.

Now we won't get into the details and sort of how ref and all this stuff works. But here you have a kind of high level of sort of a one to one of what happens when these things get moved into composition API. And because we're in the setup method of having everything exported at this point. One more piece that we need to have is we need to actually explicitly tell view, basically what we want to actually expose to the component, because sometimes certain things are more call it like private methods or private variables. And these are things that we want to expose to the template. And so we turn an object very similarly to the data property.

And so for those of you who've been following closely, well, View 3.2 released yet another way to write components, although another should be put in quotes, because really it's a sort of an enhancement on as far as the developer experience on top of the composition API, and that is the new script setup syntax. So let's do a quick review on that. And so back inside of our basically our counter example, we can see here that we have the composition API method that we had basically shown the transition of earlier that we migrated from options. Let's go ahead and show you what script setup looks like. So the first thing first is that we're gonna get rid of the exporting object, because what script setup does really it says we're going to assume you only want to use composition API, so we're not going to export an object. And more importantly, we know you're going to set up methods. So why make you define that again? So we're going to do is we're going to move that setup method and move it as an attribute as a script setup. Specifically set up is an attributable script, and then as a result, the compiler knows to do special things with the code inside. So now that we have script setup, though, we also know. Well, we can also do some sort of auto detection of what you probably want to expose to the component. So actually what we get to do as well is we get to remove the manual exposing of variables, which is quite nice. And so you get this code that's quite clean, easy to understand. And then here as a result, you have a pure composition API using the script setup. Basically, the developer experience improvement. Of course, some of you then are probably wondering again, because the question that everyone keeps wanting to ask is, well, which one is the right one? And so let's talk about the three different approaches that I would say generally people have to choose between when it comes to this. And the first of which, as you can imagine, is just pure options API. So in other words, just to reiterate, what we have here is our component here with our explicit options, right, with data, computed methods, and we stick with the structure and we don't ever even deal with composition API.

Well, the thing about this is when it comes to the options in API, there are a couple of pros that I want to want to highlight, and the first of which is that it's very easy to learn, right? That's why I think one of the reasons Vue 2's API was so popular with people is because it was actually quite easy to understand as far as where things went, and everyone followed the same structure. And so even from my own personal experience, I taught someone who was basically a designer in tech but hadn't coded for years, but basically within the first hour of taking a Vue 101 workshop where they were concerned that they weren't going to be able to follow because their JavaScript skills really wasn't up to par. They were actually able to catch on really quickly, and before they knew it, they were actually following along and building things, which was really exciting for them, and they felt really empowered by that, and so this is one of the things I always remind people that options API is really great in this regard. And then, as we talked about, because it is extremely structured, you get a sense of consistency amongst the components because everyone knows data goes in data, computed goes in computed, and so forth. And as a result, you get a sense of simplicity, right? Especially when it comes to how the code is written and because you know every time that is predictable. But on the other hand, there are cons, right? Every decision in tech has trade-offs. That's something I always try to remind people when it comes to these sort of things, and so first of all, it is really opinionated.

3. Reasons for Composition API Introduction

Short description:

If you don't want to organize your code using the Options API, it becomes difficult to do different patterns. Composition API was introduced to provide more flexibility. However, with Vue 3, the Options API might feel awkward for TypeScript support.

So, in other words, if you don't want to organize your code this way, it becomes rather difficult to basically get around or do different patterns, and this is one of the reasons Composition API was introduced. As a result, you're going to get less flexibility, right?

In addition to that opinionated structure, because now you have to deal with the fact that you have to split things apart that you might not want to. Maybe you want to keep your methods or data together in a way that's more modularized, and so that flexibility became a little bit difficult to do in the Options API.

And the thing is that with Vue 3, while a lot of things now are much more TypeScript friendly, between those who are learning TypeScript and really into it, the Options API might feel a little bit awkward when it comes to TypeScript support because you're doing things that are a little bit different than what you might do when you're normally writing a module when you're exporting for JavaScript and that kind of thing.

4. Pure Composition API Approach

Short description:

The second approach is a pure composition API approach, where everything is basically vanilla JavaScript. You have the freedom to organize your code however you want and architect it according to your preferences. This approach offers a lot of flexibility, allowing your data and computations to be organized in any way you like. It provides a feeling of working with just JavaScript, although there may be some confusion due to the abstraction and automatic hooking up of things in the background.

Now, the second approach, as you might expect, is a pure composition API approach. So in this regard, let's go ahead, and as a reminder, let me show the script setup code example that we can see here, and this is where no more options. Everything is basically vanilla JavaScript. You can organize your code however you want, and you have the freedom to do and architect whatever you like. Now, this is good, right? There are a lot of pros to this. As you can imagine, the fact that it's basically plain JavaScript with some helper methods, you get a lot of flexibility because now your data can go wherever it wants, your computer can go wherever it wants, however you want to organize it, and as a result, you get this feeling of just JavaScript because while, again, the reason I put this in quotes is because a lot of times when it comes to the code, Objects API is also just JavaScript, but because it uses things like this and there's sort of a little bit more abstraction going on in the background as far as hooking things up automatically for you, this is where people, I think, get a little bit more nervous because of this context that can, well, it's just traditionally very confusing when it comes to JavaScript.

5. Combining Options API and Composition API

Short description:

The Composition API feels more like JavaScript, integrates well with TypeScript, but also requires more familiarity with JavaScript and can lead to anti-patterns. Taking both Options API and Composition API together allows for structure and flexibility.

So as a result, you get more of this feeling of, like, I declare a constant, I do a ref, I organize it how I want, and so in this regard, I think it feels to people a little bit more like just JavaScript. And because of this sort of syntax of keeping it just like the normal JavaScript you write in modules, one of the benefits, the result is that the TypeScript syntax and everything just integrates much cleaner because now you don't have that abstraction in the background happening with this context and this sort of thing.

So as a result, very, very TypeScript friendly. On the other hand, once again, no technology is without its trade-offs. Interestingly enough, because we have flexibility, the flexibility itself, I would argue, is also a con in and of itself. In other words, it is a bit of a double-edged sword. After all of you think about it, because you now no longer have this structure that people consistently follow, there is more of an opportunity for you to create anti-patterns and a lot of the responsibility now is on you. And this means that if you make mistakes as far as architecture, that's for you to figure out later. Or, for example, if someone does something wrong with the architecture and then it gets passed to someone else, it's a lot more navigation that needs to happen. Whereas, for example, with the Options API, everyone knew where the code was at all times.

Also, this is a little bit of a mixed bag, but I would say, compared to Options would say it has a higher barrier of entry because Composition API does come with some of the prerequisites of having more familiarity with JavaScript than the Options API. And while that might sound a little bit weird at first, we have to understand that when it comes to the Options API, there is a lot that people can kind of assume with the patterns, right? This abstraction and the fact that you always write things in a certain way let people who might not totally understand how JavaScript works still do a lot of powerful things or even tinker or basically do minor edits and changes without actually basically knowing a ton of JavaScript. But on the other hand though, if you have a strong JavaScript background, again this is why the other flip side of the coin, some people might find the Composition API easier because again they come with that prerequisite of JavaScript. So they're like, oh I understand how to import helper methods, I know how to export modules, all this stuff makes sense. Whereas with Options API it's built in. There's two sides of the coin, but as a result there is that bit of a higher barrier of entry for those who aren't as familiar with JavaScript. And again, similar to the first point on more flexibility, the lack of structure can be a problem if developers are not basically using best practices when it comes to architecture of their apps and so just know that that can make it a little bit tricky sometimes when it comes to scaling projects because now it's really relying on your ability to enforce that consistency over a large code base, compared to once again, Options API, where every single component always looked the same basically.

Now, approach number three here is the one that I think is worth mentioning, which is that you can take both Options API and Composition API together. And so here we have in this codebase, we have the component for Options and Composition API. And what we see here is the standard export default. And this time, all of our Composition API stuff is defined and set up. And so what's great about this is basically all this stuff is now exposed for the Composition API to then, oh sorry, the Options API, to go ahead and then ingest it. So what you see here now is we can actually build on it. So let's say we wanted a property like triple count, similar to the double count, but we're just returning this.count times three. Well, because everything has been set up in the setup method, see, see how that naming works? Then it basically allows it to be exposed to the Options API for it to use and then like basically build on top of it. And so this to me is probably where we're going to see a lot of the, how do I say this? Okay. And what's really nice about this is that you kind of get basically a little bit of both worlds, the best of having some sort of structure and consistency while still leveraging what makes Composition API really powerful. So let's go over just like before the pros and cons of this. Well, the first of which is you get structure with some flexibility. So in other words, we have that consistent options, but then at the same time, we get to inject the flexibility when we need it.

6. Choosing the Right Approach

Short description:

Another advantage of using a hybrid approach is the ability to progressively enhance code and add Composition API features without refactoring everything. However, using two approaches requires a better understanding of both methodologies and may have a learning curve. The hybrid approach provides TypeScript friendliness and similarities between Composition and Options API. It can be a little verbose and not as TypeScript friendly as the pure Composition API. Choosing the right approach depends on the code base, team makeup, and the level of TypeScript usage.

And then otherwise, the structure is still there for us. Another nice thing about this approach as well as you can progressively enhance code. So in other words, especially if you're coming from a code base that has been around for a while, already using options, for example, there is a way for you to progressively enhance your code there is a way for you to progressively add composition API features without having to refactor everything and rewrite all of your code, which again, to me, is one of views biggest selling points as far as it's flexibility to allow to accommodate different situations.

In addition, because now you have the ability to basically fuse the composition API stuff with the options API, you have more typescript friendliness than you would if you had done pure options API. So just something to consider. When it comes to cons, though, as you might expect, because you're using two approaches, this does mean that you kind of have to have a better understanding of basically both methodologies. And this is just a con from a sense of there's a little bit more of a learning curve, because that means that people who were very comfortable with options API now also have to know composition API, and then vice versa, those who knew composition API will also then want need to know options API. But again, one of the interesting things that I would say when it comes to that is a lot of people when using Vue are already familiar with options usually right out of the gate. And more importantly, the principles that I think drive the API behind both composition and options as far as like lifecycle hooks, computer properties, reactive data, they're for the most part very, very similar. So you know, hopefully the while there are two different approaches, there are similarities and hopefully the learning curve is not too bad.

That said, though, right, as we saw earlier with the script setup, it can be quite concise. But now that you have both, it can be a little bit verbose, sometimes because you're having to manually define your returns. And while there might be a pink, like basically tooling to help with that in the future, like, this is technically a con when it comes to sort of comparing like the ability to go pure composition API versus options. And so, you know how I said it was more TS friendly, well, then, again, similarly, compared to the composition API is not as TypeScript friendly in the sense that you can use some really clean syntax with the pure composition API but with object or options API, on the other hand, then you have to do a little bit more of that finessing of making sure that you type things correctly according to the context. And so this is one of those things where it's just, it's, well, this is not a perfect solution when it comes to that. And so again, it's a hybrid approach. This is to be expected. So which approach is the right approach? Well, I think one of the challenging things when it comes to engineering is a lot of time as developers were kind of obsessed with like being like the most correct or finding ways to prove that this will always be right. But rather than think of right in terms of correctness or some sort of objective superiority, I think it's more important to flip the context of right instead as to focus on the fact that what really matters is choosing the right approach for your team. In other words, more about fit and rather than some sort of objective grading skill that we're talking about. And so here are some aspects to consider when making the choice between the various approaches. The first of which is the code base that you're working from, right? Because if you're migrating from an existing one that has view two and you already are using options API and you're migrating it into view three, for example. Again, we know that migrations can be expensive and they want to still turn out new features. So I would say in that case, because the team's already familiar with options API, in my personal opinion, it makes the most sense to progressively enhance your components with composition API. And then even if your team is thinking about doing more composition API, this does prevent the need to like make your entire code base pure composition API from the get-go, which can definitely slow down development, especially when it comes to releasing new features and such.

On the other hand, though, if we're talking about new project, this is where I think the nuances come in a little bit more differently. I think this is something I think is often overlooked, but really important to consider is who is really contributing to the code base, right? What is the makeup of the team? If you have a lot of people who aren't as familiar with JavaScript and you have maybe one or two people that are writing the code base primarily, with them coming in to help with little bits and pieces, options API serving as the primary methodology might actually be a really good use case for this for a majority of components, because believe it or not, when we think about a lot of components, it's easy to always want to think they'll scale infinitely, but because Vue gives you the flexibility to choose between various methodologies, depending on which, there's no reason to say that you can't start with options and then, as it basically grows in complexity, you can enhance it with composition API or eventually switch it as it sees fit. And so as a result, when you're considering your team, this can be really, really important, because, for example, if you have a team that's really, really familiar with JavaScript, and they want the flexibility of making their own architectural decision, then yeah, composition API all the way could make a lot of sense. But again, this is why it's really matters about your team makeup and how basically that contributes to the maintenance and iteration of your code base.

And a third one, which is actually pretty a big factor, is are you planning are you or does the team plan on using TypeScript very, very heavily, right? And I think there's a difference between using TypeScript lightly to annotate some types occasionally to like some heavier TypeScript users who want to do a lot more complex things with TypeScript.

7. Considering Team Preferences and Shipping Products

Short description:

When your team heavily prefers TypeScript, the Composition API fits naturally in terms of syntax and tooling. However, it's important to consider your team's preference. When shipping products, people care about functionality and performance, not the specific approach used. Vue allows you to choose what works best for your team. If your team doesn't enjoy working with a certain codebase, it's worth considering alternative approaches.

And so when you know your team really wants to go heavy on the TypeScript, this is where I would say you're probably going to be leaning heavier on the composition API because it'll just fit more naturally as far as syntax, tooling, and that kind of thing. That said, though, the final aspect I want you to consider, which is actually really important, is what does your team prefer? And this, I think, is counterintuitive to engineers a lot of time because, again, we're so caught up in trying to find the right answer, and we're afraid of call it people judging us for our decision or thinking our codebase is somehow inferior. But the reality is that when you're shipping products and people are downloading apps, no one's thinking like, oh, I wonder what approach they use. They just want to know does it work? Is it performant? And so Vue, one of the things I've always loved about Vue is that it lets you choose what's best for your team. Just like TypeScript, if you don't want to use TypeScript, not a big deal. You can still use Pure Composition API. You can use Options API, right? But at the end of the day, if your team doesn't enjoy working with that codebase or they dread getting in there to do something, that's the time to really think about whether or not even if it's not objectively, even if the rest of the community is saying otherwise, I would argue it doesn't matter what they think.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Vue 3 may still sound new to many users, but it's actually been released for over a year already. How did Vue 3 evolve during this period? Why did it take so long for the ecosystem to catch up? What did we learn from this process? What's coming next? We will discuss these questions in this talk!

Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Rust is a new language for writing high-performance code, that can be compiled to WebAssembly, and run within the browser. In this talk you will be taken through how you can integrate Rust, within a Vue application, in a way that's painless and easy. With examples on how to interact with Rust from JavaScript, and some of the gotchas to be aware of.
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.
For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.

Workshops on related topic

Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.
Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.
Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem
IDE of choice (Inellij or VSC) installed
Nodejs + NPM

Vue.js London Live 2021Vue.js London Live 2021
117 min
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
We'll build a Nuxt project together from scratch using Nitro, the new Nuxt rendering engine, and Nuxt Bridge. We'll explore some of the ways that you can use and deploy Nitro, whilst building a application together with some of the real-world constraints you'd face when deploying an app for your enterprise. Along the way, fire your questions at me and I'll do my best to answer them.

Vue.js London Live 2021Vue.js London Live 2021
176 min
Building Vue forms with VeeValidate
In this workshop, you will learn how to use vee-validate to handle form validation, manage form values and handle submissions effectively. We will start from the basics with a simple login form all the way to using the composition API and building repeatable and multistep forms.
Table of contents:
- Introduction to vee-validate
- Building a basic form with vee-validate components
- Handling validation and form submissions
- Building validatable input components with the composition API
- Field Arrays and repeatable inputs
- Building a multistep form
VSCode setup and an empty Vite + Vue project.

Vue.js London 2023Vue.js London 2023
137 min
TresJS create 3D experiences declaratively with Vue Components
- Intro 3D 
- Intro WebGL
- ThreeJS
- Why TresJS
- Installation or Stackblitz setup 
- Core Basics
- Setting up the Canvas
- Scene
- Camera
- Adding an object
- Geometries
- Arguments
- Props
- Slots
- The Loop
- UseRenderLoop composable
- Before and After rendering callbacks
- Basic Animations
- Materials
- Basic Material
- Normal Material
- Toon Material
- Lambert Material
- Standard and Physical Material
- Metalness, roughness 
- Lights
- AmbientLight
- DirectionalLight
- PointLights
- Shadows
- Textures
- Loading textures with useTextures
- Tips and tricks
- Misc
- Orbit Controls
- Loading models with Cientos
- Debugging your scene
- Performance
Vue.js London Live 2021Vue.js London Live 2021
116 min
Building full-stack GraphQL applications with Hasura and Vue 3
The frontend ecosystem moves at a breakneck pace. This workshop is intended to equip participants with an understanding of the state of the Vue 3 + GraphQL ecosystem, exploring that ecosystem – hands on, and through the lens of full-stack application development.
Table of contents
- Participants will use Hasura to build out a realtime GraphQL API backed Postgres. Together we'll walk through consuming it from a frontend and making the front-end reactive, subscribed to data changes.
- Additionally, we will look at commonly-used tools in the Vue GraphQL stack (such as Apollo Client and Urql), discuss some lesser-known alternatives, and touch on problems frequently encountered when starting out.
- Multiple patterns for managing stateful data and their tradeoffs will be outlined during the workshop, and a basic implementation for each pattern discussed will be shown.
Workshop level
NOTE: No prior experience with GraphQL is necessary, but may be helpful to aid understanding. The fundamentals will be covered.

Vue.js London Live 2021Vue.js London Live 2021
72 min
A Different Vue into Web Performance
Solving your front-end performance problems can be hard, but identifying where you have performance problems in the first place can be even harder. In this workshop, Abhijeet Prasad, software engineer at Sentry.io, dives deep into UX research, browser performance APIs, and developer tools to help show you the reasons why your Vue applications may be slow. He'll help answer questions like, "What does it mean to have a fast website?" and "How do I know if my performance problem is really a problem?". By walking through different example apps, you'll be able to learn how to use and leverage core web vitals, navigation-timing APIs, and distributed tracing to better understand your performance problems.