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

@noto-pdf-ts/core

v0.1.0-alpha.2

Published

PDF conversion library for Node.js - Core package without embedded fonts

Readme

@noto-pdf-ts/core

Documentation | API Reference

日本語版 README

A simple and efficient PDF conversion library for Node.js. Convert PDF pages to images (JPEG/PNG).

Features

  • Simple API - Initialize with NotoPdf.init() and convert PDFs with openPdf()
  • Memory efficient - Process one page at a time using AsyncGenerator
  • Japanese/CJK font support - Use separate font packages for CJK support
  • Full TypeScript support - Includes type definitions
  • ESM / CommonJS compatible
  • await using syntax support (ES2024 AsyncDisposable)

Installation

Note: This package is currently in alpha. The API may change in future releases.

# Install the core library
npm install @noto-pdf-ts/core@alpha

# With Japanese font support
npm install @noto-pdf-ts/core@alpha @noto-pdf-ts/fonts-jp@alpha

Peer Dependencies

This library requires sharp as a peer dependency for image processing:

npm install sharp

Note: sharp uses pre-built binaries for most platforms, so no native compilation is typically required.

Usage

Basic Usage

import { NotoPdf } from '@noto-pdf-ts/core'
import loadFontJp from '@noto-pdf-ts/fonts-jp'
import fs from 'node:fs/promises'

// Initialize with fonts
const notoPdf = await NotoPdf.init({ fonts: [await loadFontJp()] })

// Open a PDF
const pdf = await notoPdf.openPdf('/path/to/document.pdf')
console.log(`Page count: ${pdf.pageCount}`)

// Convert all pages to images
for await (const page of pdf.renderPages({ format: 'jpeg', scale: 1.5 })) {
  console.log(`Converting page ${page.pageNumber}/${page.totalPages}...`)
  await fs.writeFile(`page-${page.pageNumber}.jpg`, page.buffer)
}

// Clean up
await pdf.close()
notoPdf.destroy()

await using Syntax (ES2024)

import { NotoPdf } from '@noto-pdf-ts/core'
import loadFontJp from '@noto-pdf-ts/fonts-jp'

// Both NotoPdf and PdfDocument support await using
await using notoPdf = await NotoPdf.init({ fonts: [await loadFontJp()] })
await using pdf = await notoPdf.openPdf('/path/to/document.pdf')

for await (const page of pdf.renderPages()) {
  // ...
}
// Automatically closed when scope ends

Processing Multiple PDFs

import { NotoPdf } from '@noto-pdf-ts/core'
import loadFontJp from '@noto-pdf-ts/fonts-jp'

const notoPdf = await NotoPdf.init({ fonts: [await loadFontJp()] })

for (const file of pdfFiles) {
  const pdf = await notoPdf.openPdf(file)
  for await (const page of pdf.renderPages()) {
    await fs.writeFile(`${file}-${page.pageNumber}.jpg`, page.buffer)
  }
  await pdf.close()
}

notoPdf.destroy()

Various Input Formats

import { NotoPdf } from '@noto-pdf-ts/core'

const notoPdf = await NotoPdf.init()

// File path
const pdf1 = await notoPdf.openPdf('/path/to/document.pdf')

// Buffer
const buffer = await fs.readFile('/path/to/document.pdf')
const pdf2 = await notoPdf.openPdf(buffer)

// Uint8Array
const response = await fetch('https://example.com/document.pdf')
const data = new Uint8Array(await response.arrayBuffer())
const pdf3 = await notoPdf.openPdf(data)

// Password-protected PDF
const pdf4 = await notoPdf.openPdf('/path/to/encrypted.pdf', { password: 'secret' })

Converting Specific Pages

// Convert a single page
const page = await pdf.renderPage(1)

// Specify page numbers
for await (const page of pdf.renderPages({ pages: [1, 3, 5] })) {
  // Converts only pages 1, 3, 5
}

// Specify page range
for await (const page of pdf.renderPages({ pages: { start: 2, end: 4 } })) {
  // Converts pages 2-4
}

Rendering Options

const options = {
  scale: 2.0,      // Scale factor (default: 1.5)
  format: 'png',   // 'jpeg' or 'png' (default: 'jpeg')
  quality: 0.9,    // JPEG quality 0-1 (default: 0.85)
}

for await (const page of pdf.renderPages(options)) {
  // ...
}

API

NotoPdf

The main entry point for PDF operations.

import { NotoPdf } from '@noto-pdf-ts/core'
import loadFontJp from '@noto-pdf-ts/fonts-jp'

// Initialize with fonts
const notoPdf = await NotoPdf.init({ fonts: [await loadFontJp()] })

// Or initialize without fonts (for PDFs with embedded fonts)
const notoPdf = await NotoPdf.init()

// Register fonts later if needed
notoPdf.registerFonts([await loadFontKr()])

// Open a PDF
const pdf = await notoPdf.openPdf('/path/to/document.pdf')

// Clean up when done
notoPdf.destroy()

NotoPdf.init(options?)

Creates a new NotoPdf instance.

  • options.fonts?: FontConfig[] - Fonts to register during initialization

notoPdf.openPdf(input, options?)

Opens a PDF document.

  • input: string | Buffer | Uint8Array | ArrayBuffer - File path or binary data
  • options.password?: string - Password for encrypted PDFs

PdfDocument

interface PdfDocument {
  readonly pageCount: number
  renderPages(options?: RenderOptions): AsyncGenerator<RenderedPage>
  renderPage(pageNumber: number, options?): Promise<RenderedPage>
  close(): Promise<void>
  [Symbol.asyncDispose](): Promise<void>
}

RenderedPage

interface RenderedPage {
  pageNumber: number      // Page number (1-based)
  totalPages: number      // Total number of pages
  buffer: Buffer          // Image data
  width: number           // Width in pixels
  height: number          // Height in pixels
}

Error Handling

import { NotoPdf, PdfError } from '@noto-pdf-ts/core'

const notoPdf = await NotoPdf.init()

try {
  const pdf = await notoPdf.openPdf('/path/to/document.pdf')
} catch (error) {
  if (error instanceof PdfError) {
    switch (error.code) {
      case 'FILE_NOT_FOUND':
        console.error('File not found')
        break
      case 'INVALID_PDF':
        console.error('Invalid PDF file')
        break
      case 'PASSWORD_REQUIRED':
        console.error('Password required')
        break
      case 'INVALID_PASSWORD':
        console.error('Invalid password')
        break
      default:
        console.error(error.message)
    }
  }
}

Requirements

  • Node.js >= 20.0.0
  • sharp (peer dependency)

License

MIT