
Security News
MCP Community Begins Work on Official MCP Metaregistry
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
chromiumly
Advanced tools
A lightweight Typescript library that interacts with Gotenberg's different modules to convert a variety of document formats to PDF files.
A lightweight Typescript library that interacts with Gotenberg's different routes to convert a variety of document formats to PDF files.
Using npm:
npm install chromiumly
Using yarn:
yarn add chromiumly
Before attempting to use Chromiumly, be sure you install Docker if you have not already done so.
After that, you can start a default Docker container of Gotenberg as follows:
docker run --rm -p 3000:3000 gotenberg/gotenberg:8
Chromiumly supports configurations via both dotenv and config configuration libraries or directly via code to add Gotenberg endpoint to your project.
GOTENBERG_ENDPOINT=http://localhost:3000
{
"gotenberg": {
"endpoint": "http://localhost:3000"
}
}
import { Chromiumly } from "chromiumly";
Chromiumly.configure({ endpoint: "http://localhost:3000" });
Gotenberg introduces basic authentication support starting from version 8.4.0. Suppose you are running a Docker container using the command below:
docker run --rm -p 3000:3000 \
-e GOTENBERG_API_BASIC_AUTH_USERNAME=user \
-e GOTENBERG_API_BASIC_AUTH_PASSWORD=pass \
gotenberg/gotenberg:8.4.0 gotenberg --api-enable-basic-auth
To integrate this setup with Chromiumly, you need to update your configuration as outlined below:
GOTENBERG_ENDPOINT=http://localhost:3000
GOTENBERG_API_BASIC_AUTH_USERNAME=user
GOTENBERG_API_BASIC_AUTH_PASSWORD=pass
Or
{
"gotenberg": {
"endpoint": "http://localhost:3000",
"api": {
"basicAuth": {
"username": "user",
"password": "pass"
}
}
}
}
Or
Chromiumly.configure({
endpoint: "http://localhost:3000",
username: "user",
password: "pass",
});
To implement advanced authentication or add custom HTTP headers to your requests, you can use the customHttpHeaders
option within the configure
method. This allows you to pass additional headers, such as authentication tokens or custom metadata, with each API call.
For example, you can include a Bearer token for authentication along with a custom header as follows:
const token = await generateToken();
Chromiumly.configure({
endpoint: "http://localhost:3000",
customHttpHeaders: {
Authorization: `Bearer ${token}`,
"X-Custom-Header": "value",
},
});
Chromiumly introduces different classes that serve as wrappers to
Gotenberg's routes. These classes encompass methods featuring an
input file parameter, such as html
, header
, footer
, and markdown
, capable of accepting inputs in the form of a
string
(i.e. file path), Buffer
, or ReadStream
.
There are three different classes that come with a single method (i.e.convert
) which calls one of
Chromium's Conversion routes to convert html
and markdown
files, or
a url
to a buffer
which contains the converted PDF file content.
Similarly, a new set of classes have been added to harness the recently introduced Gotenberg Screenshot routes. These classes include a single method called capture
, which allows capturing full-page screenshots of html
, markdown
, and url
.
import { UrlConverter } from "chromiumly";
const urlConverter = new UrlConverter();
const buffer = await urlConverter.convert({
url: "https://www.example.com/",
});
import { UrlScreenshot } from "chromiumly";
const screenshot = new UrlScreenshot();
const buffer = await screenshot.capture({
url: "https://www.example.com/",
});
The only requirement is that the file name should be index.html
.
import { HtmlConverter } from "chromiumly";
const htmlConverter = new HtmlConverter();
const buffer = await htmlConverter.convert({
html: "path/to/index.html",
});
import { HtmlScreenshot } from "chromiumly";
const screenshot = new HtmlScreenshot();
const buffer = await screenshot.capture({
html: "path/to/index.html",
});
This route accepts an index.html
file plus a markdown file.
import { MarkdownConverter } from "chromiumly";
const markdownConverter = new MarkdownConverter();
const buffer = await markdownConverter.convert({
html: "path/to/index.html",
markdown: "path/to/file.md",
});
import { MarkdownScreenshot } from "chromiumly";
const screenshot = new MarkdownScreenshot();
const buffer = await screenshot.capture({
html: "path/to/index.html",
markdown: "path/to/file.md",
});
Each convert()
method takes an optional properties
parameter of the following type which dictates how the PDF generated
file will look like.
type PageProperties = {
singlePage?: boolean; // Print the entire content in one single page (default false)
size?: {
width: number; // Paper width, in inches (default 8.5)
height: number; //Paper height, in inches (default 11)
};
margins?: {
top: number; // Top margin, in inches (default 0.39)
bottom: number; // Bottom margin, in inches (default 0.39)
left: number; // Left margin, in inches (default 0.39)
right: number; // Right margin, in inches (default 0.39)
};
preferCssPageSize?: boolean; // Define whether to prefer page size as defined by CSS (default false)
printBackground?: boolean; // Print the background graphics (default false)
omitBackground?: boolean; // Hide the default white background and allow generating PDFs with transparency (default false)
landscape?: boolean; // Set the paper orientation to landscape (default false)
scale?: number; // The scale of the page rendering (default 1.0)
nativePageRanges?: { from: number; to: number }; // Page ranges to print
};
In addition to the PageProperties
customization options, the convert()
method also accepts a set of parameters to further enhance the versatility of the conversion process. Here's an overview of the full list of parameters:
type ConversionOptions = {
properties?: PageProperties; // Customize the appearance of the generated PDF
pdfFormat?: PdfFormat; // Define the PDF format for the conversion
pdfUA?: boolean; // Enable PDF for Universal Access for optimal accessibility (default false)
userAgent?: string; // Customize the user agent string sent during conversion
header?: PathLikeOrReadStream; // Specify a custom header for the PDF
footer?: PathLikeOrReadStream; // Specify a custom footer for the PDF
emulatedMediaType?: EmulatedMediaType; // Specify the emulated media type for conversion
waitDelay?: string; // Duration (e.g., '5s') to wait when loading an HTML document before conversion
waitForExpression?: string; // JavaScript expression to wait before converting an HTML document into PDF
extraHttpHeaders?: Record<string, string>; // Include additional HTTP headers in the request
failOnHttpStatusCodes?: number[]; // List of HTTP status codes triggering a 409 Conflict response (default [499, 599])
failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
skipNetworkIdleEvent?: boolean; // Do not wait for Chromium network to be idle (default true)
metadata?: Metadata; // Metadata to be written.
cookies?: Cookie[]; // Cookies to be written.
downloadFrom?: DownloadFrom; //Download a file from a URL. It must return a Content-Disposition header with a filename parameter.
split?: SplitOptions; // Split the PDF file into multiple files.
};
Similarly, the capture()
method takes an optional properties
parameter of the specified type, influencing the appearance of the captured screenshot file.
type ImageProperties = {
format: "png" | "jpeg" | "webp"; //The image compression format, either "png", "jpeg" or "webp".
quality?: number; // The compression quality from range 0 to 100 (jpeg only).
omitBackground?: boolean; // Hide the default white background and allow generating screenshots with transparency.
width?: number; // The device screen width in pixels (default 800).
height?: number; // The device screen height in pixels (default 600).
clip?: boolean; // Define whether to clip the screenshot according to the device dimensions (default false).
};
Furthermore, alongside the customization options offered by ImageProperties
, the capture()
method accommodates a variety of parameters to expand the versatility of the screenshot process. Below is a comprehensive overview of all parameters available:
type ScreenshotOptions = {
properties?: ImageProperties;
header?: PathLikeOrReadStream;
footer?: PathLikeOrReadStream;
emulatedMediaType?: EmulatedMediaType;
waitDelay?: string; // Duration (e.g, '5s') to wait when loading an HTML document before convertion.
waitForExpression?: string; // JavaScript's expression to wait before converting an HTML document into PDF until it returns true.
extraHttpHeaders?: Record<string, string>;
failOnHttpStatusCodes?: number[]; // Return a 409 Conflict response if the HTTP status code is in the list (default [499,599])
failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
skipNetworkIdleEvent?: boolean; // Do not wait for Chromium network to be idle (default true)
optimizeForSpeed?: boolean; // Define whether to optimize image encoding for speed, not for resulting size.
cookies?: Cookie[]; // Cookies to be written.
downloadFrom?: DownloadFrom; // Download the file from a specific URL. It must return a Content-Disposition header with a filename parameter.
};
The LibreOffice
class comes with a single method convert
. This method interacts with LibreOffice route to convert different documents to PDF files. You can find the file extensions
accepted here.
import { LibreOffice } from "chromiumly";
const buffer = await LibreOffice.convert({
files: [
"path/to/file.docx",
"path/to/file.png",
{ data: xlsxFileBuffer, ext: "xlsx" },
],
});
Similarly to Chromium's route convert
method, this method takes the following optional parameters :
properties
: changes how the PDF generated file will look like. It also includes a password
parameter to open the source file.pdfa
: PDF format of the conversion resulting file (i.e. PDF/A-1a
, PDF/A-2b
, PDF/A-3b
).pdfUA
: enables PDF for Universal Access for optimal accessibility.merge
: merges all the resulting files from the conversion into an individual PDF file.metadata
: writes metadata to the generated PDF file.lolosslessImageCompression
: allows turning lossless compression on or off to tweak image conversion performance.reduceImageResolution
: allows turning on or off image resolution reduction to tweak image conversion performance.quality
: specifies the quality of the JPG export. The value ranges from 1 to 100, with higher values producing higher-quality images and larger file sizes.maxImageResolution
: specifies if all images will be reduced to the specified DPI value. Possible values are: 75
, 150
, 300
, 600
, and 1200
.flatten
: a boolean that, when set to true, flattens the split PDF files, making form fields and annotations uneditable.The PDFEngines
class interacts with Gotenberg's PDF Engines routes to manipulate PDF files.
This method interacts with PDF Engines convertion route to transform PDF files into the requested PDF/A format and/or PDF/UA.
import { PDFEngines } from "chromiumly";
const buffer = await PDFEngines.convert({
files: ["path/to/file_1.pdf", "path/to/file_2.pdf"],
pdfa: PdfFormat.A_2b,
pdfUA: true,
});
This method interacts with PDF Engines merge route which gathers different engines that can manipulate and merge PDF files such as: PDFtk, PDFcpu, QPDF, and UNO.
import { PDFEngines } from "chromiumly";
const buffer = await PDFEngines.merge({
files: ["path/to/file_1.pdf", "path/to/file_2.pdf"],
pdfa: PdfFormat.A_2b,
pdfUA: true,
});
This method reads metadata from the provided PDF files.
import { PDFEngines } from "chromiumly";
const metadataBuffer = await PDFEngines.readMetadata([
"path/to/file_1.pdf",
"path/to/file_2.pdf",
]);
This method writes metadata to the provided PDF files.
import { PDFEngines } from "chromiumly";
const buffer = await PDFEngines.writeMetadata({
files: [
"path/to/file_1.pdf",
"path/to/file_2.pdf",
],
metadata: {
Author: 'Taha Cherfia',
Tite: 'Chromiumly'
Keywords: ['pdf', 'html', 'gotenberg'],
}
});
Please consider referring to ExifTool for a comprehensive list of accessible metadata options.
It is just a generic complementary method that takes the buffer
returned by the convert
method, and a
chosen filename
to generate the PDF file.
Please note that all the PDF files can be found __generated__
folder in the root folder of your project.
Each Chromium and LibreOffice route has a split
parameter that allows splitting the PDF file into multiple files. The split
parameter is an object with the following properties:
mode
: the mode of the split. It can be pages
or intervals
.span
: the span of the split. It is a string that represents the range of pages to split.unify
: a boolean that allows unifying the split files. Only works when mode
is pages
.flatten
: a boolean that, when set to true, flattens the split PDF files, making form fields and annotations uneditable.import { UrlConverter } from "chromiumly";
const buffer = await UrlConverter.convert({
url: "https://www.example.com/",
split: {
mode: "pages",
span: "1-2",
unify: true,
},
});
On the other hand, PDFEngines' has a split
method that interacts with PDF Engines split route which splits PDF files into multiple files.
import { PDFEngines } from "chromiumly";
const buffer = await PDFEngines.split({
files: ["path/to/file_1.pdf", "path/to/file_2.pdf"],
options: {
mode: "pages",
span: "1-2",
unify: true,
},
});
⚠️ Note: Gotenberg does not currently validate the
span
value whenmode
is set topages
, as the validation depends on the chosen engine for the split feature. See PDF Engines module configuration for more details.
PDF flattening converts interactive elements like forms and annotations into a static PDF. This ensures the document looks the same everywhere and prevents further edits.
import { PDFEngines } from "chromiumly";
const buffer = await PDFEngines.flatten({
files: ["path/to/file_1.pdf", "path/to/file_2.pdf"],
});
The following is a short snippet of how to use the library.
import { PDFEngines, UrlConverter } from "chromiumly";
async function run() {
const urlConverter = new UrlConverter();
const buffer = await urlConverter.convert({
url: "https://gotenberg.dev/",
properties: {
singlePage: true,
size: {
width: 8.5,
height: 11,
},
},
emulatedMediaType: "screen",
failOnHttpStatusCodes: [404],
failOnConsoleExceptions: true,
skipNetworkIdleEvent: false,
optimizeForSpeed: true,
split: {
mode: "pages",
span: "1-2",
unify: true,
},
});
await PDFEngines.generate("gotenberg.pdf", buffer);
}
run();
<small>4.1.1 (2025-03-17)</small>
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
Generated by auto-changelog
.
#571
#569
6ae581a
a3e73ba
13 March 2025
#568
#567
#566
#565
#564
#563
#562
#561
#560
#558
#559
#556
#555
#554
#552
#551
#550
#549
#548
#547
#546
#545
#544
d607390
36d9767
e6272c1
30 January 2025
#543
#542
#541
#540
#539
#538
#536
#535
#534
#531
#533
#532
#530
#529
#528
ebc3976
f943fce
b6b34ba
9 January 2025
#525
#524
#523
#522
#521
#520
#519
#518
#517
#516
#515
17cda23
0240e0c
5f31747
12 December 2024
d9c53b4
b4bb45f
fa8261d
11 December 2024
#512
#514
#513
#511
#510
#509
#508
#507
#506
#504
#503
#502
#501
#500
#499
93faa76
18 November 2024
#498
#496
#497
#495
#486
#482
#473
#474
#470
97f2e6a
79d6350
9ab42d1
13 October 2024
#468
#469
#466
#467
#464
f35f9ce
5c6da67
fb26785
4 October 2024
a35ee78
818d3d2
bf13769
1 October 2024
9f5a53d
25ef1a0
0e40ece
24 September 2024
#456
7b83743
c83a457
dba3ff1
9 September 2024
#449
787b344
74e61de
f48822c
20 August 2024
#418
b2ab059
f1ab400
2d08de8
11 July 2024
38cecfb
b22e984
a2384e0
4 July 2024
#409
bb5e890
e95051e
88da5ae
28 June 2024
1b07f8d
d748559
43fe613
14 June 2024
13 June 2024
13 June 2024
250ec4c
ba32de9
e3b182e
6 June 2024
beec84a
ce7ceaf
177a705
3 June 2024
fdbde2c
5f45d20
c259187
29 May 2024
3af3135
187f5d7
db17a5f
27 April 2024
#370
3f739e4
95d13a0
2c7b230
12 April 2024
#369
b31672a
91e487d
43db77c
9 April 2024
a077110
15d93bc
a103ba6
8 April 2024
0adba11
439f7f9
94cbc0e
5 April 2024
f58fcbb
d59c1e5
e575c57
23 March 2024
4497f5d
48aef9c
e258783
6 March 2024
2f36ccc
d56e656
915a905
29 February 2024
#341
edc284d
fdbcbdb
f762d5d
19 February 2024
#320
#332
#329
#314
#294
e9a3552
6723226
12e0618
11 December 2023
daa7783
d345e4c
be9e0dc
10 December 2023
#287
#288
#289
211c6e1
1c45580
0ca55dd
5 December 2023
4 December 2023
3 December 2023
#276
#274
#275
8b6e401
87c51bc
ed4ca4b
30 November 2023
#272
c28463a
a5e8271
66ec31c
4 November 2023
#254
#225
#251
#252
#248
#247
#211
#215
#146
#186
#189
#185
#165
045396d
c874967
84323ac
7 July 2023
#147
845b1eb
b14781f
ce3aaab
30 April 2023
#144
#135
#121
#102
3e5566f
ecc4a81
be21076
1 February 2023
#65
f7cba87
d5775c1
c123594
21 September 2022
e667a7d
d390678
834c983
11 September 2022
#27
#33
#32
#31
#29
#28
#26
#25
#23
#22
#21
#20
#18
#19
#16
#17
#15
#13
#12
#11
#14
#2
#7
#8
#6
#5
60ecc86
9aaf2d1
6614cd0
2 April 2022
bd98092
2 April 2022
#3
#1
64c1879
f873152
35533e9
1 April 2022
9625072
1513c8e
b9b4397
28 March 2022
28 March 2022
c29bdf4
7894d88
bffa17b
28 March 2022
FAQs
A lightweight Typescript library that interacts with Gotenberg's different modules to convert a variety of document formats to PDF files.
The npm package chromiumly receives a total of 6,893 weekly downloads. As such, chromiumly popularity was classified as popular.
We found that chromiumly demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
Research
Security News
Socket uncovers an npm Trojan stealing crypto wallets and BullX credentials via obfuscated code and Telegram exfiltration.
Research
Security News
Malicious npm packages posing as developer tools target macOS Cursor IDE users, stealing credentials and modifying files to gain persistent backdoor access.