npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@k.nirmal/gemini-kit

v1.0.1

Published

Unofficial Node.js wrapper for Google Gemini — interact via cookies. Supports ask, speech, image upload, image extraction, sharing, and continuous conversations.

Readme

Gemini-Kit (Node.js)

npm version License: MIT Node.js >=18

Gemini-Kit is an unofficial Node.js wrapper for Google Gemini, developed through reverse-engineering.
It uses your browser cookie values to communicate with Google Gemini — no official API key required.

⚠️ For testing / educational purposes only. Reverse-engineering Google services may violate their Terms of Service.


✨ Features

| Feature | Description | |---|---| | 💬 Single & Multi-turn Chat | Ask questions and maintain conversation context | | 🖼️ Image Fetching | Extract inline image URLs returned by Gemini | | 🎨 Generated Image Extraction | Save AI-generated images from responses | | 📸 Image Upload | Upload images and ask questions about them | | 🔊 Text-to-Speech | Convert any Gemini response to audio bytes | | 🔗 Share Conversations | Generate shareable conversation links | | 🍪 Cookie Parsing | Parse cookies from Chrome net-export log files |


📦 Installation

npm install @k.nirmal/gemini-kit

🍪 Get Cookie File (chrome-net-export-log)

For a detailed video guide, click here.

1. Close All Tabs

Ensure all tabs are closed in Google Chrome.

2. Access Network Export

  • Open a new tab and navigate to chrome://net-export/.

3. Configure Logging Settings

  • Check the box labelled "Include cookies and credentials".
  • Set the Maximum log size to 1 MB.
  • Click "Start logging".

4. Perform Actions

  • Open a new tab and go to gemini.google.com.
  • Log in to your Gemini account.
  • Send a sample message and wait for Gemini's response.

5. Stop Logging

  • Return to the logging tab and click "Stop logging".

6. Save the JSON File

  • The cookies will be saved in a JSON file (e.g. chrome-net-export-log.json).

7. Extract Cookies in Node.js

const { getCookiesFromFile } = require('geminikit');
const fs = require('fs');

const raw = fs.readFileSync('chrome-net-export-log.json', 'utf8');
const cookies = getCookiesFromFile(raw);
console.log(cookies);

🚀 Quick Start

const { createGemini, getCookiesFromFile } = require('geminikit');
const fs = require('fs');

(async () => {
  const cookies = getCookiesFromFile(fs.readFileSync('chrome-net-export-log.json', 'utf8'));
  const gemini = await createGemini(cookies);

  const res = await gemini.ask('Hello! Who are you?');
  console.log(res.text);
})();

📖 API Reference

createGemini(cookies)Promise<Gemini>

Factory helper. Creates and initialises a Gemini client in one call.

const gemini = await createGemini(cookies);

new Gemini(cookies)

Construct a client manually. Call await gemini.ready() before using any methods.

const { Gemini } = require('geminikit');
const gemini = new Gemini(cookies);
await gemini.ready();

getCookiesFromFile(text)Object

Parse cookies from the raw text content of a Chrome net-export-log JSON file.

const { getCookiesFromFile } = require('geminikit');
const cookies = getCookiesFromFile(fs.readFileSync('chrome-net-export-log.json', 'utf8'));

gemini.ask(text, [opts])Promise<Object>

Send a message and get a structured response.

Parameters:

| Name | Type | Description | |---|---|---| | text | string | The message to send | | opts.user | Object | Previous response (for conversation continuity) | | opts.photo | [name, url] | Photo array for vision questions |

Returns:

{
  text: string,               // Gemini's response text
  conversation_id: string,    // Conversation ID (pass back in opts.user)
  response_id: string,
  choice_id: string,
  req_id: number,
  fsid: string,
  bott: string,
  SNlM0e: string,
  image_urls: string[],           // Inline image URLs in the response
  generated_image_urls: string[]  // AI-generated image URLs
}

Example — Single message:

const res = await gemini.ask('Tell me a joke');
console.log(res.text);

Example — Continuous conversation:

const res1 = await gemini.ask('Tell me a joke');
console.log(res1.text);

const res2 = await gemini.ask('Another one!', { user: res1 });
console.log(res2.text);

Example — Ask with a photo:

const fs = require('fs');
const imgBytes = fs.readFileSync('cat.jpg');
const imgUrl = await gemini.uploadImage(imgBytes);

const res = await gemini.ask('What is in this photo?', {
  photo: ['cat.jpg', imgUrl]
});
console.log(res.text);

