gemini-api
Gemini API Patterns
SDK Setup
Use the @google/genai package with Expo Constants for API key management:
import { GoogleGenAI } from '@google/genai';
import Constants from 'expo-constants';
const genAI = new GoogleGenAI({
apiKey: Constants.expoConfig?.extra?.geminiApiKey as string
});
Available Models
| Model | ID | Best For |
|---|---|---|
| Gemini 3 Pro | gemini-3-pro-preview |
Advanced reasoning, complex tasks |
| Gemini 3 Flash | gemini-3-flash-preview |
Balanced speed/intelligence |
| Gemini 2.5 Flash | gemini-2.5-flash |
Price-performance, scale |
| Gemini 2.5 Flash-Lite | gemini-2.5-flash-lite |
High-throughput, cost-efficient |
| Gemini 2.5 Pro | gemini-2.5-pro |
Complex reasoning, code, math |
All models support 1M input tokens and 65K output tokens.
Basic Text Generation
const response = await genAI.models.generateContent({
model: 'gemini-3-flash-preview',
contents: 'Your prompt here',
});
const text = response.text ?? '';
Structured Content Format
For multi-turn or complex inputs, use the full contents structure:
const response = await genAI.models.generateContent({
model: 'gemini-3-flash-preview',
contents: [
{ role: 'user', parts: [{ text: 'First message' }] },
{ role: 'model', parts: [{ text: 'Assistant response' }] },
{ role: 'user', parts: [{ text: 'Follow-up question' }] },
],
});
System Instructions
Guide model behavior with system instructions in the config:
const response = await genAI.models.generateContent({
model: 'gemini-3-flash-preview',
contents: [{ role: 'user', parts: [{ text: userMessage }] }],
config: {
systemInstruction: 'You are a helpful language tutor. Respond in a friendly, encouraging tone.',
},
});
JSON Mode (Structured Output)
Request JSON responses for type-safe parsing:
async function generateJSON<T>(prompt: string, model: string): Promise<T> {
const result = await genAI.models.generateContent({
model,
contents: [{ role: 'user', parts: [{ text: prompt }] }],
config: {
responseMimeType: 'application/json',
},
});
return JSON.parse(result.text ?? '') as T;
}
With JSON Schema (Zod)
For strict schema validation:
import { z } from 'zod';
const CorrectionSchema = z.object({
correction: z.string(),
feedback: z.string(),
});
const result = await genAI.models.generateContent({
model: 'gemini-3-flash-preview',
contents: prompt,
config: {
responseMimeType: 'application/json',
responseSchema: CorrectionSchema,
},
});
Configuration Options
const response = await genAI.models.generateContent({
model: 'gemini-3-flash-preview',
contents: prompt,
config: {
temperature: 1.0, // Randomness (keep at 1.0 for Gemini 3)
topP: 0.95, // Nucleus sampling
topK: 40, // Top-k sampling
maxOutputTokens: 8192, // Limit response length
stopSequences: ['END'], // Stop generation triggers
systemInstruction: '...', // System prompt
responseMimeType: 'application/json', // Force JSON output
},
});
Temperature Warning
For Gemini 3 models, keep temperature at 1.0 (the default). Lowering it can cause:
- Response looping
- Degraded performance on complex tasks
- Unexpected behavior in reasoning
Error Handling Pattern
async function generateText(prompt: string, model: string): Promise<string> {
try {
const response = await genAI.models.generateContent({
model,
contents: prompt,
});
if (!response) {
throw new Error('No response from Gemini');
}
return response.text ?? '';
} catch (error) {
console.error('Error generating text:', error);
return '';
}
}
Multi-Turn Chat
Maintain conversation history:
async function chat(
systemPrompt: string,
messages: Array<{ role: 'user' | 'model'; text: string }>,
model: string
): Promise<string> {
const contents = messages.map((msg) => ({
role: msg.role,
parts: [{ text: msg.text }],
}));
const result = await genAI.models.generateContent({
model,
contents,
config: {
systemInstruction: systemPrompt,
},
});
return result.text ?? '';
}
Best Practices
- Always handle null/undefined: Use
response.text ?? ''for safe access - Type your JSON responses: Use generics with
JSON.parse()result - Use system instructions: Define persona and behavior expectations
- Keep Gemini 3 temperature at 1.0: Avoid performance degradation
- Validate JSON output: Structured format doesn't guarantee semantic correctness
- Choose appropriate model: Use Flash for speed, Pro for complex reasoning
Common Mistakes to Avoid
- Don't lower temperature below 1.0 for Gemini 3 models
- Don't assume JSON responses are semantically valid - always validate
- Don't forget to handle the case where
response.textis undefined - Don't use raw string concatenation for multi-turn - use proper contents array
More from jchaselubitz/drill-app
expo-router
Patterns for Expo Router including Stack configuration, native tabs, and file-based routing best practices. Apply when working with navigation, routing, or screen configuration.
106watermelondb
WatermelonDB models, observation patterns, and React integration. Use when writing or debugging model code, observers (findAndObserve, query.observe), or screens that display live-updating DB data.
37expo-audio
Guide for using expo-audio to implement audio playback and recording in React Native apps. Apply when working with audio features, sound playback, recording, or text-to-speech functionality.
17expo-glass-effect
Guide for using expo-glass-effect to create iOS native liquid glass UI effects. Apply when implementing glass effect UI components, cards, or surfaces on iOS.
9zod-v4-patterns
Ensures Zod v4 patterns are used correctly throughout the codebase. Apply when creating or modifying validation schemas, form schemas, or any Zod validators. Enforces v4 syntax and prevents deprecated v3 patterns.
5rn-button-component
Ensures buttons use the unified Button component with proper state management, icon support, and glass effect integration. Apply when creating or modifying buttons in the app.
5