Composable Factories and Parameterized Composables
Creating composable factories, scoping state per instance, avoiding shared singleton state.
Composable Factories and Parameterized Composables is a free Vue Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Composables That Take Parameters
A plain composable returns fixed behavior. A parameterized composable accepts arguments to customize what it does — a base URL, options, defaults — making one function serve many cases.
A Simple Parameterized Composable
Pass configuration as arguments. Here the URL is provided by the caller, so one useFetch works for any endpoint.
import { ref } from "vue"
export function useFetch(url) {
const data = ref(null)
fetch(url).then(r => r.json()).then(d => data.value = d)
return { data }
}Accepting an Options Object
For many knobs, take an options object with defaults. This keeps the call site readable and the composable flexible.
export function useFetch(url, options = {}) {
const { immediate = true, method = "GET" } = options
const data = ref(null)
function run() { /* fetch with method */ }
if (immediate) run()
return { data, run }
}What Is a Composable Factory?
A factory goes one step further: a function that returns a composable, pre-configured with shared settings. You configure once, then get a tailored composable to use across components.
Building a Factory
The outer function captures shared config (e.g. baseURL); the returned inner function is the composable, with the config baked in via closure.
export function createApi(baseURL) {
return function useApi(path) {
const data = ref(null)
fetch(baseURL + path).then(r => r.json()).then(d => data.value = d)
return { data }
}
}Using a Factory
Call the factory once (often in a shared module) to produce a configured composable, then import and use that everywhere.
// api.js
export const useApi = createApi("https://api.example.com")
// component
import { useApi } from "./api"
const { data } = useApi("/users")Scoped State Per Instance
Each time you call a composable, the refs it creates are fresh and local to that call. Two components calling useFetch get independent data refs — no accidental sharing.
const a = useFetch("/posts") // its own data ref
const b = useFetch("/comments") // a separate data refModule-Level Shared Singleton
Sometimes you WANT one shared instance. Declare state at module level (outside the function) and the composable closes over it — every caller shares the same refs.
import { ref } from "vue"
const user = ref(null) // module-level, shared
export function useAuth() {
function login(u) { user.value = u }
return { user, login }
}Per-Instance vs Singleton
- State inside the function → new per call (per-component) — forms, fetchers.
- State at module level → shared singleton — current user, theme, app-wide flags.
Choose based on whether the data is component-local or global.
Combining Factory and Singleton
A factory can also produce a singleton: create the shared state inside the factory call (runs once) and have the returned composable close over it.
export function createStore(initial) {
const state = ref(initial) // created once per factory call
return function useStore() {
return { state }
}
}
export const useCounter = createStore(0)When to Reach for a Factory
Use a factory when several composables share configuration (base URL, headers, client instance) or when you build a small library and want consumers to configure once. Otherwise a parameterized composable is simpler.
Quick Check
Check your understanding of composable factories and scoping.
Recap
You learned composable factories and scoping:
- Parameterized composables take arguments/options to customize behavior.
- A factory is a function returning a pre-configured composable (config captured via closure).
- State inside the function is per-instance; state at module level is a shared singleton.
- Use per-instance for component-local data, singleton for app-wide state (current user, theme).
Frequently asked questions
Is the “Composable Factories and Parameterized Composables” lesson free?
Yes — the full text of “Composable Factories and Parameterized Composables” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.
What will I learn in “Composable Factories and Parameterized Composables”?
Creating composable factories, scoping state per instance, avoiding shared singleton state. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Composable Factories and Parameterized Composables” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Advanced Reactivity: shallowRef and triggerRef
- Composable Factories and Parameterized Composables
- State Machines with XState in Vue
- effectScope for Grouped Effects