Skip to content

What Is a Composable in Vue?

Vue composables are a design pattern and a structural building block in the Vue ecosystem: reusable functions used to share and manage logic between components.

A composable groups a piece of functionality so it can be used outside a single component — in another file or in several components. This keeps the code tidy, creates reusable parts and makes sharing logic between components easy.

A composable is usually a JavaScript function built for one task. It typically uses Vue's reactivity (ref, reactive, computed) to manage state. Here is a simple example:

JavaScriptCode fragment
// useCounter.js
import { ref } from 'vue';

export function useCounter() {
  const count = ref(0);

  function increment() {
    count.value++;
  }

  function decrement() {
    count.value--;
  }

  return {
    count,
    increment,
    decrement,
  };
}

This composable manages the state of a counter together with its increment and decrement functions, and any component can use it.

Usage:

VueCode fragment
<!-- MyComponent.vue -->
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

<script>
import { useCounter } from './useCounter';

export default {
  setup() {
    const { count, increment, decrement } = useCounter();

    return { count, increment, decrement };
  },
};
</script>

Here the useCounter composable is used inside MyComponent — an easy, tidy way to bring the counter's state and behaviour into the component.

Note: Templates unwrap only top-level refs. If you return the whole object (return { counter }) and write {{ counter.count }}, the ref is not unwrapped; destructure the composable's result as above, or wrap it with reactive().

Have a question about this article? Write to me