2024.06.12
A Node.js Wrapper for the Gemini API.
Building a clean abstraction over Google's Gemini API before the official SDK existed.
GeminiNode.jsLLMAPI
Before Google released the official @google/generative-ai Node SDK, I built a lightweight wrapper for a news aggregation project. The core insight: Gemini's REST API is clean enough that you don't need much abstraction.
Minimal wrapper
const BASE = 'https://generativelanguage.googleapis.com/v1beta';
async function generate(prompt, { model = 'gemini-pro', temp = 0.7 } = {}) {
const res = await fetch(
`${BASE}/models/${model}:generateContent?key=${process.env.GEMINI_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
contents: [{ parts: [{ text: prompt }] }],
generationConfig: { temperature: temp },
}),
}
);
const data = await res.json();
return data.candidates?.[0]?.content?.parts?.[0]?.text ?? null;
}What I used it for
- Summarizing Nepali and English news articles into 3-sentence briefs
- Tagging articles by topic (Politics, Tech, Sports) for the aggregator
- Generating search-optimized titles from raw article text
- Detecting near-duplicate stories across sources
Rate limiting and retries
async function generateWithRetry(prompt, retries = 3) {
for (let i = 0; i < retries; i++) {
try { return await generate(prompt); }
catch (err) {
if (err.status === 429) await sleep(1000 * 2 ** i);
else throw err;
}
}
}The official SDK is now the right call for new projects. But rolling your own for a week taught me the shape of the API better than any documentation would have. Worth doing once.
↳ Always stream for long outputs — buffering 2000-token responses adds visible latency.