# Gemini JavaScript SDK gebruiken [[TOC]] ## Welke SDK gebruik je? Google biedt sinds Gemini 2.0 één unified SDK: `@google/genai`. Deze vervangt de oude `@google/generative-ai`, die sinds 30 november 2025 is uitgefaseerd en geen updates of bugfixes meer krijgt. Begin nieuwe projecten daarom altijd met `@google/genai`. Deze SDK werkt zowel met de Gemini Developer API (met API-sleutel) als met Vertex AI. :::warn title="Migreer oude code" Gebruik je nog `@google/generative-ai`? Dan blijft die voorlopig werken, maar krijgt geen beveiligingsupdates meer. Plan een migratie naar `@google/genai`: de import en de methodenamen wijzigen, maar de onderliggende concepten blijven gelijk. ::: ## Installatie ```bash npm install @google/genai ``` Voor een nieuw project: ```bash mkdir mijn-gemini-app cd mijn-gemini-app npm init -y npm install @google/genai dotenv ``` Voeg `"type": "module"` toe aan `package.json` voor de ES module import-syntax. ## Basis configuratie Je maakt één keer een client aan en hergebruikt die voor alle aanroepen. ```javascript import { GoogleGenAI } from "@google/genai"; import dotenv from "dotenv"; dotenv.config(); const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY }); ``` ## Tekstgeneratie Tekst genereer je via `ai.models.generateContent()`. Het resultaat lees je uit de `text`-property (geen functieaanroep). ```javascript const response = await ai.models.generateContent({ model: "gemini-3.5-flash", contents: "Geef een overzicht van de vijf meest gebruikte JavaScript frameworks.", config: { systemInstruction: "Je bent een behulpzame assistent die antwoord geeft in het Nederlands.", }, }); console.log(response.text); console.log("Prompt tokens:", response.usageMetadata.promptTokenCount); console.log("Output tokens:", response.usageMetadata.candidatesTokenCount); ``` :::tip title="Welk model kies je?" `gemini-3.5-flash` is medio 2026 een goede standaard voor de meeste taken: snel en betaalbaar. Heb je diepere redenering of complexe code-taken nodig, kies dan `gemini-2.5-pro`. Voor zeer hoog volume tegen lage kosten bestaat `gemini-2.5-flash-lite`. Controleer de actuele modellijst op ai.google.dev, want het aanbod verandert geregeld. ::: ## Generatieconfiguratie Alle generatie-instellingen geef je mee in het `config`-object. ```javascript const response = await ai.models.generateContent({ model: "gemini-3.5-flash", contents: "Schrijf een korte productbeschrijving.", config: { temperature: 0.8, topP: 0.95, topK: 40, maxOutputTokens: 2048, stopSequences: ["---EINDE---"], }, }); ``` ## Chatsessie opzetten Voor gesprekken met geheugen gebruik je `ai.chats.create()`. De sessie onthoudt de geschiedenis tussen aanroepen. ```javascript const chat = ai.chats.create({ model: "gemini-3.5-flash", history: [ { role: "user", parts: [{ text: "Hoi, ik wil leren programmeren in Python." }], }, { role: "model", parts: [{ text: "Geweldig! Python is een uitstekende eerste taal. Waar wil je mee beginnen?" }], }, ], }); const response1 = await chat.sendMessage({ message: "Leg variabelen uit." }); console.log(response1.text); const response2 = await chat.sendMessage({ message: "En functies?" }); console.log(response2.text); console.log("Geschiedenis:", chat.getHistory().length, "berichten"); ``` :::tip title="Geschiedenis bewaren" Met `chat.getHistory()` haal je de volledige gespreksgeschiedenis op. Sla die op in een database en herstel de sessie later met `ai.chats.create({ model, history: bewaardeGeschiedenis })`. ::: ## Streaming Met streaming toon je het antwoord woord voor woord, zodra het binnenkomt. Dat geeft een snellere gebruikerservaring. ```javascript const stream = await ai.models.generateContentStream({ model: "gemini-3.5-flash", contents: "Schrijf een uitleg van async/await in JavaScript met praktische voorbeelden.", }); for await (const chunk of stream) { process.stdout.write(chunk.text); } console.log(); ``` In een chatsessie stream je met `chat.sendMessageStream({ message: "..." })`, die je op dezelfde manier doorloopt. ## Afbeeldingen verwerken Multimodale invoer geef je mee als onderdelen in de `contents`-array. Een lokale afbeelding lees je in als base64. ```javascript import * as fs from "node:fs"; const base64Afbeelding = fs.readFileSync("diagram.png", { encoding: "base64" }); const response = await ai.models.generateContent({ model: "gemini-3.5-flash", contents: [ { inlineData: { mimeType: "image/png", data: base64Afbeelding, }, }, { text: "Beschrijf dit diagram en leg de architectuur uit." }, ], }); console.log(response.text); ``` Voor grotere of veel hergebruikte bestanden kun je beter de Files API gebruiken (`ai.files.upload()`), zodat je een bestand niet bij elke aanroep opnieuw verstuurt. ## Gebruik in de browser In de browser laad je de SDK via een bundler (Vite, webpack) of een import map. ```html ``` :::danger title="Nooit je API-sleutel in de browser" Plaats je API-sleutel nooit in client-side code in productie. Iedereen kan die uitlezen en op jouw rekening gebruiken. Zet een backend-proxy ertussen die de sleutel veilig bewaart, de aanroep namens de gebruiker doet en rate limiting per gebruiker afdwingt. ::: ## Foutafhandeling Vang fouten op en bouw een eenvoudige retry voor rate limits (HTTP 429). ```javascript async function veiligGenereren(prompt) { try { const response = await ai.models.generateContent({ model: "gemini-3.5-flash", contents: prompt, }); if (response.promptFeedback?.blockReason) { throw new Error(`Prompt geblokkeerd: ${response.promptFeedback.blockReason}`); } return response.text; } catch (error) { if (error.status === 429) { console.error("Rate limit bereikt, wacht even..."); await new Promise(resolve => setTimeout(resolve, 60000)); return veiligGenereren(prompt); } throw error; } } ``` :::warn title="Gebruik een verstandige retry-strategie" Een vaste wachttijd van 60 seconden is eenvoudig maar grof. Voor productie is exponentiële backoff met een maximum aantal pogingen beter, zodat je niet eindeloos blijft hangen bij een aanhoudende fout. ::: ## TypeScript-ondersteuning De SDK is volledig getypeerd. Importeer types voor betere ondersteuning in je editor. ```typescript import { GoogleGenAI, type GenerateContentConfig, } from "@google/genai"; const config: GenerateContentConfig = { temperature: 0.7, maxOutputTokens: 1024, }; const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY }); const response = await ai.models.generateContent({ model: "gemini-3.5-flash", contents: "Hallo", config, }); ``` :::faq ### Wat is het verschil tussen @google/generative-ai en @google/genai? `@google/genai` is de nieuwere unified SDK die zowel de Gemini Developer API als Vertex AI ondersteunt. De oude `@google/generative-ai` is sinds eind 2025 uitgefaseerd en krijgt geen updates meer. Gebruik voor elk nieuw project `@google/genai`. ### Hoe migreer ik bestaande code naar @google/genai? De belangrijkste wijzigingen: vervang `new GoogleGenerativeAI(key)` door `new GoogleGenAI({ apiKey: key })`, roep `ai.models.generateContent({ model, contents, config })` aan in plaats van eerst een model op te halen, en lees het antwoord uit de property `response.text` in plaats van `response.response.text()`. Chat gaat via `ai.chats.create()`. De officiele migratiegids op ai.google.dev beschrijft alle stappen. ### Werkt de SDK ook met Deno of Bun? Ja. Bun ondersteunt npm-packages native, dus daar werkt het direct. In Deno importeer je met het npm-prefix, bijvoorbeeld `import { GoogleGenAI } from "npm:@google/genai"`. ### Welk model kan ik het beste kiezen? Voor de meeste toepassingen is `gemini-3.5-flash` een goede balans tussen snelheid, kosten en kwaliteit. Voor complexe redenering of zware code-taken neem je `gemini-2.5-pro`. Controleer altijd de actuele modellijst, omdat Google het aanbod regelmatig vernieuwt. ### Hoe ga ik om met CORS bij directe browser-aanroepen? De Gemini Developer API ondersteunt CORS, dus technisch kan een aanroep vanuit de browser. Toch raden we een backend-proxy aan om je API-sleutel te beschermen en rate limiting per gebruiker af te dwingen. ### Kan ik de SDK gebruiken in Next.js Server Actions? Ja. Gebruik de SDK in Server Actions of API-routes, waar je sleutel veilig op de server blijft. Roep de SDK nooit aan vanuit client-side componenten. :::