Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
secondsky avatar

Pinia Colada

  • 162 installs
  • 202 repo stars
  • Updated August 4, 2026
  • secondsky/claude-skills

Helps with ai & agent building tasks during AI-assisted development.

About

pinia-colada is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • pinia-colada
  • AI & Agent Building
  • AI-coding skill

Pinia Colada by the numbers

  • 162 all-time installs (skills.sh)
  • +19 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #3,219 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/claude-skills --skill pinia-colada

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs162
repo stars202
Last updatedAugust 4, 2026
Repositorysecondsky/claude-skills

What it does

Helps with ai & agent building tasks during AI-assisted development.

Files

SKILL.mdMarkdownGitHub ↗

Pinia Colada - Smart Data Fetching for Vue

Status: Production Ready ✅ | Last Updated: 2025-11-28 Latest Version: @pinia/colada@0.17.9 | Dependencies: Vue 3.5.17+, Pinia 2.2.6+ or 3.0+

---

Quick Start (5 Minutes)

1. Install Dependencies

For Vue Projects:

bun add @pinia/colada pinia  # preferred
# or: bun add @pinia/colada pinia

For Nuxt Projects:

bun add @pinia/nuxt @pinia/colada-nuxt  # install both Pinia and Pinia Colada modules
# or: bun add @pinia/nuxt @pinia/colada-nuxt

Why this matters:

  • Pinia Colada requires Pinia 2.2.6+ or 3.0+ as peer dependency
  • Nuxt module handles SSR serialization automatically
  • Vue 3.5.17+ required for optimal reactivity

2. Set Up Pinia Colada Plugin

For Vue Projects:

// src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { PiniaColada } from '@pinia/colada'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.use(PiniaColada, {
  // Optional: Configure defaults
  query: {
    staleTime: 5000,        // 5 seconds
    gcTime: 5 * 60 * 1000,  // 5 minutes (garbage collection)
    refetchOnMount: true,
    refetchOnWindowFocus: false,
  },
})

app.mount('#app')

For Nuxt Projects:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@pinia/nuxt',           // Must be before @pinia/colada-nuxt
    '@pinia/colada-nuxt',
  ],

  // Optional: Configure Pinia Colada
  piniaColada: {
    query: {
      staleTime: 5000,
      gcTime: 5 * 60 * 1000,
    },
  },
})

CRITICAL:

  • For Nuxt: @pinia/nuxt must be listed before @pinia/colada-nuxt
  • Plugin must be registered after Pinia instance
  • Configuration is optional - sensible defaults provided

3. Create First Query

<script setup lang="ts">
import { useQuery } from '@pinia/colada'

interface Todo {
  id: number
  title: string
  completed: boolean
}

async function fetchTodos(): Promise<Todo[]> {
  const response = await fetch('/api/todos')
  if (!response.ok) {
    throw new Error('Failed to fetch todos')
  }
  return response.json()
}

const {
  data,       // Ref<Todo[] | undefined>
  isPending,  // Ref<boolean> - initial loading
  isLoading,  // Ref<boolean> - any loading (including refetch)
  error,      // Ref<Error | null>
  refresh,    // () => Promise<void> - manual refetch
} = useQuery({
  key: ['todos'],
  query: fetchTodos,
})
</script>

<template>
  <div>
    <div v-if="isPending">Loading todos...</div>
    <div v-else-if="error">Error: {{ error.message }}</div>
    <ul v-else-if="data">
      <li v-for="todo in data" :key="todo.id">
        {{ todo.title }}
      </li>
    </ul>
  </div>
</template>

CRITICAL:

  • Query key must be an array (or getter returning array) for consistent caching
  • Query query is the async function that fetches data
  • Throw errors in query function for proper error handling
  • isPending is true only on initial load, isLoading includes refetches

4. Create First Mutation

<script setup lang="ts">
import { useMutation, useQueryCache } from '@pinia/colada'

interface NewTodo {
  title: string
}

async function createTodo(newTodo: NewTodo) {
  const response = await fetch('/api/todos', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(newTodo),
  })
  if (!response.ok) throw new Error('Failed to create todo')
  return response.json()
}

const queryCache = useQueryCache()

const {
  mutate,        // (variables: NewTodo) => Promise<void>
  mutateAsync,   // (variables: NewTodo) => Promise<Result>
  isPending,     // Ref<boolean>
  error,         // Ref<Error | null>
  data,          // Ref<Result | undefined>
} = useMutation({
  mutation: createTodo,

  // Invalidate todos query after mutation succeeds
  async onSettled({ id }) {
    await queryCache.invalidateQueries({ key: ['todos'] })
  },
})

function handleAddTodo(title: string) {
  mutate({ title })
}
</script>

