Home / Blog / Vue Options API vs Composition API
Vue Options API vs Composition API

Vue Options API vs Composition API

Vue 3 gives you two ways to write a component, the Options API and the Composition API. The Options API is the original style, the one you already know if you came from Vue 2. The Composition API arrived in Vue 3 and is now the recommended default for new apps. Which one you reach for changes how your logic is organized, how easily you reuse it, and how well TypeScript can help. Here is how the two compare, and which one to pick for your next Vue project.

Options API vs Composition API, the short answer

In Vue 3, the Composition API is the recommended default for new applications, while the Options API remains fully supported and is often simpler for small components and beginners. The Options API organizes a component into fixed options like data, methods, computed, and lifecycle hooks. The Composition API lets you group related logic together using functions such as ref, computed, and watch, usually inside <script setup>. Both APIs compile to the same result, both are first-class in Vue 3, and you can even mix them across components in the same project. The right choice comes down to component complexity, how much logic you want to reuse, your TypeScript needs, and team preference.

What the Options API and Composition API are

The Options API is the original way to write Vue components, and it has been part of Vue since the very beginning. You describe a component as an object of options, where data holds reactive state, computed holds derived values, methods holds functions, and lifecycle hooks like mounted run code at set points. If you learned Vue 2, this is the syntax you learned. Vue School's Options API master class covers it in depth.

<script>
export default {
    data() {
        return {
            name: '',
            age: 0,
            aboveAge:false
        }
    },
    computed: {
        displayProfile() {
         return `My name is ${this.name} and i am ${this.age}`;
        }
    },
    methods: {
         verifyUser() {
         if(this.age < 18){
         this.aboveAge = false
        } else {
        this.aboveAge = true    
           }
        },   
    },
    mounted() {
        console.log('Application mounted');
    },
}
</script>

The Composition API arrived in Vue 3 to fix the parts of the Options API that get awkward as a component grows. Instead of splitting logic across fixed options, you write it as plain functions and reactive values, usually inside <script setup>. State is created with ref and reactive, derived values with computed, and side effects with watch and the lifecycle functions. Vue School's Vue.js 3 master class teaches it end to end.

<script setup>
import { ref, computed } from 'vue'

const name = ref('')
const age = ref(0)
const aboveAge = ref(false)

const displayProfile = computed(() => `My name is ${name.value} and I am ${age.value}`)

const verifyUser = () => {
  aboveAge.value = age.value >= 18
}
</script>

Options API vs Composition API at a glance

Here is a side-by-side comparison of the two APIs across the dimensions that usually decide the choice.

Dimension Options API Composition API
Syntax Logic split across fixed options (data, methods, computed, lifecycle hooks) Related logic grouped together with ref, computed, watch, and lifecycle functions in <script setup>
Logic reusability Mixins, which are prone to naming collisions and unclear sources Composables, which are explicit, collision-free, and easy to test
TypeScript support Workable, but relies on this and often needs defineComponent First-class inference that works naturally with typed refs, props, and emits
Learning curve Gentle and structured, friendly for beginners Steeper, assumes comfort with reactivity and functions
Best for Small components, no-build setups, and teams new to Vue Large or complex components, shared logic, and TypeScript codebases
Vue 3 status Fully supported and not deprecated Recommended default for new apps

Structure

The Options API reads like a form you fill in. Reactive state goes in data, derived values in computed, behavior in methods, and setup or teardown in the lifecycle hooks. That layout is easy to learn and easy to scan, which is exactly why it has been a comfortable starting point for years and why the Vue documentation still teaches it first to many people.

The friction shows up as a component grows. A single feature ends up scattered across four or five options, so one piece of logic lives partly in data, partly in computed, and partly in methods, and you jump around the file to follow it. On a large component this is what people mean by option explosion, where the options get long and the related bits drift far apart.

Side by side codeblock comparing Options API vs Composition API

Reusability

Sharing logic between components is where the Options API starts to strain. If two components need the same behavior, your choices are to copy the code or pull it into a mixin, and mixins carry a well-known problem, which is that they merge their properties into the component silently. When two mixins define the same data key or method, or a mixin collides with the component itself, nothing tells you where a given property actually came from. That is the pain of sharing logic between Vue components once a project grows past a handful of components.

