KS
Killer-Skills

native-data-fetching — how to use native-data-fetching how to use native-data-fetching, native-data-fetching vs axios, native-data-fetching setup guide, what is native-data-fetching, native-data-fetching install, expo networking with native-data-fetching, native-data-fetching for React Query, native-data-fetching alternative, native-data-fetching and SWR, native-data-fetching for API requests

v1.0.0
GitHub

About this Skill

Perfect for Expo Networking Agents needing efficient data fetching and caching capabilities. native-data-fetching is a skill that enables Expo networking for API requests, data fetching, caching, and network debugging, utilizing technologies like expo/fetch.

Features

Implements API requests using expo/fetch
Sets up data fetching with React Query or SWR
Handles caching strategies for optimized performance
Debugs network failures and handles offline scenarios
Manages authentication and token management
Configures API URLs and environment variables

# Core Topics

satsigner satsigner
[46]
[22]
Updated: 2/27/2026

Quality Score

Top 5%
58
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add satsigner/satsigner

Agent Capability Analysis

The native-data-fetching MCP Server by satsigner is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use native-data-fetching, native-data-fetching vs axios, native-data-fetching setup guide.

Ideal Agent Persona

Perfect for Expo Networking Agents needing efficient data fetching and caching capabilities.

Core Value

Empowers agents to handle API requests, implement caching strategies, and manage UTXO and signing using React Query or SWR, with a preference for expo/fetch over axios, enabling seamless data fetching and network debugging.

Capabilities Granted for native-data-fetching MCP Server

Implementing API requests with environment variable configuration
Setting up data fetching and caching using React Query or SWR
Debugging network failures and handling offline scenarios
Managing authentication and token validation

! Prerequisites & Limits

  • Requires Expo networking project setup
  • Prefer expo/fetch over axios for requests
Project
SKILL.md
10.6 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Expo Networking

You MUST use this skill for ANY networking work including API requests, data fetching, caching, or network debugging.

When to Use

Use this router when:

  • Implementing API requests
  • Setting up data fetching (React Query, SWR)
  • Debugging network failures
  • Implementing caching strategies
  • Handling offline scenarios
  • Authentication/token management
  • Configuring API URLs and environment variables

Preferences

  • Avoid axios, prefer expo/fetch

Common Issues & Solutions

1. Basic Fetch Usage

Simple GET request:

tsx
1const fetchUser = async (userId: string) => { 2 const response = await fetch(`https://api.example.com/users/${userId}`); 3 4 if (!response.ok) { 5 throw new Error(`HTTP error! status: ${response.status}`); 6 } 7 8 return response.json(); 9};

POST request with body:

tsx
1const createUser = async (userData: UserData) => { 2 const response = await fetch("https://api.example.com/users", { 3 method: "POST", 4 headers: { 5 "Content-Type": "application/json", 6 Authorization: `Bearer ${token}`, 7 }, 8 body: JSON.stringify(userData), 9 }); 10 11 if (!response.ok) { 12 const error = await response.json(); 13 throw new Error(error.message); 14 } 15 16 return response.json(); 17};

2. React Query (TanStack Query)

Setup:

tsx
1// app/_layout.tsx 2import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; 3 4const queryClient = new QueryClient({ 5 defaultOptions: { 6 queries: { 7 staleTime: 1000 * 60 * 5, // 5 minutes 8 retry: 2, 9 }, 10 }, 11}); 12 13export default function RootLayout() { 14 return ( 15 <QueryClientProvider client={queryClient}> 16 <Stack /> 17 </QueryClientProvider> 18 ); 19}

Fetching data:

tsx
1import { useQuery } from "@tanstack/react-query"; 2 3function UserProfile({ userId }: { userId: string }) { 4 const { data, isLoading, error, refetch } = useQuery({ 5 queryKey: ["user", userId], 6 queryFn: () => fetchUser(userId), 7 }); 8 9 if (isLoading) return <Loading />; 10 if (error) return <Error message={error.message} />; 11 12 return <Profile user={data} />; 13}

Mutations:

