100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

The Composition API vs Options API

Compares Vue's two component authoring styles, explaining why the Composition API was introduced and when each approach makes sense in real projects.

Reactivity FundamentalsIntermediate9 min readJul 9, 2026
Analogies

The Composition API vs Options API

Vue 3 ships with two ways to author component logic. The Options API, inherited from Vue 2, organizes a component into fixed properties — data, methods, computed, watch, lifecycle hooks — each declared as a separate object key. The Composition API, introduced alongside Vue 3, instead gives you a set of importable functions (ref, reactive, computed, watch, onMounted, and so on) that you call inside a single setup() function or, more commonly today, directly inside a <script setup> block. Both APIs compile to the same underlying reactivity system and can even be mixed in the same application, but they lead to very different code organization as components grow.

🏏

Cricket analogy: Like a team that can organize training either by a fixed traditional schedule — batting, bowling, fielding drills as separate rigid blocks (Options API) — or by a modern position-based camp where an all-rounder's coach (Composition API function) runs batting, bowling, and fitness together for that one player, both ultimately building the same match-fit squad.

Why the Composition API exists

The Options API groups code by option type rather than by feature. A component that manages both a search filter and a pagination state ends up with its filter logic and pagination logic scattered across the data, computed, methods, and watch blocks. As components grow past a couple hundred lines, this makes a single logical concern hard to read top to bottom. The Composition API solves this by letting you colocate all the reactive state, computed values, and functions for one concern together, then repeat the pattern for the next concern. It also solves a deeper problem: reusing stateful logic across components. In the Options API, the only reuse mechanism is mixins, which suffer from unclear property origins and naming collisions. The Composition API replaces mixins with composables — plain functions that encapsulate and return reactive state — which are explicit, type-friendly, and free of naming collisions.

🏏

Cricket analogy: Like a team logbook organized by category — all batting stats in one ledger, all fielding stats in another — so tracking one player's all-round form means flipping between ledgers, versus a modern player-file that groups everything about that one cricketer together; reusing techniques via vague 'style notes' (mixins) causes confusion, while a documented specific drill routine (composable) is explicit and reusable.

script setup: the ergonomic sugar

<script setup> is compile-time syntax sugar over the Composition API's setup() function. Everything declared at the top level — variables, functions, imports — is automatically exposed to the template, without an explicit return statement. Props and emits are declared via the defineProps and defineEmits compiler macros rather than a setup(props, { emit }) signature. This trims a substantial amount of boilerplate compared to a plain setup() function, and it is the idiomatic way to write Composition API components in Vue 3 today.

🏏

Cricket analogy: Like a modern net-session app where every drill a player runs is automatically logged to their visible stat sheet without a coach manually re-entering each one, and specific intake forms (defineProps/defineEmits) capture exactly the fitness data coming in and the injury reports going out, cutting the paperwork a traditional clipboard system required.

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

const searchTerm = ref('')
const products = ref([
  { id: 1, name: 'Wireless Mouse', price: 25 },
  { id: 2, name: 'Mechanical Keyboard', price: 89 },
  { id: 3, name: 'USB-C Hub', price: 34 }
])

const filteredProducts = computed(() =>
  products.value.filter((p) =>
    p.name.toLowerCase().includes(searchTerm.value.toLowerCase())
  )
)
</script>

<template>
  <input v-model="searchTerm" placeholder="Search products..." />
  <ul>
    <li v-for="product in filteredProducts" :key="product.id">
      {{ product.name }}  ${{ product.price }}
    </li>
  </ul>
</template>

Angular's dependency-injection services and React's custom hooks solve the same reuse problem Vue composables solve — extracting stateful logic into a reusable, composable unit outside the component tree. Vue's composables are the closest conceptual sibling to React hooks, though composables don't have the 'rules of hooks' restriction on conditional calls, because Vue's reactivity is proxy-based rather than call-order-based.

Vue does not force a binary choice at the file level — you can adopt the Composition API incrementally, file by file, in an existing Options API codebase. A common mistake is assuming the two styles cannot coexist in one component; while you can technically use setup() alongside Options API properties in the same component, mixing them adds cognitive overhead and is discouraged. Pick one style per component.

  • The Options API organizes code by option type (data, methods, computed); the Composition API organizes code by logical feature.
  • The Composition API's setup() function (or <script setup>) uses imported functions like ref, reactive, and computed instead of fixed component options.
  • <script setup> is compiler sugar that removes the need to explicitly return values from setup() and simplifies prop/emit declarations via defineProps and defineEmits.
  • Composables (reusable functions built on Composition API primitives) replace Options API mixins and avoid mixins' naming-collision and unclear-origin problems.
  • Both APIs compile to the same reactivity system underneath, so performance is not a deciding factor between them.
  • New Vue 3 projects and the official documentation default to the Composition API with <script setup> as the recommended style.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#VueJsStudyNotes#WebDevelopment#TheCompositionAPIVsOptionsAPI#Composition#API#Options#Exists#APIs#StudyNotes#SkillVeris