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

Composables Explained

Understand what composables are, why they replace mixins as Vue's primary reuse pattern, and the conventions they follow.

The Composition API in DepthIntermediate8 min readJul 9, 2026
Analogies

Composables Explained

A composable is simply a function that uses Vue's Composition API primitives — ref, reactive, computed, watch, lifecycle hooks — to encapsulate and reuse stateful logic across components. Composables are Vue's answer to the reuse problem that Options API mixins solved poorly: mixins silently merged properties into a component, making it unclear where any given piece of state or method actually came from, and colliding names could overwrite each other unpredictably. Composables avoid this because everything they expose is explicit, returned as named values that the calling component destructures.

🏏

Cricket analogy: A composable is like a specialist fielding coach who can be brought into any team's training camp to teach catching drills, versus the old mixin approach which was like silently swapping players' kits before a match without telling anyone; a composable's explicit return values are like the coach handing back a clearly labeled drill sheet.

Anatomy of a composable

By convention, a composable is named starting with use (e.g. useMouse, useFetch, useLocalStorage), lives in its own file (often under a composables/ directory), and returns an object of reactive state and functions rather than a plain non-reactive object. Internally it can use any Composition API feature, including lifecycle hooks, since those correctly attach to whichever component instance calls the composable.

🏏

Cricket analogy: Naming a composable useMouse or useFetch is like labeling a training drill 'Fielding Drill 3' so any coach can find it in the team's shared drill folder, and because the drill attaches to whichever squad runs it, the same drill produces separate results for the U19 team and the senior team.

javascript
// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  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))

  return { x, y }
}

Using a composable in a component

Consuming a composable looks just like calling any other function inside <script setup>; the returned refs are used directly in the template, and Vue's reactivity system takes care of updating the DOM whenever the composable's internal state changes. Multiple components can call the same composable independently, and each call creates its own isolated instance of the state — there is no shared singleton unless the composable is explicitly written to share module-level state.

🏏

Cricket analogy: Calling useMouse() in a component is like a batter calling up their personal stance coach before an innings — each batter who calls the same coach gets individually tailored advice for their own stance, not a shared one, unless the coach is explicitly running a shared team-wide session (module-level state).

vue
<script setup>
import { useMouse } from '@/composables/useMouse'

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

<template>
  <p>Mouse position: {{ x }}, {{ y }}</p>
</template>

Composables are conceptually very close to React's custom hooks (functions prefixed with use that call other hooks internally). The major structural difference is that Vue composables are ordinary functions with no 'rules of hooks' restricting them to a fixed call order, because Vue's reactivity tracking doesn't depend on call order the way React's hook slots do.

A subtle pitfall: if a composable returns a plain destructured value from a reactive() object instead of refs, the returned value loses reactivity once destructured. Composables should generally return individual refs (or use toRefs() on a reactive object) so consumers can safely destructure the return value without breaking reactivity.

  • A composable is a function that encapsulates reusable stateful logic using Composition API primitives.
  • Composables replace Options API mixins, avoiding unclear property origins and naming collisions.
  • Naming convention: prefix with 'use' and typically place in a composables/ directory.
  • Lifecycle hooks called inside a composable correctly attach to whichever component invokes it.
  • Each call to a composable creates independent state unless module-level state is deliberately shared.
  • Composables should return refs (or toRefs() output) so their state stays reactive after destructuring.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#VueJsStudyNotes#WebDevelopment#ComposablesExplained#Composables#Explained#Anatomy#Composable#StudyNotes#SkillVeris