nano-ai-pdf
v1.0.5
Published
This package helps you summarize pdfs using Gemini nano on edge or on browser, making it compliant safe, faster and free
Maintainers
Readme
nano-ai-pdf
A TypeScript/JavaScript library that extracts text from PDF files and summarizes them using Chrome’s built‑in on-device Summarizer API (Gemini Nano).
Runs entirely in the browser on supported Chrome versions — no API keys, no servers.
Badges
✨ Features
- 📄 PDF Text Extraction using
react-pdftotext - 🤖 On-device AI Summarization — Chrome’s Summarizer API (Gemini Nano)
- ⏳ Streaming Support — get real-time summary updates
- 🛡️ Runs locally — private & secure
- 🚫 Rejects image-only PDFs
- 📊 Metrics — compression ratio, processing time
- 🖥️ TypeScript typings included
- 📥 Progress tracking — get model download % via functions or callback
📦 Installation
npm install nano-ai-pdf
# or
yarn add nano-ai-pdf⚙️ Prerequisites
- 🖥 Chrome 138+ (desktop)
- Enable flags:
chrome://flags/#prompt-api-for-gemini-nano→ Enabledchrome://flags/#optimization-guide-on-device-model→ Enabled BypassPerfRequirement
- OS: Windows 10/11, macOS 13+, Linux
- ≥ 22 GB disk space, ≥ 4 GB GPU VRAM
- Must be triggered with user gesture (
click,tap, etc.)
📚 API Reference & Examples
1️⃣ summarizePdf(file, options?)
Extracts text from a PDF and returns an AI-generated summary.
import { summarizePdf } from "nano-ai-pdf";
async function runSummarization(file) {
try {
const result = await summarizePdf(file, {
type: "key-points", // 'tldr' | 'headline' | 'teaser'
format: "markdown", // or 'plain-text'
length: "medium", // 'short' | 'long'
context: "Technical report",
});
console.log("Summary:", result.summary);
console.log("Compression:", result.compressionRatio + "%");
} catch (err) {
console.error("Error summarizing PDF:", err);
}
}Returns:
{
summary: string;
originalText: string;
originalLength: number;
summaryLength: number;
compressionRatio: number;
processingTime: number;
config: PdfSummarizerOptions;
}2️⃣ summarizePdfStreaming(file, options?)
Like summarizePdf but yields chunks of the summary as they arrive.
import { summarizePdfStreaming } from "nano-ai-pdf";
async function runStreaming(file) {
const result = await summarizePdfStreaming(file, {
type: "tldr",
format: "plain-text",
length: "medium",
});
let summaryText = "";
for await (const chunk of result.summaryStream) {
summaryText += chunk;
console.log("Chunk:", chunk);
}
console.log("Final summary:", summaryText);
}3️⃣ isSummarizerSupported()
Checks if Chrome’s Summarizer API exists.
import { isSummarizerSupported } from "nano-ai-pdf";
if (!isSummarizerSupported()) {
console.error("Chrome Summarizer API not supported in this browser.");
}4️⃣ checkModelAvailability()
Checks if the AI model is ready, needs download, or is unavailable.
import { checkModelAvailability } from "nano-ai-pdf";
(async () => {
const status = await checkModelAvailability();
console.log("Model status:", status);
})();Returns one of:
"available" | "downloadable" | "downloading" | "unavailable"
5️⃣ getDownloadProgress()
Returns the last known download % (0-100).
import { getDownloadProgress } from "nano-ai-pdf";
// Polling example
setInterval(() => {
console.log("Current download progress:", getDownloadProgress() + "%");
}, 500);6️⃣ onDownloadProgressUpdate(callback)
Registers a callback to receive real-time download updates.
import { onDownloadProgressUpdate } from "nano-ai-pdf";
onDownloadProgressUpdate((progress) => {
console.log("Progress update:", progress + "%");
});🚨 Error Handling
Functions throw PdfSummarizerError with a .code property.
| Code | Meaning |
| :--------------------------- | :------------------------------ |
| NO_FILE | No file provided |
| INVALID_FILE_TYPE | File is not PDF |
| FILE_TOO_LARGE | Exceeds allowed size |
| EMPTY_FILE | File has zero bytes |
| EXTRACTION_FAILED | Text extraction failed |
| INSUFFICIENT_TEXT | Not enough text content |
| API_NOT_SUPPORTED | API not available |
| USER_ACTIVATION_REQUIRED | Not called from a user gesture |
| MODEL_UNAVAILABLE | AI model unavailable |
| SUMMARIZER_CREATION_FAILED | Summarizer could not be created |
| SUMMARIZATION_FAILED | Summary generation failed |
🖥 Example Minimal React App
import { useState } from "react";
import {
summarizePdf,
isSummarizerSupported,
checkModelAvailability,
onDownloadProgressUpdate,
} from "nano-ai-pdf";
export default function App() {
const [summary, setSummary] = useState("");
const [progress, setProgress] = useState(0);
onDownloadProgressUpdate((p) => setProgress(p));
const handleClick = async (e) => {
e.preventDefault();
if (!isSummarizerSupported()) {
alert("Not supported in this browser!");
return;
}
const availability = await checkModelAvailability();
if (availability === "unavailable") {
alert("Model unavailable - check Chrome setup.");
return;
}
const file = document.getElementById("file").files[0];
if (!file) return alert("Pick a PDF first");
const result = await summarizePdf(file, { type: "tldr" });
setSummary(result.summary);
};
return (
<div>
<input id="file" type="file" accept="application/pdf" />
<button onClick={handleClick}>Summarize PDF</button>
<p>Download Progress: {progress}%</p>
<pre>{summary}</pre>
</div>
);
}