gemini.share(conversationId, responseId, choiceId, reqId, fsid, [opts])Promise<string>

Generate a shareable URL for a conversation.

Parameters:

| Name | Type | Description | |---|---|---| | conversationId | string | From response object | | responseId | string | From response object | | choiceId | string | From response object | | reqId | number | From response object | | fsid | string | From response object | | opts.title | string | Custom share title (optional) |

Example:

const res = await gemini.ask('Hi!');
const url = await gemini.share(
  res.conversation_id,
  res.response_id,
  res.choice_id,
  res.req_id,
  res.fsid,
  { title: 'My Gemini Chat' }
);
console.log(url); // https://gemini.google.com/share/...

gemini.speech(text, [opts])Promise<Buffer>

Convert text to speech and return raw audio bytes (WAV format).

Parameters:

| Name | Type | Default | Description | |---|---|---|---| | text | string | — | Text to convert | | opts.langCode | string | "en-GB" | BCP-47 language code |

Example:

const fs = require('fs');

const audio = await gemini.speech('Hello, world!');
fs.writeFileSync('output.wav', audio);

With a different language:

const audio = await gemini.speech('Bonjour!', { langCode: 'fr-FR' });
fs.writeFileSync('output.wav', audio);

gemini.uploadImage(imageBuffer)Promise<string>

Upload an image buffer to Google's servers and get a URL back.
Use the returned URL with gemini.ask() via the photo option.

Example:

const fs = require('fs');
const imgBytes = fs.readFileSync('photo.jpg');
const url = await gemini.uploadImage(imgBytes);
console.log('Uploaded to:', url);

gemini.getImgBytes(url)Promise<Buffer>

Download raw image bytes from a URL using the authenticated session.
Useful for saving image_urls or generated_image_urls from ask().

Example:

const res = await gemini.ask('Show me some wallpapers');
console.log(res.text);

for (const url of res.image_urls) {
  const bytes = await gemini.getImgBytes(url);
  const name = url.split('/').pop();
  require('fs').writeFileSync(name, bytes);
}

gemini.refreshCookies()Promise<[string, string]>

Re-fetch SNlM0e and bott tokens from the Gemini homepage.
Called automatically on construction. Useful if your session expires.

await gemini.refreshCookies();

gemini.getCookies()Object

Return the cookies currently in use.

const cookies = gemini.getCookies();

💡 Full Examples

Save All Response Images

const { createGemini, getCookiesFromFile } = require('geminikit');
const fs = require('fs');

(async () => {
  const cookies = getCookiesFromFile(fs.readFileSync('chrome-net-export-log.json', 'utf8'));
  const gemini = await createGemini(cookies);

  const res = await gemini.ask('Send me some nature wallpapers');
  console.log(res.text);

  for (const url of res.image_urls) {
    const name = url.split('/').pop();
    const bytes = await gemini.getImgBytes(url);
    fs.writeFileSync(name, bytes);
    console.log('Saved:', name);
  }
})();

Save AI-Generated Images

(async () => {
  const res = await gemini.ask('Generate an image of a cat holding a rose.');
  console.log(res.text);

  for (const url of res.generated_image_urls) {
    const name = url.split('/').pop().slice(0, 10) + '.png';
    const bytes = await gemini.getImgBytes(url);
    fs.writeFileSync(name, bytes);
    console.log('Saved generated image:', name);
  }
})();

Text-to-Speech to File

(async () => {
  const audio = await gemini.speech('Welcome to GeminiKit!');
  fs.writeFileSync('welcome.wav', audio);
  console.log('Audio saved to welcome.wav');
})();

🔢 Response Object Fields

| Field | Type | Description | |---|---|---| | text | string | Gemini's text reply | | conversation_id | string | Continue the conversation | | response_id | string | ID of this response | | choice_id | string | Selected response variant ID | | req_id | number | Request ID | | fsid | string | File session ID | | bott | string | Internal Gemini version token | | SNlM0e | string | CSRF/session token | | image_urls | string[] | Inline image URLs from response | | generated_image_urls | string[] | AI-generated image URLs |


📁 Project Structure

geminikit/
├── index.js          # Package entry point
├── src/
│   ├── gemini.js     # Gemini class (all API methods)
│   ├── headers.js    # HTTP headers
│   └── helpers.js    # Cookie parsing & utilities
├── package.json
├── README.md
└── LICENSE

🤝 Contributing

Pull requests are welcome! Please open an issue first to discuss what you would like to change.


📄 License

MIT — © Nirmal Gmage