Building Type-Safe APIs with Nuxt 3 and Prisma
Learn how to build end-to-end type-safe APIs using Nuxt 3 server routes and Prisma ORM for a seamless developer experience.
Understand the power of Vue 3's Composition API through practical, real-world composable patterns that you can use today.
Mbeah Essilfie
July 19, 2026 at 06:02 AM
Composables are functions that leverage Vue's Composition API to encapsulate and reuse stateful logic. Think of them as React hooks, but with Vue's reactivity system.
// composables/useDarkMode.ts
export function useDarkMode() {
const isDark = ref(false)
function toggle() {
isDark.value = !isDark.value
document.documentElement.classList.toggle('dark', isDark.value)
}
onMounted(() => {
isDark.value = document.documentElement.classList.contains('dark')
})
return { isDark, toggle }
}
// composables/useApi.ts
export function useApi<T>(url: MaybeRef<string>) {
const data = ref<T | null>(null)
const error = ref<Error | null>(null)
const loading = ref(false)
async function execute() {
loading.value = true
error.value = null
try {
const response = await fetch(unref(url))
if (!response.ok) throw new Error(response.statusText)
data.value = await response.json()
} catch (e) {
error.value = e as Error
} finally {
loading.value = false
}
}
// Auto-fetch when URL changes
watch(() => unref(url), execute, { immediate: true })
return { data, error, loading, refresh: execute }
}
// composables/useAuth.ts
const currentUser = ref<User | null>(null)
const isAuthenticated = computed(() => !!currentUser.value)
export function useAuth() {
async function login(credentials: LoginInput) {
const user = await $fetch('/api/auth/login', {
method: 'POST',
body: credentials,
})
currentUser.value = user
}
function logout() {
currentUser.value = null
navigateTo('/login')
}
return {
currentUser: readonly(currentUser),
isAuthenticated,
login,
logout,
}
}
use — Convention makes composables instantly recognizableMaybeRef params — Makes composables flexibleonUnmounted for intervals, listeners, etc.import { describe, it, expect } from 'vitest'
import { useDarkMode } from './useDarkMode'
describe('useDarkMode', () => {
it('toggles dark mode', () => {
const { isDark, toggle } = useDarkMode()
expect(isDark.value).toBe(false)
toggle()
expect(isDark.value).toBe(true)
})
})
Composables are the backbone of modern Vue development. Master them, and you'll write cleaner, more testable, more reusable code.
Fullstack Software Developer
Learn how to build end-to-end type-safe APIs using Nuxt 3 server routes and Prisma ORM for a seamless developer experience.
Go beyond basic utility classes and learn how to build cohesive, maintainable design systems with Tailwind CSS.
Stop saying 'it works on my machine.' Learn Docker fundamentals through the lens of frontend development workflows.
