
Studio Queries
OfficialFreeStreamline data fetching in Supabase Studio with React Query.
Free · Opens the source repo
What Studio Queries does
The Studio Queries skill provides a structured approach to data fetching and mutation in Supabase Studio, utilizing React Query conventions. This skill is particularly useful for developers working within the Supabase ecosystem, as it offers clear guidelines for implementing query hooks, mutation hooks, and query keys. By adhering to the specified patterns, developers can ensure that their data interactions are efficient and maintainable.
The skill emphasizes the importance of defining query keys in a consistent manner, with each domain having its own keys.ts file. This approach not only enhances code readability but also prevents common pitfalls associated with inlining query keys directly in components. Additionally, the skill outlines the preferred pattern for query options, which includes type safety and the ability to handle errors gracefully. This is achieved through a private function that validates input and manages responses, ensuring that developers can focus on building features rather than debugging data fetching logic.
For mutation operations, the skill provides a robust framework that includes the validation of required variables and automatic cache invalidation upon successful updates. This ensures that the application state remains consistent and up-to-date without requiring manual intervention. The skill also highlights best practices for using query options in React components, making it easier for developers to manage loading states and errors effectively.
Overall, this skill is designed for developers who are building applications with Supabase and React. It simplifies the process of implementing data fetching and mutations, allowing developers to follow best practices and maintain high code quality throughout their projects.
When to use it
Use this skill when developing or reviewing query and mutation hooks for Supabase Studio applications.
When not to use it
Avoid using this skill if you are not working within the Supabase ecosystem or do not require React Query for data management.
What you can build with it
Implementing a New API Endpoint
Use this skill to create the first fetch or mutation for a new API endpoint in Supabase Studio, following best practices.
Reviewing Existing Query Hooks
Leverage the guidelines provided by this skill to review and improve existing query hooks and mutation hooks in your application.
Ensuring Type Safety in Queries
Utilize the query options pattern to ensure type safety and consistent error handling across your data fetching logic.
How to install Studio Queries
View source1. Install with the skills CLI
npx skills add supabase/supabase/studio-queries --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by supabaseStudio Queries & Mutations (React Query)
Follow the patterns in apps/studio/data/. Reference examples:
- Query options:
apps/studio/data/table-editor/table-editor-query.ts - Mutation hook:
apps/studio/data/edge-functions/edge-functions-update-mutation.ts - Keys:
apps/studio/data/edge-functions/keys.ts
Query Keys
Define a keys.ts per domain. Export *Keys helpers using array keys with as const. Never inline query keys in components.
export const edgeFunctionsKeys = {
list: (projectRef: string | undefined) => ['projects', projectRef, 'edge-functions'] as const,
detail: (projectRef: string | undefined, slug: string | undefined) =>
['projects', projectRef, 'edge-function', slug, 'detail'] as const,
}
Query Options (preferred pattern)
Use queryOptions from @tanstack/react-query. This gives type safety and works with both useQuery() and queryClient.fetchQuery().
Rules:
- Export
XVariables,XData, andXErrortypes (prefixed with the domain name) - Implement a private
getX(variables, signal?)function:- Throws if required variables are missing
- Passes
signalfor cancellation - Calls
handleError(error)on failure (which throws); returnsdataon success - Not exported — use
queryClient.fetchQuery(xQueryOptions(...))for imperative fetching
- Export
xQueryOptions()usingqueryOptions - Gate with
enabledso the query doesn't run until required variables exist - Platform-only queries: include
IS_PLATFORMfromlib/constantsinenabled - Don't add extra params to
xQueryOptions— callers override by destructuring:{ ...xQueryOptions(vars), enabled: true }
import { queryOptions } from '@tanstack/react-query'
import { xKeys } from './keys'
import { get, handleError } from '@/data/fetchers'
import { IS_PLATFORM } from '@/lib/constants'
import { ResponseError } from '@/types'
export type XVariables = { projectRef?: string }
export type XError = ResponseError
async function getX({ projectRef }: XVariables, signal?: AbortSignal) {
if (!projectRef) throw new Error('projectRef is required')
const { data, error } = await get('/v1/projects/{ref}/x', {
params: { path: { ref: projectRef } },
signal,
})
if (error) handleError(error)
return data
}
export type XData = Awaited<ReturnType<typeof getX>>
export const xQueryOptions = ({ projectRef }: XVariables) =>
queryOptions({
queryKey: xKeys.list(projectRef),
queryFn: ({ signal }) => getX({ projectRef }, signal),
enabled: IS_PLATFORM && typeof projectRef !== 'undefined',
})
Using Query Options in Components
import { useQuery } from '@tanstack/react-query'
import { xQueryOptions } from '@/data/x/x-query'
const { data, isPending, isError } = useQuery(xQueryOptions({ projectRef: project?.ref }))
Imperative Fetching (outside React or in callbacks)
const queryClient = useQueryClient()
const { data: project } = useSelectedProjectQuery()
const handleClick = useCallback(
async (id: number) => {
const data = await queryClient.fetchQuery(xQueryOptions({ id, projectRef: project?.ref }))
// use data...
},
[project?.ref, queryClient]
)
Mutation Hook
- Export a
Variablestype withprojectRef, identifiers, andpayload - Implement a private
updateX(vars)function with required variable validation andhandleError - Wrap in
useXMutation():- Accepts
UseMutationOptions(omitmutationFn) - Invalidates
list()+detail()keys inonSuccesswithawait Promise.all([...]) - Defaults to
toast.error(...)whenonErrorisn't provided
- Accepts
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'
import { xKeys } from './keys'
type XUpdateVariables = { projectRef: string; slug: string; payload: XPayload }
export const useXUpdateMutation = ({
onSuccess,
onError,
...options
}: UseMutationOptions<XData, XError, XUpdateVariables> = {}) => {
const queryClient = useQueryClient()
return useMutation({
mutationFn: updateX,
async onSuccess(data, variables, context) {
await Promise.all([
queryClient.invalidateQueries({
queryKey: xKeys.detail(variables.projectRef, variables.slug),
}),
queryClient.invalidateQueries({ queryKey: xKeys.list(variables.projectRef) }),
])
await onSuccess?.(data, variables, context)
},
async onError(error, variables, context) {
if (onError === undefined) toast.error(`Failed to update: ${error.message}`)
else onError(error, variables, context)
},
...options,
})
}
Component Usage
- Use React Query v5 flags:
isPendingfor initial load,isFetchingfor background refetches - Render states explicitly in order: pending → error → success
Frequently asked questions about Studio Queries
Similar skills
WinMD API Search
Easily find and explore Windows desktop APIs.
WebMCPify
Transform any web app into an agent-ready platform.
Phoenix Tracing
Instrument LLM applications with OpenInference tracing.
Foundry Hosted Agent CopilotKit
Guidance for developing agentic web apps on Azure.
Power Automate Foundation
Connect AI agents to Power Automate seamlessly.
Power Automate Flow Builder
Efficiently build and deploy Power Automate flows programmatically.