var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}

// define a component that uses this mixin
var Component = Vue.extend({
  mixins: [myMixin]
})

var component = new Component() // => "hello from mixin!"

Composables fix this by being plain functions. A composable owns its own state and returns exactly what it wants to expose, so when you read const { x, y } = useMouse() you can see precisely what you are getting and where it came from. There is no hidden merge and no guessing which mixin set a property. This is also where the reactive programming style in Vue pays off, because the state stays reactive while living inside a normal function.

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  // state encapsulated and managed by the composable
  const x = ref(0)
  const y = ref(0)

  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // expose managed state as return value
  return { x, y }
}

//usage in component
<script setup>
import { useMouse } from './mouse.js'

const { x, y } = useMouse()
</script>

Because the state is isolated inside the function, composables are also straightforward to test on their own, and you can compose several of them in one component without them stepping on each other. If you want the deeper version of this comparison, read mixins vs composables with the Composition API, and when you are ready to write your own, here is how to write a Vue composable step by step.

Full access to JavaScript

Because a Composition API component is really a setup function running plain JavaScript, the whole language is available to you without fighting the this context. Async/await, closures, and plain JS libraries slot in the way they would in any other module. <script setup> even supports top-level await, so you can resolve data before the component renders when you pair it with Suspense.

You can call async code from Options API methods too, so this is not one API doing something the other cannot. It is about how much sits between you and the language. With the Composition API there is almost nothing, which is why wiring up a library like RxJS or a custom reactive integration feels like normal code instead of a workaround.

Learning curve

The Composition API asks more of you up front. You have to understand refs and .value, when to reach for reactive versus ref, and how reactivity behaves when you pass values around. None of that is hard once it clicks, but it is more than the Options API asks of a beginner, who can get a working component knowing only data, methods, and computed. If you are teaching someone their very first Vue component, the Options API still has the gentler on-ramp, and that is a fair reason to start there.

TypeScript support

If your project uses TypeScript, the Composition API is the clear winner. Because state is declared as plain variables with ref and reactive, TypeScript can infer types directly without extra ceremony. Props, emits, and reactive state are all strongly typed with almost no boilerplate when you use <script setup> together with defineProps and defineEmits.

The Options API can be typed too, but it leans on the this context, which forces you to wrap components in defineComponent and often add explicit type annotations to get the same level of safety. For a TypeScript-first codebase, the Composition API keeps your types cleaner and your editor autocompletion more reliable.

Compatibility

The Composition API is native to Vue 3. In older Vue 2 projects it was available through the @vue/composition-api plugin, but Vue 2 itself reached end of life on December 31, 2023, and that plugin is no longer maintained. Any new work should be on Vue 3, where the Composition API is built in and no plugin is needed. If you are still maintaining a Vue 2 codebase, migrating to Vue 3 is the path forward.

As of Vue 3.5, the framework keeps adding ergonomic improvements aimed at the Composition API and <script setup>, like reactive props destructure and helpers such as useTemplateRef and useId. New framework features increasingly assume you are writing Composition API code, which is another reason to reach for it in fresh projects.

Performance and bundle size

At runtime, the two APIs perform about the same, because both compile to the same kind of component instance. Anyone telling you one is meaningfully faster than the other is overselling it. The one real difference is bundle size, and it is small.

Code written with <script setup> can minify a little better. The compiled template runs in the same scope as your setup code, so it references your variables directly instead of going through a this proxy, and a minifier is free to shorten those local variable names. With the Options API, properties hang off this and keep their names. The result is usually a slightly smaller bundle for <script setup>, which is not something you will feel on a page, but it is real.

Can you mix the Options API and Composition API?

Yes. Vue 3 lets you use both APIs in the same project, and you can even combine them in a single component by adding a setup() function alongside your options. In practice it is cleaner to pick one style per component so the logic stays easy to follow. A common and perfectly valid pattern is to keep existing components on the Options API while writing new ones with the Composition API. That way you adopt the Composition API gradually, without rewriting a whole codebase at once.

Converting from the Options API to the Composition API

