Google Gen AI JavaScript SDK for building applications powered by Gemini with content generation, image/video generation, function calling, caching, and real-time live sessions
The Files module provides file upload and management capabilities for use in generation requests (Gemini API only). Files can be images, videos, audio, or documents.
Upload a file to use in generation requests.
/**
* Upload file asynchronously
* @param params - File upload parameters
* @returns Promise resolving to uploaded file
*/
function upload(
params: UploadFileParameters
): Promise<File>;
interface UploadFileParameters {
/** File path (Node.js) or Blob object (browser) */
file: string | Blob;
/** MIME type (auto-detected from extension if not provided) */
mimeType?: string;
/** Display name for the file */
displayName?: string;
}
interface File {
/** File name (unique identifier) */
name?: string;
/** Display name */
displayName?: string;
/** MIME type */
mimeType?: string;
/** File size in bytes */
sizeBytes?: string;
/** Creation timestamp */
createTime?: string;
/** Last update timestamp */
updateTime?: string;
/** Expiration timestamp */
expirationTime?: string;
/** SHA-256 hash */
sha256Hash?: string;
/** File URI for use in generation */
uri?: string;
/** Processing state */
state?: FileState;
/** Error if processing failed */
error?: Status;
/** Video metadata (if applicable) */
videoMetadata?: VideoMetadata;
}Usage Examples:
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({ apiKey: 'YOUR_API_KEY' });
// Upload image file (Node.js)
const imageFile = await client.files.upload({
file: './photo.jpg',
mimeType: 'image/jpeg',
displayName: 'My Photo'
});
console.log('File uploaded:', imageFile.name);
console.log('File URI:', imageFile.uri);
// Wait for processing if needed
while (imageFile.state === FileState.PROCESSING) {
await new Promise(resolve => setTimeout(resolve, 1000));
const updated = await client.files.get({ file: imageFile.name! });
if (updated.state === FileState.ACTIVE) {
console.log('File ready');
break;
}
}
// Use in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Describe this image' },
{ fileData: {
fileUri: imageFile.uri!,
mimeType: 'image/jpeg'
}}
]
});
// Upload video
const videoFile = await client.files.upload({
file: './video.mp4',
mimeType: 'video/mp4'
});
console.log('Video metadata:', videoFile.videoMetadata);List uploaded files with pagination.
/**
* List uploaded files
* @param params - List parameters
* @returns Promise resolving to pager of files
*/
function list(
params?: ListFilesParameters
): Promise<Pager<File>>;
interface ListFilesParameters {
/** Page size */
pageSize?: number;
/** Page token for pagination */
pageToken?: string;
}Usage Examples:
// List all files
const pager = await client.files.list({
pageSize: 10
});
for await (const file of pager) {
console.log(`File: ${file.displayName}`);
console.log(` Name: ${file.name}`);
console.log(` MIME: ${file.mimeType}`);
console.log(` Size: ${file.sizeBytes} bytes`);
console.log(` State: ${file.state}`);
console.log(` Expires: ${file.expirationTime}`);
}
// Manual pagination
const page1 = await client.files.list({ pageSize: 5 });
console.log('First page:', page1.page);
if (page1.hasNextPage()) {
const page2 = await page1.nextPage();
console.log('Second page:', page2);
}Get file information by name.
/**
* Get file by name
* @param params - Get parameters
* @returns Promise resolving to file
*/
function get(
params: GetFileParameters
): Promise<File>;
interface GetFileParameters {
/** File name */
file: string;
}Usage Examples:
// Get file details
const file = await client.files.get({
file: 'files/abc123'
});
console.log('File:', file);
console.log('State:', file.state);
console.log('URI:', file.uri);Download a file (Node.js only).
/**
* Download file (Node.js only)
* @param params - Download parameters
* @returns Promise resolving when download completes
*/
function download(
params: DownloadFileParameters
): Promise<void>;
interface DownloadFileParameters {
/** File to download */
file: DownloadableFileUnion;
/** Destination path */
path: string;
}
/** File reference types that can be downloaded */
type DownloadableFileUnion = string | File | GeneratedVideo | Video;Usage Examples:
// Download by file object
const file = await client.files.upload({
file: './source.pdf',
mimeType: 'application/pdf'
});
await client.files.download({
file: file,
path: './downloaded.pdf'
});
// Download by file name
await client.files.download({
file: 'files/abc123',
path: './document.pdf'
});
// Download generated video
const videoOp = await client.models.generateVideos({
model: 'veo-2.0-generate-001',
prompt: 'A sunset'
});
// Wait for completion
const completed = await pollOperation(videoOp.name!);
if (completed.response?.generatedVideos?.[0]) {
await client.files.download({
file: completed.response.generatedVideos[0],
path: './generated.mp4'
});
}Delete an uploaded file.
/**
* Delete file
* @param params - Delete parameters
* @returns Promise resolving to deletion response
*/
function delete(
params: DeleteFileParameters
): Promise<DeleteFileResponse>;
interface DeleteFileParameters {
/** File name */
file: string;
}
interface DeleteFileResponse {
/** Empty response on success */
}Usage Examples:
// Delete file
await client.files.delete({
file: 'files/abc123'
});
console.log('File deleted');File processing states.
enum FileState {
STATE_UNSPECIFIED = 'STATE_UNSPECIFIED',
PROCESSING = 'PROCESSING',
ACTIVE = 'ACTIVE',
FAILED = 'FAILED'
}Video-specific metadata.
interface VideoMetadata {
/** Video duration (e.g., '3.5s', '1m30s') */
videoDuration?: string;
}Error information if processing failed.
interface Status {
/** Error code */
code?: number;
/** Error message */
message?: string;
/** Additional error details */
details?: unknown[];
}import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({ apiKey: 'YOUR_API_KEY' });
// Upload image
const imageFile = await client.files.upload({
file: './product.jpg',
mimeType: 'image/jpeg',
displayName: 'Product Image'
});
console.log('Uploaded:', imageFile.name);
// Use in multiple generations
const descriptions = await Promise.all([
client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Describe this product' },
{ fileData: { fileUri: imageFile.uri!, mimeType: 'image/jpeg' }}
]
}),
client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'List features of this product' },
{ fileData: { fileUri: imageFile.uri!, mimeType: 'image/jpeg' }}
]
}),
client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Suggest marketing copy for this product' },
{ fileData: { fileUri: imageFile.uri!, mimeType: 'image/jpeg' }}
]
})
]);
console.log('Description:', descriptions[0].text);
console.log('Features:', descriptions[1].text);
console.log('Marketing:', descriptions[2].text);// Upload video
const videoFile = await client.files.upload({
file: './video.mp4',
mimeType: 'video/mp4',
displayName: 'Demo Video'
});
console.log('Video uploaded:', videoFile.name);
console.log('Initial state:', videoFile.state);
// Poll until video is processed
let processedFile = videoFile;
while (processedFile.state === FileState.PROCESSING) {
console.log('Processing video...');
await new Promise(resolve => setTimeout(resolve, 5000));
processedFile = await client.files.get({
file: videoFile.name!
});
}
if (processedFile.state === FileState.ACTIVE) {
console.log('Video ready');
console.log('Duration:', processedFile.videoMetadata?.videoDuration);
// Use in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Summarize what happens in this video' },
{ fileData: {
fileUri: processedFile.uri!,
mimeType: 'video/mp4'
}}
]
});
console.log('Summary:', response.text);
} else if (processedFile.state === FileState.FAILED) {
console.error('Video processing failed:', processedFile.error);
}const filePaths = ['./doc1.pdf', './doc2.pdf', './doc3.pdf'];
// Upload all files in parallel
const files = await Promise.all(
filePaths.map((path, index) =>
client.files.upload({
file: path,
mimeType: 'application/pdf',
displayName: `Document ${index + 1}`
})
)
);
console.log(`Uploaded ${files.length} files`);
// Use all in single generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Analyze these documents and find common themes' },
...files.map(file => ({
fileData: {
fileUri: file.uri!,
mimeType: 'application/pdf'
}
}))
]
});
console.log('Analysis:', response.text);// List all files
const files = await client.files.list();
const now = new Date();
for await (const file of files) {
console.log(`\nFile: ${file.displayName || file.name}`);
console.log(` Size: ${file.sizeBytes} bytes`);
console.log(` Created: ${file.createTime}`);
console.log(` Expires: ${file.expirationTime}`);
// Delete files expiring soon
if (file.expirationTime) {
const expiresAt = new Date(file.expirationTime);
const hoursUntilExpiry = (expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60);
if (hoursUntilExpiry < 1) {
console.log(' Deleting (expiring soon)...');
await client.files.delete({ file: file.name! });
}
}
}// In browser environment
import { GoogleGenAI } from '@google/genai/web';
const client = new GoogleGenAI({ apiKey: 'YOUR_API_KEY' });
// Handle file input
document.getElementById('fileInput')?.addEventListener('change', async (e) => {
const input = e.target as HTMLInputElement;
const file = input.files?.[0];
if (file) {
// Upload blob
const uploadedFile = await client.files.upload({
file: file,
mimeType: file.type,
displayName: file.name
});
console.log('Uploaded:', uploadedFile.name);
// Use in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Describe this file' },
{ fileData: {
fileUri: uploadedFile.uri!,
mimeType: file.type
}}
]
});
document.getElementById('result')!.textContent = response.text || '';
}
});try {
const file = await client.files.upload({
file: './large-video.mp4',
mimeType: 'video/mp4'
});
console.log('Upload successful:', file.name);
// Check for processing errors
let processed = file;
let attempts = 0;
const maxAttempts = 60; // 5 minutes with 5s intervals
while (processed.state === FileState.PROCESSING && attempts < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, 5000));
processed = await client.files.get({ file: file.name! });
attempts++;
}
if (processed.state === FileState.FAILED) {
console.error('File processing failed:', processed.error);
} else if (attempts >= maxAttempts) {
console.error('Processing timeout');
} else {
console.log('File ready:', processed.uri);
}
} catch (error) {
console.error('Upload failed:', error);
}// Generate image
const imageResponse = await client.models.generateImages({
model: 'imagen-3.0-generate-002',
prompt: 'A beautiful sunset'
});
const imageData = imageResponse.generatedImages?.[0]?.image?.data;
if (imageData) {
// Save base64 image (Node.js)
const buffer = Buffer.from(imageData, 'base64');
require('fs').writeFileSync('./generated-sunset.png', buffer);
console.log('Image saved');
}
// Download video from operation
const videoOp = await client.models.generateVideos({
model: 'veo-2.0-generate-001',
prompt: 'Ocean waves'
});
// Poll until complete
const completed = await pollVideoOperation(client, videoOp.name!);
if (completed.response?.generatedVideos?.[0]?.video) {
// Download using files module
await client.files.download({
file: completed.response.generatedVideos[0].video,
path: './generated-ocean.mp4'
});
console.log('Video downloaded');
}// Upload audio file
const audioFile = await client.files.upload({
file: './speech.mp3',
mimeType: 'audio/mpeg',
displayName: 'Speech Recording'
});
// Wait for processing
while (audioFile.state === FileState.PROCESSING) {
await new Promise(resolve => setTimeout(resolve, 2000));
const updated = await client.files.get({ file: audioFile.name! });
if (updated.state === FileState.ACTIVE) {
break;
}
}
// Transcribe and analyze
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Transcribe this audio and summarize the key points' },
{ fileData: {
fileUri: audioFile.uri!,
mimeType: 'audio/mpeg'
}}
]
});
console.log('Transcription:', response.text);// Upload document
const docFile = await client.files.upload({
file: './report.pdf',
mimeType: 'application/pdf',
displayName: 'Annual Report'
});
console.log('Document uploaded:', docFile.name);
// Extract information
const extraction = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Extract key financial figures from this report' },
{ fileData: {
fileUri: docFile.uri!,
mimeType: 'application/pdf'
}}
]
});
console.log('Extracted data:', extraction.text);
// Generate summary
const summary = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: [
{ text: 'Provide a 3-paragraph summary of this report' },
{ fileData: {
fileUri: docFile.uri!,
mimeType: 'application/pdf'
}}
]
});
console.log('Summary:', summary.text);// Upload with awareness of expiration (48 hours default)
const file = await client.files.upload({
file: './temp-data.json',
mimeType: 'application/json'
});
console.log('File expires at:', file.expirationTime);
// Calculate time until expiration
const expiresAt = new Date(file.expirationTime!);
const now = new Date();
const hoursUntilExpiry = (expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60);
console.log(`File will expire in ${hoursUntilExpiry.toFixed(1)} hours`);
// If you need the file longer, re-upload before expiration
if (hoursUntilExpiry < 2) {
console.log('File expiring soon, re-uploading...');
const newFile = await client.files.upload({
file: './temp-data.json',
mimeType: 'application/json'
});
console.log('New file:', newFile.name);
}Install with Tessl CLI
npx tessl i tessl/npm-google--genai