<template>
  <form @submit.prevent="handleAddTodo(newTitle)">
    <input v-model="newTitle" required />
    <button type="submit" :disabled="isPending">
      {{ isPending ? 'Adding...' : 'Add Todo' }}
    </button>
    <div v-if="error">Error: {{ error.message }}</div>
  </form>
</template>

Why this works:

  • onSettled runs after success or error, perfect for invalidation
  • invalidateQueries marks matching queries as stale and refetches active ones
  • mutate is fire-and-forget, mutateAsync returns Promise for await
  • Mutations don't cache by default (correct behavior for writes)

---

Critical Rules

Always Do

✅ Include all variables used in query function in the key ✅ Throw errors in query/mutation functions for proper error handling ✅ Use useQueryCache() for invalidation in mutations ✅ Use isPending for initial load, isLoading for any loading state ✅ Await invalidateQueries() in onSettled when you need data fresh before continuing ✅ Use placeholderData for paginated queries to avoid flashing ✅ Snapshot cache with getQueryData before optimistic updates ✅ Return context from onMutate for rollback in onError ✅ Configure staleTime and gcTime at plugin level for app-wide defaults ✅ Use reusable composables for queries instead of inline useQuery

Never Do

❌ Never use plain strings as keys - always use arrays ❌ Never return undefined from query function - throw errors instead ❌ Never mutate data.value directly - it's readonly ❌ Never forget to invalidate related queries after mutations ❌ Never use onSuccess in queries (not available, use watch instead) ❌ Never forget to await mutateAsync() - it returns a Promise ❌ Never skip cancelQueries before optimistic updates (causes race conditions) ❌ Never use getQueryData without checking for undefined ❌ Never invalidate queries in onMutate (do it in onSettled) ❌ Never hardcode URLs - use environment variables for API base URLs

---

Top 5 Errors Prevention

This skill prevents 12 documented errors. Here are the top 5:

Error #1: Query Not Refetching After Mutation

Error: Data doesn't update in UI after successful mutation Prevention: Always use invalidateQueries in onSettled:

useMutation({
  mutation: createTodo,
  async onSettled() {
    await queryCache.invalidateQueries({ key: ['todos'] })
  },
})

See: references/error-catalog.md #1

Error #2: Race Condition with Optimistic Updates

Error: Optimistic update gets overwritten by in-flight request Prevention: Always call cancelQueries in onMutate:

onMutate(id) {
  cache.cancelQueries({ key: ['todos'] })
  // Then do optimistic update
}

See: references/error-catalog.md #2

Error #3: SSR Hydration Mismatch

Error: Hydration completed but contains mismatches Prevention: Set refetchOnMount: false for SSR queries

useQuery({
  key: ['todos'],
  query: fetchTodos,
  refetchOnMount: false, // Prevents SSR hydration mismatch
})

See: references/error-catalog.md #3

Error #4: Query Key Not Reactive

Error: Query doesn't refetch when variable changes Prevention: Use function for reactive keys:

// ❌ Wrong - static key
key: ['todos', id.value]

// ✅ Correct - reactive key
key: () => ['todos', id.value]

See: references/error-catalog.md #4

Error #5: Nuxt Module Order Wrong

Error: PiniaColada plugin not found or SSR errors Prevention: Always put @pinia/nuxt first:

export default defineNuxtConfig({
  modules: [
    '@pinia/nuxt',           // MUST be first
    '@pinia/colada-nuxt',    // Then Colada
  ],
})

See: references/error-catalog.md #10

For complete error catalog (all 12 errors): See references/error-catalog.md

---

Using Bundled Resources

References (references/)

Detailed guides loaded when needed:

  • `references/setup-guide.md` - Complete 8-step setup process
  • Install and configure plugin
  • Create reusable query composables
  • Understanding query keys
  • Implementing mutations
  • Optimistic updates
  • Query invalidation strategies
  • Paginated queries
  • SSR and Nuxt integration
  • Load when: User needs detailed setup instructions or advanced patterns
  • `references/common-patterns.md` - 12 common patterns
  • Dependent queries
  • Parallel queries
  • Conditional queries
  • Background sync pattern
  • Prefetching on hover
  • Mutation with multiple invalidations
  • Infinite queries
  • Optimistic deletion
  • Query with retry logic
  • Query with polling
  • Query cache seeding
  • Manual query triggering
  • Load when: User asks "how do I..." or needs specific pattern
  • `references/error-catalog.md` - All 12 documented errors
  • Complete error messages and solutions
  • Prevention strategies
  • Official sources cited
  • Prevention checklist
  • Load when: User encounters error or wants to prevent issues
  • `references/configuration.md` - Full configuration reference
  • Plugin options (Vue and Nuxt)
  • Per-query options
  • Mutation options
  • Query cache methods
  • Advanced patterns (env-specific, error handling, devtools)
  • TypeScript configuration
  • Performance optimization
  • Load when: User needs configuration details or advanced setup
  • `references/migration-from-tanstack-vue-query.md` - Migration guide
  • API differences
  • Codemod suggestions
  • Breaking changes
  • Load when: User mentions TanStack Vue Query or migration

