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

@imgly/pdfx-exporter

v0.1.0

Published

Export CE.SDK designs as print-ready PDF/X-1a, X-3 and X-4, with bleed; converts existing PDFs too.

Readme

@imgly/pdfx-exporter

Exports CE.SDK designs as print-ready PDF/X-1a:2003, PDF/X-3:2003 or PDF/X-4, with an embedded output intent (FOGRA39, GRACoL 2013, sRGB or your own ICC profile) and real bleed boxes. Runs in the browser and in Node.js.

It replaces @imgly/plugin-print-ready-pdfs-web 1.x (Ghostscript, AGPL); see Migrating.

import { exportPDFX } from '@imgly/pdfx-exporter';

// Engine → PDF/X in one call: every page of the scene, with bleed.
const printReady = await exportPDFX(cesdk.engine, { outputProfile: 'fogra39' });

Usage

convertToPDFX converts a PDF Blob you already have:

import { convertToPDFX } from '@imgly/pdfx-exporter';

const pdf = await engine.block.export(page, 'application/pdf');
const printReady = await convertToPDFX(pdf, {
  outputStandard: 'PDF/X-4', // or 'PDF/X-3', 'PDF/X-1a'
  outputProfile: 'fogra39', // 'gracol' | 'srgb' | 'custom'
  title: 'Spring campaign'
});

Pass an array of Blobs to convert several PDFs; the result is an array in the same order.

Options

| Option | Default | Notes | | --------------------------- | -------------- | -------------------------------------------------------------- | | outputStandard | 'PDF/X-4' | 'PDF/X-1a', 'PDF/X-3' or 'PDF/X-4'. | | outputProfile | — | Required. 'fogra39', 'gracol', 'srgb' or 'custom'. | | customProfile | — | ICC profile Blob; required when outputProfile is 'custom'. | | flattenTransparency | true for X-3 | PDF/X-1a always flattens; PDF/X-4 keeps live transparency. | | flattenResolution | 300 | Resolution in dpi for flattened pages. | | embedICCProfile | true | Embed the output profile in the output intent. | | title | 'Untitled' | Document title in Info and XMP metadata. | | outputCondition | per profile | Overrides the output intent's OutputCondition. | | outputConditionIdentifier | per profile | Overrides the output intent's OutputConditionIdentifier. | | nonPrinterProfile | 'keep' | 'keep' or 'reject'; see below. |

PDF/X-1a allows only CMYK and spot colours, so srgb is rejected for it.

srgb and other non-printer profiles are not PDF/X

PDF/X (ISO 15930) describes a printing condition, so its output intent must be a printer profile (ICC device class prtr). srgb is a display profile (mntr), and a custom profile may be a display, input or colour-space profile. Output with such a profile is never PDF/X compliant, for any standard: Acrobat Preflight reports "OutputIntent profile not 'prtr'" and checkPDFX reports 6.2.3 dest-profile-class. nonPrinterProfile decides what happens:

  • 'keep' (default, as in @imgly/plugin-print-ready-pdfs-web 1.x): the file is produced anyway. Use it where an RGB file with PDF/X structure (boxes, output intent, metadata) is good enough.
  • 'reject': conversion throws Output profile is not a printer profile (ICC device class "mntr"); PDF/X needs class "prtr" (with the profile's class) before any work is done (in exportPDFX, after the engine export).

With an RGB output intent, gray content colour is written as the equal RGB, so the only finding left is the profile class.

Exporting straight from the engine

exportPDFX takes the running CE.SDK engine instead of a PDF Blob: it exports the pages, or any other blocks, itself, with print-oriented export settings and bleed, and returns one PDF/X — engine to PDF/X in one call. Use convertToPDFX only for PDFs you already have.

import { exportPDFX } from '@imgly/pdfx-exporter';

// Every page of the current scene, as one multi-page PDF/X:
const printReady = await exportPDFX(cesdk.engine, {
  outputStandard: 'PDF/X-4',
  outputProfile: 'fogra39'
});

// Selected pages, in the order given:
const back = await exportPDFX(engine, {
  outputProfile: 'gracol',
  blocks: [pages[3], pages[0]]
});

// Any block — a group, an image, a text — as a page of its own, mixed with pages:
const sticker = await exportPDFX(engine, {
  outputProfile: 'fogra39',
  blocks: [logoGroup, pages[0]]
});

It works with the browser cesdk.engine, @cesdk/node and @cesdk/node-native (tested against @cesdk/node-native 1.83); the engine parameter is typed by the methods it calls (PDFXEngine), so the package has no CE.SDK dependency. It takes every convertToPDFX option, plus:

| Option | Default | Notes | | --------------- | ----------------------- | -------------------------------------------------------------------------------------------- | | blocks | every page of the scene | Block ids, one output page each, in this order. Pages get bleed (below); any other block (group, image, text, …) is exported at its own size, without bleed boxes. A scene or stack block stands for its pages. Blocks the engine cannot export fail with the engine's error. | | exportOptions | see below | Overrides the options passed to engine.block.export. | | title | block or scene name | One block: its name, else the scene's. Several blocks: the scene's name. Else 'Untitled'. |

Engine export options. Each block is exported with engine.block.export(block, { mimeType: 'application/pdf', … }) and:

| Engine option | exportPDFX sets | Why | | -------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | exportPdfWithHighCompatibility | true | The engine's own default, set explicitly so every engine build behaves the same. It is the output the converter is validated against (corpus, legacy suite). Bitmaps and gradients are rasterised at the scene's scene/dpi (300 by default). false keeps source images and vector gradients — also passes every standard, but a sample page with a photo grew about 3× as PDF/X-4. | | exportPdfWithDeviceCMYK | true for a CMYK output intent | CMYK and spot colours set in the scene reach the PDF as CMYK instead of a round trip through RGB. false for srgb (and RGB custom profiles): the converter does not map DeviceCMYK into an RGB intent, so PDF/X-4 with srgb would fail. Custom profiles are detected from the ICC header. | | exportPdfWithUnderlayer | not set (off) | An underlayer is a white-ink layer for special printers, not part of a regular PDF/X job; turn it on through exportOptions. | | printer's marks (1.83+) | not set | exportPdfWithCropMarks / exportPdfWithRegistrationMarks pass every standard with CMYK intents (the marks' All colorant fails 6.10 with srgb). They grow the MediaBox around the page, so combined with bleed exportPDFX throws instead of writing wrong boxes. | | others | not set | pdfImageQuality, allowTextOverhang, abortSignal, onProgress, … keep the engine defaults; pass them in exportOptions. |

