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

n8n-nodes-pdf-text

v1.0.1

Published

n8n community node to insert text at X/Y positions into existing PDFs using pdf-lib

Readme

n8n-nodes-pdf-text

An n8n community node that inserts text at precise X/Y positions into existing PDF files using pdf-lib.

Perfect for stamping values onto pre-made form templates — invoices, expense forms, certificates, contracts — without rebuilding the document.

Features

  • Takes a PDF as binary input from any upstream node (configurable binary property, default data).
  • Add multiple text fields — each with its own text, position, size, font and color.
  • Text supports n8n expressions, so you can map values from previous nodes.
  • Choose the target page (or apply to all pages).
  • Outputs the modified PDF as binary (configurable property, default data).

Installation

Community Nodes (recommended)

  1. In your n8n instance go to Settings → Community Nodes.

  2. Click Install.

  3. Enter the package name / GitHub URL:

    https://github.com/x88a9/pdflib-custom-node
  4. Agree to the risks and click Install.

After installation the PDF Text node is available in the node panel.

n8n must be configured to allow installing community nodes (N8N_COMMUNITY_PACKAGES_ENABLED=true, which is the default).

Manual / self-hosted

cd ~/.n8n/nodes        # or your custom nodes folder
npm install https://github.com/x88a9/pdflib-custom-node

Then restart n8n.

Node configuration

| Field | Description | | --- | --- | | Input Binary Property | Name of the binary property on the incoming item holding the source PDF (default data). | | Text Fields | One or more text entries to draw (see below). | | Page Number | 1-based page to draw on. Use 0 to apply text to all pages. | | Output Binary Property | Name of the binary property to write the result to (default data). | | Output File Name | File name for the resulting PDF. .pdf is appended automatically if omitted (so invoice and invoice.pdf both produce invoice.pdf). If left empty, the input file name is reused with an _edited suffix (e.g. report.pdf → report_edited.pdf). |

The output item contains only the generated PDF — the original input file is not carried through.

Each Text Field has:

| Property | Description | | --- | --- | | Text | The text to insert (supports expressions). | | X (pt from left) | Horizontal position in points from the left edge. | | Y (pt from bottom) | Vertical position in points from the bottom edge. | | Font Size | Font size in points. | | Font | Helvetica, Helvetica Bold, Times Roman, or Courier. | | Color | Hex color string, e.g. #000000. |

Coordinate system

pdf-lib uses a coordinate system where the origin (0, 0) is the bottom-left corner of the page. This is the opposite of most screen/image coordinate systems where (0, 0) is the top-left.

 (0, height) ┌───────────────┐ (width, height)
             │               │
             │   Y increases │
             │      ↑        │
             │               │
      (0, 0) └───────────────┘ (width, 0)
              X increases →
  • X grows to the right.
  • Y grows upward — a larger Y moves the text higher on the page.

Common page sizes (in points, 1 pt = 1/72 inch):

| Size | Width | Height | | --- | --- | --- | | A4 | 595 | 842 | | Letter | 612 | 792 |

So to place text near the top of an A4 page, use a large Y value (e.g. Y ≈ 800); near the bottom, use a small Y (e.g. Y ≈ 40).

Example: German expense form (Spesenformular)

Suppose you have an A4 template (595 × 842 pt) with labels printed on it and you want to fill in the values next to each label. Approximate coordinates:

| Feld | Text (example) | X | Y | Font Size | Font | | --- | --- | --- | --- | --- | --- | | Beantrager | {{$json.name}} | 180 | 760 | 11 | Helvetica | | Datum | {{$json.datum}} | 180 | 730 | 11 | Helvetica | | Betrag | {{$json.betrag}} € | 180 | 700 | 11 | Helvetica-Bold | | Anzahl | {{$json.anzahl}} | 180 | 670 | 11 | Helvetica | | Verwendungszweck | {{$json.zweck}} | 180 | 640 | 11 | Helvetica |

Remember: because Y is measured from the bottom, the first row (Y = 760) sits near the top of the page and each subsequent row steps down by 30 pt.

Tip: the exact X/Y values depend on your template. Start with rough values, run the workflow, open the output PDF, and nudge the numbers until the text lands where you want it.

Development

npm install
npm run build      # compiles TypeScript to dist/ and copies assets

The compiled output in dist/ is committed to the repository so the package can be installed directly from GitHub without a build step.

License

MIT