Every panel in Dastavej — compress, convert, forms, OCR, watermark — is backed by a plain async function that takes and returns Uint8Array bytes, with zero dependency on React or Dastavej's UI. That whole layer lives in lib/ and is re-exported from a single entry point, lib/publicApi.ts, so you can pull it into your own app.
No AI included. AI-powered features (topic → PDF generation, AI form fill) are deliberately left out of this API while we build a local, on-device AI story — see the AI tab in the app for status.
Option A — copy the source (simplest, works anywhere)
Copy the lib/ and workers/ folders from the repository into your project and import from ./lib/publicApi. No build-step surprises since it's just TypeScript you compile with your own toolchain.
Option B — git dependency
npm install github:prabhassaas/dastavej
Then import { compressPdf } from 'dastavej'. This package ships TypeScript source (not precompiled JS) via its exports field — works out of the box with bundlers that transpile dependencies (Vite, esbuild-based setups); with Next.js/webpack you may need to add it to transpilePackages. A precompiled npm package is on the roadmap.
Some functions need a Web Worker file
compressPdf loads workers/compress.worker.ts via new URL(..., import.meta.url) — make sure your bundler supports that pattern (Next.js, Vite and webpack 5 all do) and that the file is included wherever you copy lib/ to.
Merge PDFs
import { mergePdfs } from 'dastavej';
const merged = await mergePdfs([bytesA, bytesB, bytesC]);Compress
import { compressPdf } from 'dastavej';
const { bytes, imagesRecompressed } = await compressPdf(pdfBytes, {
quality: 0.6,
maxDimension: 1600,
onProgress: (done, total) => console.log(`${done}/${total}`),
});Build a fillable form
import { buildFormPdf, FORM_TEMPLATES } from 'dastavej';
const template = FORM_TEMPLATES.find((t) => t.id === 'job-application')!;
const pdf = await buildFormPdf({
title: template.title,
fields: template.fields.map((f) => ({ ...f, id: crypto.randomUUID() })),
pageSize: 'A4',
orientation: 'portrait',
photoBox: template.photoBox,
});Convert to Word
import { openForConversion, convertToWord } from 'dastavej';
const doc = await openForConversion(pdfBytes);
const docxBytes = await convertToWord(doc, (p) => console.log(p));Collect filled forms into Excel
import { extractFormData, exportRowsToXlsx } from 'dastavej';
const rows = await Promise.all(
files.map((f) => f.arrayBuffer().then((buf) => extractFormData(f.name, new Uint8Array(buf)))),
);
await exportRowsToXlsx(rows, 'responses.xlsx');OCR a scanned PDF
import { ocrPdfBytes } from 'dastavej';
const results = await ocrPdfBytes(pdfBytes, (p) => console.log(p.phase, p.progress), {
enhance: true, // grayscale + auto-threshold for faded scans
});
console.log(results.map((r) => r.text).join('\n\n'));| Function | Module | What it does |
|---|---|---|
| mergePdfs(files) | lib/pdfOps.ts | Merge PDF byte arrays, in order, into one document. |
| reorderPages(bytes, order) | lib/pdfOps.ts | Rebuild a PDF with a new page order/subset and per-page rotation. |
| extractPage(bytes, index) | lib/pdfOps.ts | Pull one page out as its own standalone PDF. |
| splitPdfByRanges(bytes, ranges) | lib/pdfOps.ts | Split a PDF into multiple PDFs by 0-based [start, end] page ranges. |
| splitPdfEveryNPages(bytes, n) | lib/pdfOps.ts | Split a PDF into fixed-size chunks of N pages each. |
| parsePageRanges(spec, totalPages) | lib/pdfOps.ts | Parse a human range spec like "1-3, 5, 8-9" into 0-based ranges. |
| compressPdf(bytes, opts) | lib/compress.ts | Downsample & re-encode embedded JPEGs in a Web Worker. |
| assemblePdf(sources, pages, edits, extras) | lib/export.ts | Build a document from sources + apply text edits, annotations, watermark/header/footer. |
| printPdf(bytes) | lib/print.ts | Open the browser print dialog with a date/time-stamped copy. |
| imagesToPdf(images, options) | lib/imageToPdf.ts | Combine PNG/JPEG images into a new PDF, one per page, with page size/orientation/fit options. |
| pdfToImages(bytes, options) | lib/pdfToImages.ts | Render every page of a PDF to a PNG/JPEG image. |
| flattenFormPdf(bytes) | lib/flatten.ts | Burn AcroForm field values permanently into the page content. |
| openForConversion(bytes) | lib/convert.ts | Parse bytes into a pdf.js document for the convert* functions. |
| convertToWord(doc, onProgress) | lib/convert.ts | PDF → .docx (paragraphs, page breaks, heading sizes); OCRs scanned pages automatically. |
| convertToExcel(doc, onProgress) | lib/convert.ts | PDF → .xlsx — infers real table columns from text position, all pages in one sheet. |
| convertToCsv(doc, onProgress) | lib/convert.ts | Same table extraction as convertToExcel, written as plain-text CSV. |
| convertToPowerPoint(doc, onProgress) | lib/convert.ts | PDF → .pptx (each page as a full-bleed slide image). |
| buildWordFromPages(pages) | lib/convert.ts | Build a .docx straight from an array of extracted/OCR'd page text strings. |
| buildFormPdf(options) | lib/formBuilder.ts | Generate a fillable AcroForm PDF from a field spec, with logo/photo box. |
| FORM_TEMPLATES | lib/formTemplates.ts | 10 ready-made professional form field sets. |
| extractFormData(name, bytes) | lib/formData.ts | Read AcroForm field values out of a filled PDF. |
| exportRowsToXlsx(rows) | lib/formData.ts | Write form responses to a real .xlsx (SheetJS). |
| exportRowsToCsv(rows) | lib/formData.ts | Write form responses to a plain CSV file. |
| ocrPdfBytes(bytes, onProgress, opts) | lib/ocr.ts | Run Tesseract.js OCR over a PDF's pages, fully client-side. |
| ocrImages(images, onProgress, opts) | lib/ocr.ts | Run OCR over standalone image files (photos/screenshots), no PDF needed. |
| createOcrEngine(onProgress) | lib/ocr.ts | Low-level: spin up one tesseract.js worker to reuse across multiple recognize() calls. |
| buildPdfFromMarkdown(title, markdown) | lib/mdPdf.ts | Render Markdown into a clean, styled PDF report. |
| createZip(entries) | lib/zip.ts | Zero-dependency ZIP writer for bundling multiple output files. |
RAG over this exact reference and the examples above — answers quote real function signatures instead of a paraphrase from memory, and stay correct as the API evolves.
Uses whatever AI provider is configured in the app's AI tab (shared browser storage) — needs a provider with an embeddings endpoint, e.g. Ollama with ollama pull nomic-embed-text.