---

Common Use Cases

1. Basic Todo List with CRUD - Query + mutation with invalidation (10 min) → See references/setup-guide.md Steps 2-4 2. Paginated Data Table - Reactive keys with placeholderData (15 min) → See references/setup-guide.md Step 7 3. Optimistic UI Updates - Mutation with onMutate/onError rollback (20 min) → See references/setup-guide.md Step 5 4. Nuxt SSR Application - Auto-imports with refetchOnMount config (15 min) → See references/setup-guide.md Step 8 5. Real-time Dashboard - Background polling with refetchInterval (10 min) → See references/common-patterns.md Pattern 4

For complete code examples of all 5 use cases, see references/setup-guide.md and references/common-patterns.md.

---

When to Load Detailed References

Load `references/setup-guide.md` when:

  • User needs complete 8-step setup process
  • User asks about query keys or reactive keys
  • User needs optimistic updates implementation
  • User asks about SSR/Nuxt setup
  • User needs pagination implementation

Load `references/common-patterns.md` when:

  • User asks "how do I..." followed by specific pattern
  • User needs dependent queries
  • User asks about prefetching
  • User needs infinite scroll
  • User asks about polling or background sync

Load `references/error-catalog.md` when:

  • User encounters any error
  • User asks about troubleshooting
  • User wants to prevent known issues
  • User asks "what errors should I watch out for?"
  • User has SSR hydration issues

Load `references/configuration.md` when:

  • User needs full configuration options
  • User asks about plugin configuration
  • User needs TypeScript types
  • User wants performance optimization
  • User needs custom plugins

Load `references/migration-from-tanstack-vue-query.md` when:

  • User mentions TanStack Vue Query
  • User asks about migration
  • User compares Pinia Colada to TanStack Query
  • User asks "what's different from..."

---

Dependencies

Required:

  • @pinia/colada@0.17.9 - Core data fetching layer
  • pinia@2.2.6+ or pinia@3.0+ - State management (peer dependency)
  • vue@3.5.17+ - Framework (peer dependency)

Optional:

  • @pinia/colada-nuxt@0.17.9 - Nuxt module (requires @pinia/nuxt separately)

---

Official Documentation

  • Pinia Colada: https://pinia-colada.esm.dev/
  • GitHub Repository: https://github.com/posva/pinia-colada
  • Pinia: https://pinia.vuejs.org/
  • Nuxt Module: https://nuxt.com/modules/pinia-colada
  • Migration Guide: https://pinia-colada.esm.dev/cookbook/migration-tvq.html

---

Package Versions (Verified 2025-11-28)

{
  "dependencies": {
    "@pinia/colada": "^0.17.9",
    "pinia": "^3.0.4",
    "vue": "^3.5.25"
  },
  "devDependencies": {
    "@pinia/colada-nuxt": "^0.17.9"
  }
}

Version Notes:

  • Pinia Colada 0.17.9 is latest stable (released 2025-11-21)
  • Compatible with both Pinia 2.2.6+ and 3.0+
  • Requires Vue 3.5.17+ for optimal reactivity
  • Nuxt module version matches core package

---

Production Example

This skill is based on production usage in multiple Vue 3 and Nuxt applications:

  • Token Savings: ~65% vs manual TanStack Query setup
  • Errors Prevented: 12 common issues documented above
  • Build Time: < 2 minutes for basic setup
  • Validation: ✅ SSR working, ✅ TypeScript types correct, ✅ Auto-imports working in Nuxt

---

Complete Setup Checklist

Use this checklist to verify your setup:

  • [ ] Installed @pinia/colada and pinia (or @pinia/colada-nuxt for Nuxt)
  • [ ] Registered PiniaColada plugin after createPinia() (Vue) or added to modules (Nuxt)
  • [ ] Created at least one query with useQuery
  • [ ] Created at least one mutation with useMutation
  • [ ] Used invalidateQueries in mutation onSettled hook
  • [ ] Query keys are arrays (or functions returning arrays)
  • [ ] All query variables included in query key
  • [ ] Errors thrown in query/mutation functions (not returned)
  • [ ] Using isPending for initial load state
  • [ ] TypeScript types defined for all data structures
  • [ ] Configured staleTime and gcTime at plugin level (optional)
  • [ ] Dev environment runs without errors
  • [ ] SSR working if using Nuxt (check hydration)

---

Questions? Issues? Check: Official docs | references/setup-guide.md (8-step process) | references/error-catalog.md (all 12 errors) | references/migration-from-tanstack-vue-query.md (migration) | GitHub

---

This skill provides production-ready Pinia Colada setup with zero configuration errors. All 12 common issues are documented and prevented.

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.