The @google/genai SDK introduces lightweight model aliases (`gemini-2.5-flash`, `gemini-1.5-pro`) and native responseSchema enforcement. However, embedding API keys directly into client JavaScript poses a high security risk. Here is how to construct a robust Express + Node server proxy.
Security Imperative
Never expose process.env.GEMINI_API_KEY in Vite client builds. Always route requests through a secure server endpoint (/api/ai/generate) to protect credentials and enforce rate limits.
Streaming chunks directly from Gemini to the React frontend eliminates perceived latency for long multi-paragraph responses:
1400 font-semibold">import { Router } 400 font-semibold">from 400 font-semibold">class="text-emerald-300">"express";2400 font-semibold">import { GoogleGenAI } 400 font-semibold">from 400 font-semibold">class="text-emerald-300">"@google/genai";34400 font-semibold">const router = 300 font-medium">Router();5400 font-semibold">const ai = 400 font-semibold">new 300 font-medium">GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });67router.300 font-medium">post(400 font-semibold">class="text-emerald-300">"/api/ai/stream", 400 font-semibold">async (req, res) => {8 400 font-semibold">const { prompt } = req.body;910 res.300 font-medium">setHeader(400 font-semibold">class="text-emerald-300">"Content-Type", 400 font-semibold">class="text-emerald-300">"text/event-stream");11 res.300 font-medium">setHeader(400 font-semibold">class="text-emerald-300">"Cache-Control", 400 font-semibold">class="text-emerald-300">"no-cache");12 res.300 font-medium">setHeader(400 font-semibold">class="text-emerald-300">"Connection", 400 font-semibold">class="text-emerald-300">"keep-alive");1314 400 font-semibold">try {15 400 font-semibold">const responseStream = 400 font-semibold">await ai.models.300 font-medium">generateContentStream({16 model: 400 font-semibold">class="text-emerald-300">"gemini-2.5-flash",17 contents: prompt,18 });1920 400 font-semibold">for 400 font-semibold">await (400 font-semibold">const chunk of responseStream) {21 400 font-semibold">if (chunk.text) {22 res.300 font-medium">write(`data: ${JSON.300 font-medium">stringify({ text: chunk.text })}2324`);25 }26 }27 res.300 font-medium">write("data: [DONE]2829");30 res.300 font-medium">end();31 } 400 font-semibold">catch (error: 300 font-medium">any) {32 res.300 font-medium">status(500).300 font-medium">json({ error: error.message });33 }34});Gemini can trigger function calls based on user prompts. Here is how to register tools for live data retrieval:
1400 font-semibold">const weatherTool = {2 name: 400 font-semibold">class="text-emerald-300">"getWeather",3 description: 400 font-semibold">class="text-emerald-300">"Get real-time weather metrics 400 font-semibold">for a target city",4 parameters: {5 400 font-semibold">type: 400 font-semibold">class="text-emerald-300">"OBJECT",6 properties: {7 city: { 400 font-semibold">type: 400 font-semibold">class="text-emerald-300">"STRING", description: 400 font-semibold">class="text-emerald-300">"City name e.g. San Francisco" },8 },9 required: [400 font-semibold">class="text-emerald-300">"city"],10 },11};1213400 font-semibold">const response = 400 font-semibold">await ai.models.300 font-medium">generateContent({14 model: 400 font-semibold">class="text-emerald-300">"gemini-2.5-flash",15 contents: 400 font-semibold">class="text-emerald-300">"What is the current temperature in Seattle?",16 config: {17 tools: [{ functionDeclarations: [weatherTool] }],18 },19});Building Resumetrix: Architecting an ATS Resume Parser & AI Engine with Gemini 1.5 Pro & WebAssembly
A deep dive into how I built Resumetrix—an AI career toolkit that parses complex PDFs in-browser via WebAssembly, computes semantic embedding matches, and stream-optimizes resumes for Applicant Tracking Systems.
Final-Year CS Student & Full-Stack / AI Developer
React Performance Optimization: Profiling, Rerender Elimination, & Virtualization
Practical techniques to fix laggy React web apps: avoiding primitive useEffect dependency traps, using useSyncExternalStore, virtualizing large lists, and profile-guided tuning.
Final-Year CS Student & Full-Stack / AI Developer
