jchaselubitz/drill-app

gemini-api

Patterns for using Google Gemini API with structured output, JSON mode, and proper configuration. Apply when implementing AI features, text generation, or working with Gemini models.

First seen Jan 25, 2026

Installation

$ npx skills add jchaselubitz/drill-app --skill gemini-api

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from jchaselubitz/drill-app.

npx skills add jchaselubitz/drill-app

Browse all from jchaselubitz/drill-app

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Edit, Write, Grep, Glob
Declared agents gemini

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,440 B
  • docs SUMMARY.md 200 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 5 installs

SKILL.md

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

  1. Always handle null/undefined: Use response.text ?? '' for safe access
  2. Type your JSON responses: Use generics with JSON.parse() result
  3. Use system instructions: Define persona and behavior expectations
  4. Keep Gemini 3 temperature at 1.0: Avoid performance degradation
  5. Validate JSON output: Structured format doesn't guarantee semantic correctness
  6. 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.text is undefined
  • Don't use raw string concatenation for multi-turn - use proper contents array