@google/genai review
A single generateContent call in @google/genai 2.30.0 can continue across follow-up requests when the model returns a continuation token. Google's JavaScript and TypeScript SDK connects applications to Gemini Developer API and Gemini Enterprise Agent Platform, with generation, streaming, tools and conversation APIs. Choose it when you want those Google-specific controls and can own the surrounding request lifecycle. Python developers need the separate [google-genai client](https://mrkeyoor.com/libs/google-genai/).
@google/genai 2.30.0 gives a Node 20+ service direct Gemini access with automatic continuation that can span follow-up requests. Choose it when you can explicitly manage endpoint selection and tool execution, then validate a bounded request on your own configured service before adopting the examples.
Answers from our run
@google/genai or ai: which should you use?
ai: Choose ai when you want a single model interface spanning Google and other providers, through Vercel AI Gateway or direct provider connections. @google/genai 2.30.0 gives a Node 20+ service direct Gemini access with automatic continuation that can span follow-up requests.
When should you not use @google/genai?
Your runtime is below Node.js 20. The published 2.30.0 package requires Node 20 or later, and its README announces Node 22 as the floor for 3.0.0.
Use it if
- Your Node service calls Gemini directly and needs Google's generateContent and streaming interfaces rather than a common interface across model vendors.
- You need to choose explicitly between an AI Studio API key and a Google Cloud project with application-default credentials.
- Long generations need an explicit continuation policy. Version 2.30.0 exposes automaticContinuation so your application can decide whether the SDK follows continuation tokens.
- You want to keep tool execution under application control: declare a function, inspect the returned call and decide whether to run it.
- Your runtime is below Node.js 20. The published 2.30.0 package requires Node 20 or later, and its README announces Node 22 as the floor for 3.0.0.
- Production would embed a reusable API key in browser JavaScript. Google explicitly advises server-side implementations to avoid exposing keys.
- You need a common interface across model providers. This guide's ai alternative serves that requirement more directly than adopting Google-specific request shapes.
- You require stable endpoints without configuration. The SDK defaults to beta APIs, so package pinning alone does not select the stable API surface.
- You cannot budget time for the next major migration. The 2.30.0 README warns that automatic function calling will move from direct Models calls to Chats in 3.0, alongside removed fields and the Node runtime change.
Setup reality
We did not install @google/genai or execute requests against Google for this guide. The examples are documentation-based illustrations checked against the 2.30.0 README and model implementation, not a compatibility or performance test. Version 2.30.0 requires Node.js 20 or later. Start with npm install @google/genai@2.30.0 in an isolated project. Use an ES module for the snippets below; request examples assume the ai and model variables from the Developer API setup, unless they show a replacement client.
Choose the service before configuring authentication. Developer API examples pass an AI Studio key explicitly from process.env.GEMINI_API_KEY. For production, keep that code on the server. Enterprise setup needs a Google Cloud project, billing, the Vertex AI API and authentication; the README uses gcloud auth application-default login for local credentials. The SDK defaults to beta endpoints; set apiVersion to 'v1' to select the stable API. Check that your chosen feature exists on that endpoint.
Automatic continuation is enabled by default. When a response carries the continuation finish reason and token, the SDK can request the next part and merge responses. That means the duration and service usage of a logical call can extend beyond its first response. Set config.automaticContinuation to false when your application needs to handle that boundary itself. This switch controls continuation, not every possible retry or tool call. Plain function declarations still require your code to execute the selected function and return its result.
Conversation state also has different homes. The README describes ai.chats as local stateful objects, while Interactions continues server-side state through previous_interaction_id. Decide which lifecycle you need before mixing examples. The model alias gemini-flash-latest below follows the versioned README; these snippets do not establish its availability for your account or region. Before upgrading to 3.0, review the published migration warning about automatic function calling, removed Live fields and the higher Node requirement.
Patterns
Set up a server-side Developer API client developer-api-client
import { GoogleGenAI } from '@google/genai';
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) throw new Error('Set GEMINI_API_KEY on the server');
const ai = new GoogleGenAI({ apiKey });
const model = 'gemini-flash-latest';This reads the key explicitly and passes it as apiKey, matching the 2.30.0 quickstart. It is server code. The browser constructor has a similar shape, but Google warns against exposing API keys in client code.
Select the enterprise service and stable endpoint enterprise-stable-client
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({
enterprise: true,
project: 'your-project-id',
location: 'your-location',
apiVersion: 'v1',
});
const model = 'gemini-flash-latest';This replaces the Developer API setup. Configure billing, the Vertex AI API and authentication first. Setting v1 chooses the stable endpoint; it does not make every preview feature available there.
Read a generated text response generate-text
const response = await ai.models.generateContent({
model,
contents: 'Explain why a database migration needs a rollback plan.',
});
console.log(response.text ?? 'No text returned');The quickstart reads response.text as a property. The fallback handles a missing text value in this illustration; it does not prove that a request succeeded or explain why text was absent. Continuation is enabled by default.
Await the stream, then iterate its chunks stream-text
const stream = await ai.models.generateContentStream({
model,
contents: 'Write a short checklist for reviewing a database migration.',
});
for await (const chunk of stream) {
if (chunk.text) process.stdout.write(chunk.text);
}Version 2.30.0 documents an awaited generateContentStream call followed by for await iteration. Streaming also participates in automatic continuation. Chunks arriving at your process are not evidence that your web server forwards them promptly to a browser.
Send conversation turns with explicit roles explicit-conversation-history
const response = await ai.models.generateContent({
model,
contents: [
{ role: 'user', parts: [{ text: 'Our maintenance window is Sunday.' }] },
{ role: 'model', parts: [{ text: 'The window is Sunday.' }] },
{ role: 'user', parts: [{ text: 'Which day is the window?' }] },
],
});
console.log(response.text);The README says Content[] passes through without transformation. A flat list of strings becomes one user Content instead, so it is the wrong representation for separate speakers. The model turn here is illustrative history, not output recorded from an earlier request.
Inspect a proposed function call before execution declare-function-tool
import { FunctionCallingConfigMode } from '@google/genai';
const response = await ai.models.generateContent({
model,
contents: 'Look up the status of order SAMPLE-001.',
config: {
tools: [{ functionDeclarations: [{
name: 'lookupOrder',
description: 'Read an order status by its identifier.',
parametersJsonSchema: {
type: 'object',
properties: { orderId: { type: 'string' } },
required: ['orderId'],
},
}] }],
toolConfig: { functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY,
allowedFunctionNames: ['lookupOrder'],
} },
},
});
console.log(response.functionCalls);This stops at inspection and performs no order lookup. The README's manual flow requires your application to execute the function and send a FunctionResponse with history. Validate the proposed arguments and the caller's access before connecting it to a real order service.
Keep continuation under application control disable-automatic-continuation
const response = await ai.models.generateContent({
model,
contents: 'Write a detailed migration checklist.',
config: { automaticContinuation: false },
});
console.log(response.text);Without callable tools, setting config.automaticContinuation to false takes the direct generateContentInternal path instead of the continuation loop. This example supplies no tools. It disables this automatic follow-up mechanism, not every transport retry, and may leave a generation unfinished. Inspect the full response before treating the text as complete.
Keep error status alongside the message inspect-api-errors
try {
const response = await ai.models.generateContent({
model,
contents: 'Return a short greeting.',
});
console.log(response.text);
} catch (error) {
console.error({
name: error?.name,
status: error?.status,
message: error?.message,
});
throw error;
}The 2.30.0 README's API error example reads name, message and status. Other errors may lack a status. This illustration rethrows after logging and adds no application retry loop; decide retry behavior from the failure and your own request budget.
Continue an Interaction by its previous identifier continue-server-side-interaction
const first = await ai.interactions.create({
model,
input: 'The project codename is Cedar.',
});
const second = await ai.interactions.create({
model,
input: 'What is the project codename?',
previous_interaction_id: first.id,
});
console.log(second);The README documents previous_interaction_id for server-side conversation state. This is the Interactions API, with input rather than generateContent's contents. Check service and model availability before adopting it; the local ai.chats objects described elsewhere are a different state-management choice.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| ai | npm | Choose ai when you want a single model interface spanning Google and other providers, through Vercel AI Gateway or direct provider connections. |
| @langchain/google-genai | npm | Choose @langchain/google-genai when the application already uses LangChain.js and needs its Google Generative AI integration. |
More ai / ml guides
openai · mcp · huggingface-hub · scikit-learn · tiktoken · tokenizers · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.