Moving a component from the Options API to the Composition API is mostly a mechanical translation.

  • data() properties become ref() or reactive() declarations.
  • computed options become computed() functions.
  • methods become plain functions.
  • watch options become watch() or watchEffect() calls.
  • Lifecycle hooks map to their function equivalents, so mounted becomes onMounted(), and created logic moves to the top level of <script setup>.

You do not have to convert everything at once. Migrate component by component, starting with the ones that would benefit most from shared logic or better TypeScript support. For a longer walkthrough with the trade-offs, read our guide on From Vue.js Options API to Composition API: Is it Worth It?.

Which should you use in your next project?

  • Choose the Composition API for new Vue 3 projects, large or complex components, logic you want to reuse across components, and any TypeScript-heavy codebase.
  • Choose the Options API for small, simple components, quick prototypes, no-build pages that pull Vue in from a CDN, or teams that are brand new to Vue and want the gentlest starting point.
  • Either works for medium-sized apps, so consistency across your team usually matters more than the specific choice.

Because both APIs are first-class citizens in Vue 3, you are never locked in. Many teams standardize on the Composition API for new work while leaving stable Options API components untouched.

Bottom line, start with the Composition API

If you are building a real application, start with the Composition API and <script setup>. It is how Vue 3 is written today, what current courses teach, and what most job postings now expect. The Options API is not deprecated, though. It stays a perfectly good choice for simpler components or a no-build setup, and it reads easily once you know the Composition API, so you lose nothing by starting modern. If you are brand new to Vue, our free, interactive Learn Vue tutorial teaches the Composition API from the ground up with runnable examples you can edit in the browser.

Want to go deeper on the move between the two? Read From Vue.js Options API to Composition API: Is it Worth It?. And if you would rather learn each API properly, Vue School has full courses on both the Options API and the Composition API.

Frequently asked questions

What is the Options API in Vue?

The Options API is Vue's original component syntax. You build a component from a set of options, where data holds reactive state, computed holds derived values, methods holds functions, and lifecycle hooks like mounted run code at set points. It has been in Vue since Vue 2, and it is still fully supported in Vue 3.

What is the Composition API in Vue?

The Composition API is the newer way to write Vue 3 components. Instead of fixed options, you declare reactive state with ref and reactive, derive values with computed, and group related logic together as plain functions, usually inside <script setup>. It is the recommended default for new Vue 3 apps.

Is the Composition API better than the Options API?

Neither is strictly better. The Composition API scales better for complex components, logic reuse, and TypeScript, which is why it is the recommended default for new Vue 3 apps. The Options API is simpler and more structured, which makes it a great fit for smaller components and developers who are new to Vue.

Is the Options API deprecated?

No. The Options API is not deprecated and remains fully supported in Vue 3, with no plans for removal. Vue recommends the Composition API for new projects, but the Options API is still a valid, first-class way to build Vue components.

Should beginners learn the Options API or the Composition API?

Beginners can start with either, but the Composition API with <script setup> is how modern Vue is written and what most current courses and job postings expect. Learning the Composition API first sets you up for real-world Vue 3 work. Our free, interactive Learn Vue tutorial teaches it from the ground up with runnable examples you can edit in the browser.

Can you mix the Options API and Composition API?

Yes. You can use both across different components in the same project, and you can even add a setup() function to an Options API component. For readability, most teams pick one style per component and often adopt the Composition API only for new components.

Is the Composition API faster than the Options API?

At runtime they perform almost identically, because both compile to the same kind of component instance. The Composition API with <script setup> can produce slightly smaller bundles thanks to better minification, but for most apps the practical difference in speed is negligible.

Related Courses

Start learning Vue.js for free

Comments

Latest Vue School Articles

5 Component Design Patterns to Boost Your Vue.js Applications

5 Component Design Patterns to Boost Your Vue.js Applications

5 essential Vue.js component design patterns, including branching components, slots usage, list organization, smart vs dumb components, and form handling - perfect for both Vue beginners and experienced developers looking to improve code maintainability and scalability.
Vibe Coding a Collaborative Editor with Comment Support with Nuxt UI and Jazz

Vibe Coding a Collaborative Editor with Comment Support with Nuxt UI and Jazz

Why I built a Nuxt + Jazz powered real time editor, how you can use it, and a list of takeaways on building with the help of AI.
VueSchool logo

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 250.000 users have already joined us. You are welcome too!

Follow us on Social