tsx
1import { useMutation, useQueryClient } from "@tanstack/react-query"; 2 3function CreateUserForm() { 4 const queryClient = useQueryClient(); 5 6 const mutation = useMutation({ 7 mutationFn: createUser, 8 onSuccess: () => { 9 // Invalidate and refetch 10 queryClient.invalidateQueries({ queryKey: ["users"] }); 11 }, 12 }); 13 14 const handleSubmit = (data: UserData) => { 15 mutation.mutate(data); 16 }; 17 18 return <Form onSubmit={handleSubmit} isLoading={mutation.isPending} />; 19}

3. Error Handling

Comprehensive error handling:

tsx
1class ApiError extends Error { 2 constructor(message: string, public status: number, public code?: string) { 3 super(message); 4 this.name = "ApiError"; 5 } 6} 7 8const fetchWithErrorHandling = async (url: string, options?: RequestInit) => { 9 try { 10 const response = await fetch(url, options); 11 12 if (!response.ok) { 13 const error = await response.json().catch(() => ({})); 14 throw new ApiError( 15 error.message || "Request failed", 16 response.status, 17 error.code 18 ); 19 } 20 21 return response.json(); 22 } catch (error) { 23 if (error instanceof ApiError) { 24 throw error; 25 } 26 // Network error (no internet, timeout, etc.) 27 throw new ApiError("Network error", 0, "NETWORK_ERROR"); 28 } 29};

Retry logic:

tsx
1const fetchWithRetry = async ( 2 url: string, 3 options?: RequestInit, 4 retries = 3 5) => { 6 for (let i = 0; i < retries; i++) { 7 try { 8 return await fetchWithErrorHandling(url, options); 9 } catch (error) { 10 if (i === retries - 1) throw error; 11 // Exponential backoff 12 await new Promise((r) => setTimeout(r, Math.pow(2, i) * 1000)); 13 } 14 } 15};

4. Authentication

Token management:

tsx
1import * as SecureStore from "expo-secure-store"; 2 3const TOKEN_KEY = "auth_token"; 4 5export const auth = { 6 getToken: () => SecureStore.getItemAsync(TOKEN_KEY), 7 setToken: (token: string) => SecureStore.setItemAsync(TOKEN_KEY, token), 8 removeToken: () => SecureStore.deleteItemAsync(TOKEN_KEY), 9}; 10 11// Authenticated fetch wrapper 12const authFetch = async (url: string, options: RequestInit = {}) => { 13 const token = await auth.getToken(); 14 15 return fetch(url, { 16 ...options, 17 headers: { 18 ...options.headers, 19 Authorization: token ? `Bearer ${token}` : "", 20 }, 21 }); 22};

Token refresh:

tsx
1let isRefreshing = false; 2let refreshPromise: Promise<string> | null = null; 3 4const getValidToken = async (): Promise<string> => { 5 const token = await auth.getToken(); 6 7 if (!token || isTokenExpired(token)) { 8 if (!isRefreshing) { 9 isRefreshing = true; 10 refreshPromise = refreshToken().finally(() => { 11 isRefreshing = false; 12 refreshPromise = null; 13 }); 14 } 15 return refreshPromise!; 16 } 17 18 return token; 19};

5. Offline Support

Check network status:

tsx
1import NetInfo from "@react-native-community/netinfo"; 2 3// Hook for network status 4function useNetworkStatus() { 5 const [isOnline, setIsOnline] = useState(true); 6 7 useEffect(() => { 8 return NetInfo.addEventListener((state) => { 9 setIsOnline(state.isConnected ?? true); 10 }); 11 }, []); 12 13 return isOnline; 14}

Offline-first with React Query:

tsx
1import { onlineManager } from "@tanstack/react-query"; 2import NetInfo from "@react-native-community/netinfo"; 3 4// Sync React Query with network status 5onlineManager.setEventListener((setOnline) => { 6 return NetInfo.addEventListener((state) => { 7 setOnline(state.isConnected ?? true); 8 }); 9}); 10 11// Queries will pause when offline and resume when online

6. Environment Variables

Using environment variables for API configuration:

Expo supports environment variables with the EXPO_PUBLIC_ prefix. These are inlined at build time and available in your JavaScript code.

tsx
1// .env 2EXPO_PUBLIC_API_URL=https://api.example.com 3EXPO_PUBLIC_API_VERSION=v1 4 5// Usage in code 6const API_URL = process.env.EXPO_PUBLIC_API_URL; 7 8const fetchUsers = async () => { 9 const response = await fetch(`${API_URL}/users`); 10 return response.json(); 11};

Environment-specific configuration:

tsx
1// .env.development 2EXPO_PUBLIC_API_URL=http://localhost:3000 3 4// .env.production 5EXPO_PUBLIC_API_URL=https://api.production.com

Creating an API client with environment config:

tsx
1// api/client.ts 2const BASE_URL = process.env.EXPO_PUBLIC_API_URL; 3 4if (!BASE_URL) { 5 throw new Error("EXPO_PUBLIC_API_URL is not defined"); 6} 7 8export const apiClient = { 9 get: async <T,>(path: string): Promise<T> => { 10 const response = await fetch(`${BASE_URL}${path}`); 11 if (!response.ok) throw new Error(`HTTP ${response.status}`); 12 return response.json(); 13 }, 14 15 post: async <T,>(path: string, body: unknown): Promise<T> => { 16 const response = await fetch(`${BASE_URL}${path}`, { 17 method: "POST", 18 headers: { "Content-Type": "application/json" }, 19 body: JSON.stringify(body), 20 }); 21 if (!response.ok) throw new Error(`HTTP ${response.status}`); 22 return response.json(); 23 }, 24};

Important notes:

  • Only variables prefixed with EXPO_PUBLIC_ are exposed to the client bundle
  • Never put secrets (API keys with write access, database passwords) in EXPO_PUBLIC_ variables—they're visible in the built app
  • Environment variables are inlined at build time, not runtime
  • Restart the dev server after changing .env files
  • For server-side secrets in API routes, use variables without the EXPO_PUBLIC_ prefix

TypeScript support:

tsx
1// types/env.d.ts 2declare global { 3 namespace NodeJS { 4 interface ProcessEnv { 5 EXPO_PUBLIC_API_URL: string; 6 EXPO_PUBLIC_API_VERSION?: string; 7 } 8 } 9} 10 11export {};

7. Request Cancellation

Cancel on unmount:

tsx
1useEffect(() => { 2 const controller = new AbortController(); 3 4 fetch(url, { signal: controller.signal }) 5 .then((response) => response.json()) 6 .then(setData) 7 .catch((error) => { 8 if (error.name !== "AbortError") { 9 setError(error); 10 } 11 }); 12 13 return () => controller.abort(); 14}, [url]);

With React Query (automatic):

tsx
1// React Query automatically cancels requests when queries are invalidated 2// or components unmount

Decision Tree

User asks about networking
  |-- Basic fetch?
  |   \-- Use fetch API with error handling
  |
  |-- Need caching/state management?
  |   |-- Complex app -> React Query (TanStack Query)
  |   \-- Simpler needs -> SWR or custom hooks
  |
  |-- Authentication?
  |   |-- Token storage -> expo-secure-store
  |   \-- Token refresh -> Implement refresh flow
  |
  |-- Error handling?
  |   |-- Network errors -> Check connectivity first
  |   |-- HTTP errors -> Parse response, throw typed errors
  |   \-- Retries -> Exponential backoff
  |
  |-- Offline support?
  |   |-- Check status -> NetInfo
  |   \-- Queue requests -> React Query persistence
  |
  |-- Environment/API config?
  |   |-- Client-side URLs -> EXPO_PUBLIC_ prefix in .env
  |   |-- Server secrets -> Non-prefixed env vars (API routes only)
  |   \-- Multiple environments -> .env.development, .env.production
  |
  \-- Performance?
      |-- Caching -> React Query with staleTime
      |-- Deduplication -> React Query handles this
      \-- Cancellation -> AbortController or React Query

Common Mistakes

Wrong: No error handling

tsx
1const data = await fetch(url).then((r) => r.json());

Right: Check response status

tsx
1const response = await fetch(url); 2if (!response.ok) throw new Error(`HTTP ${response.status}`); 3const data = await response.json();

Wrong: Storing tokens in AsyncStorage

tsx
1await AsyncStorage.setItem("token", token); // Not secure!

Right: Use SecureStore for sensitive data

tsx
1await SecureStore.setItemAsync("token", token);

Example Invocations

User: "How do I make API calls in React Native?" -> Use fetch, wrap with error handling

User: "Should I use React Query or SWR?" -> React Query for complex apps, SWR for simpler needs

User: "My app needs to work offline" -> Use NetInfo for status, React Query persistence for caching

User: "How do I handle authentication tokens?" -> Store in expo-secure-store, implement refresh flow

User: "API calls are slow" -> Check caching strategy, use React Query staleTime

User: "How do I configure different API URLs for dev and prod?" -> Use EXPOPUBLIC env vars with .env.development and .env.production files

User: "Where should I put my API key?" -> Client-safe keys: EXPOPUBLIC in .env. Secret keys: non-prefixed env vars in API routes only

Related Skills

Looking for an alternative to native-data-fetching or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication