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.
What's up, Vue London? How's it going? I'm excited today because I'm here to talk about something that, well, is being 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 Map Platforms.
Options API vs Composition API
[01:21] All right. So to kick things off, let's face it, before Vue 3, 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. 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 had these opinionated places for where you put your code, IE data computed methods, this was the Options API.
[02:12] 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 to assume, no one, 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 and 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.
[02:57] 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 go ahead and import the ref, which makes it a reactive reference. And we wrap the value zero in it, 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 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 Vue basically what we want to actually expose to the component. Because sometimes certain things are more called 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.
Vue 3.2 and the new script setup syntax
[04:14] And so for those of you've been falling closely, well Vue 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. And let's go ahead and show you what script setup looks like.
So the first thing first is that we're going to 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 use a set method. So why make you define that again? So what 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 setup is an attribute of script. And then as a result, the compiler knows to do special things with the code inside.
[05:14] 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 developer experience improvement.
[05:38] 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. With data computed methods and we stick with the structure and we don't ever even deal with Composition API.
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.
[07:14] And as a result, you get a sense of simplicity, 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. 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. 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 in addition to that opinionated like 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 keep your methods or data together in a way that's more like modularized. And so that flexibility became a little bit difficult to do in the Options API.
And because of this sort of syntax of keeping it just like the normal jobs that you write in modules, one of the benefit that results is that the Typescript syntax and everything just integrates much cleaner. Because now you don't have that abstraction in the background happening with the, this context and this sort of thing. So as a result, very, very TypeScript friendly.
[10:13] 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, if 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 someone else, it gets passed to someone else, it's a lot more sort of navigation that needs to happen. Whereas for example, with the Options API, everyone knew where the code was at all times.
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 reliant 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.
[12:38] 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 code base, 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, or sorry, the Options API to go ahead and then ingest it.
[13:15] 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 dot count times three. Well, because everything has been set up in the setup method, see, see how that, 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? 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.
[14:08] 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. And then otherwise the structure is still there for us.
Another nice thing about this approach as well is you can progressively enhance codes. 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 add Composition API features without having to refactor everything and rewrite all of your code, which again, to me is one of Vue's biggest selling points as far as its flexibility, to allow to accommodate different situations.
[14:48] 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 just 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 need to know Options API.
[15:30] But again, and 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 are for the most part, very, very similar. So you know, hopefully while they're two different approaches, there are similarities and hopefully the learning curve is not too bad.
That said, though, 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 pin, like basically tooling help with that in the future, this is technically a con when it comes to sort of comparing like the ability to go pure Composition API versus Options.
[16:20] 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 like 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 is just, it's... well, it's just not a perfect solution when it comes to that. And so again, it's a hybrid approach, this is to be expected.
So which one is the "right" one?
[16:54] 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 we're kind of obsessed with being 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 scale that we're talking about.
And so here are some aspects to consider when making the choice between the various approaches.
[17:35] The first of which is the code base that you're working from. Because if you're migrating from an existing one that has Vue 2 and you already are using Options API, and you're migrating it into Vue 3, for example, again, we know that migrations can be expensive and they want to still churn 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.
And a third one, which is actually pretty a big factor. Is, are you planning, or does the team plan on using TypeScript very, very heavily? 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. 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.
[20:09] 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 code base is somehow inferior. But the reality is, is that when you're shipping products and people are downloading apps, no one's thinking, 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.
But at the end of the day, if your team doesn't enjoy working with that code base or they dread getting in there to do something, that's the time to really think about whether or not like, 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.
[21:05] And so the final verdict. What exactly is going on? Well, it's probably not a surprise to you, but in my opinion, every approach is a valid one. We've seen with Vue 2 people creating really, really large code bases like GitLab and their apps are great. They work. And so, the key thing here is to remember that, regardless of what everyone says, if you're building it and it works and you're having fun, that's really what matters. Because that's how you'll be shipping new features. That's how you'll be iterating.
And then don't get me wrong when you run into problems and you're like, oh, now I need to do something different, that option doesn't really provide, and I need composition. Like Composition API will be there waiting for you regardless. You don't have to start going all in on it in order to start basically feel like you're getting the most use out of it.
[21:55] With that, thanks everyone for listening to my talk today. If you want to get in touch or you have any other questions, please feel free to reach out. There's my website, bencodezen.io. You can find me under the basically I'm at Twitter, YouTube, Twitch under the moniker, BenCodeZen so come hang out on livestream or check out the videos. Either way, it's been a lot of fun. So thanks to you London.