Documentation

Encryption

Protect a PDF with a password and jasy encrypts it with AES-256 (V5/R6, the newest handler in the PDF spec). It runs on the platform's WebCrypto, so there are no native dependencies and no Java - the same code encrypts in Node and right in the browser.

Set a password

Pass an encrypt option to renderToBytes (or renderPdf). A userPassword is all you need - any viewer asks for it before it opens the document.

import { Document, Page, Text, renderToBytes } from "@jasy/pdf";

const doc = Document([Page([Text("Confidential")])]);

const bytes = await renderToBytes(doc, {
  encrypt: { userPassword: "secret" },
});

Owner password and permissions

Add an ownerPassword for full rights, and permissions to allow or deny actions. The owner password defaults to the user password when you leave it out, and every permission defaults to allowed.

const bytes = await renderToBytes(doc, {
  encrypt: {
    userPassword: "secret", // to open the document
    ownerPassword: "owner", // full rights
    permissions: {
      printing: false, // disallow printing
      copying: false, // disallow text/content extraction
      modifying: true,
      annotating: true,
    },
  },
});

Good to know

  • AES-256, R6. The current ISO 32000-2 handler - not the older revisions some libraries still ship.
  • Pure JS, isomorphic. WebCrypto under the hood: no native crypto, zero extra dependencies, identical in Node and the browser.
  • Vue and Nuxt too. In @jasy/vue pass it as the third argument - renderToPdf(Doc, props, { encrypt: { userPassword: "secret" } }). In @jasy/nuxt use renderOptions.
  • Not for PDF/A. PDF/A (and therefore ZUGFeRD / Factur-X invoices) forbids encryption, so encrypting one is rejected with a clear error.
jasypdf

Declarative PDFs in pure TypeScript. ZUGFeRD & XRechnung compliant, with no headless browser and no Java.

Resources

© 2026 Florian Heuberger · MIT License

Built with Nuxt · self-hosted fonts · no trackers