Overriding exportPdfWithDeviceCMYK: true with outputProfile: 'srgb' produces a PDF/X-4 that checkPDFX rejects (rule 6.10).

Bleed. CE.SDK keeps a page's bleed in page/marginEnabled and page/margin/{top,bottom,left,right} (design units), and engine.block.export (1.83) includes those margins for a page in a VerticalStack or HorizontalStack scene but exports the page area alone in a Free or DepthStack scene. For a page with bleed enabled and any margin above 0, exportPDFX exports a hidden copy of the page, enlarged by the margins, with its own margins turned off and its content shifted by the left/top margins, so whatever reaches into the bleed is printed, once, in every scene layout. The output page then has MediaBox = BleedBox = page + bleed and TrimBox = the page. The engine snaps the page size to whole device pixels at scene/dpi, so the TrimBox can be off by a device pixel or two (at most 0.5 pt at 300 dpi). Pages without bleed, and blocks other than pages, get TrimBox = MediaBox.

The copy lives only while it is exported: it is made invisible (it never shows in an editor, but engine.scene.getPages() lists it for the duration of the export) and destroyed in a finally, children first (destroying a page leaves its children's fills and shapes behind in CE.SDK 1.82 and 1.83). The scene is left as it was, whether or not the export succeeds. exportPDFX does not touch undo histories: the copy is added and removed between two undo steps, so it nets out of the next one, but an undo step the host app records while an export runs would contain it. (A scratch history was tried and dropped: in @cesdk/node-native 1.83, once the active history has been switched, an export discards pending changes.) Overlapping exportPDFX calls on the same engine object run one after the other. Limits: the copy's direct children are placed with absolute positions and sizes taken from their current frames, and a page's own fill (e.g. a background image fill on the page itself) is stretched across the bleed by the engine.

Each page is exported separately and the pages are merged before conversion, so fonts used on several pages are embedded once per page (about 7% larger than a single scene export in a six-page text test).

Checking conformance

import { checkPDFX } from '@imgly/pdfx-exporter';

const violations = await checkPDFX(printReady, 'PDF/X-4');
// [] when the file conforms; otherwise { rule, message, object } per finding

Loading

The engine is a WebAssembly module in wasm/, loaded on first use: fetched next to the package's own files in the browser (serve dist/ and wasm/ as siblings), read from disk in Node.js. It needs Node.js 22+ or a current browser with WebAssembly SIMD (Chrome, Firefox, Edge, Safari 16.4+).

Logging

import { Logger } from '@imgly/pdfx-exporter';

Logger.setLogLevel('info'); // 'debug' | 'info' | 'warn' (default) | 'error'
Logger.getLogs(); // most recent 1000 entries
Logger.clearLogs();

Migrating from @imgly/plugin-print-ready-pdfs-web 1.x

  • Uninstall @imgly/plugin-print-ready-pdfs-web, install this package and change the import specifiers; the API is unchanged: convertToPDFX, the deprecated convertToPDFX3 (defaults to PDF/X-3), Logger and the validation error messages behave as in 1.82 and 1.83.
  • New: outputStandard: 'PDF/X-1a', flattenResolution, nonPrinterProfile, checkPDFX and exportPDFX (pages with bleed, or any block).
  • srgb output is converted as before but is not PDF/X compliant (it never was: sRGB is not a printer profile); checkPDFX says so. Pass nonPrinterProfile: 'reject' to refuse it.
  • Removed: ghostscriptArgs. The converter no longer uses Ghostscript, so passing a non-empty ghostscriptArgs throws ghostscriptArgs is not supported: this build does not use Ghostscript.
  • Not supported: the signal, timeoutMs, maxOutputBytes and runtime options added in 1.84. TypeScript rejects them; plain JavaScript ignores them.
  • The engine uses WebAssembly SIMD, so it needs Safari 16.4+ (CE.SDK itself supports Safari 15.6+); see Loading.
  • The package no longer contains AGPL-licensed code. The ICC profile licences ship in ICC-PROFILE-LICENSES.md.

The @imgly/plugin-print-ready-pdfs-web 2.0.0-beta.1–4 tarballs from this repository's GitHub releases were earlier builds of this package: 0.1.0 replaces 2.0.0-beta.4 despite the lower version number. Migrate the same way: uninstall the -web tarball, install this one and change the import specifiers.

License

See LICENSE.md. This software is based in part on the work of the Independent JPEG Group.