Convert PDF documents to HTML from server-side Node.js code using the PDFCrowd client. Conversions run on PDFCrowd's servers.
This guide uses SDK 7 or later, supported on Node.js 18 and later. Install the client with npm, or see other installation options.
npm install pdfcrowd
See upgrading to SDK 7 when updating an existing installation.
You can run the examples below with the displayed API credentials. Update the input URLs and filenames as needed.
Examples use ES modules. For CommonJS, replace the import
statements with require() and place awaited operations inside an
async function.
const pdfcrowd = require('pdfcrowd');
The package includes TypeScript declarations. TypeScript infers conversion results and callback parameters from the SDK types. Use a namespace import:
import * as pdfcrowd from 'pdfcrowd';
For TypeScript compiled as CommonJS, you can also use:
import pdfcrowd = require('pdfcrowd');
When compiling a default import to CommonJS, enable esModuleInterop.
If your project needs Node.js types, see TypeScript dependency setup.
Convert a PDF URL to HTML and save it locally as invoice.html:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); const filePath = await client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.html" ); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.html", (error, filePath) => { if (error) { // Handle the error in your application. console.error(error.toString()); return; } console.log("Saved:", filePath); } ); } catch (error) { // Handle the error in your application. console.error(String(error)); }
The URL must return a PDF and be reachable from PDFCrowd's servers.
The output file is ready after await completes successfully,
or when the file callback runs without an error.
Handle failures as shown in Handle Errors.
Convert logo.pdf to HTML and save it locally as logo.html:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); const filePath = await client.convertFileToFile("logo.pdf", "logo.html"); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); client.convertFileToFile("logo.pdf", "logo.html", (error, filePath) => { if (error) { // Handle the error in your application. console.error(error.toString()); return; } console.log("Saved:", filePath); }); } catch (error) { // Handle the error in your application. console.error(String(error)); }
Pass your PDFCrowd username and API key to
PdfToHtmlClient.
Find your credentials on the API Keys page.
Send a PDF URL, upload a local file, or pass PDF bytes or a readable binary stream.
| Input | Method |
|---|---|
| URL | convertUrlToFile() |
| Local file | convertFileToFile() |
| Bytes in memory | convertRawDataToFile() |
| Readable binary stream | convertStreamToFile() |
Set conversion options on the client before calling a conversion method.
For example, client.setScaleFactor(150); enlarges the HTML page layout by a factor of 1.5.
Common settings are listed below. See the method reference for all available options or browse Node.js examples.
| Purpose | Methods |
|---|---|
| Pages to convert | setPrintPageRange() |
| Password-protected input | setPdfPassword() |
| Embedded or separate resources | setImageMode(), setCssMode(), setFontMode() |
| Image format and resolution | setImageFormat(), setDpi() |
| Scale and styles | setScaleFactor(), setCustomCss(), setHtmlNamespace() |
| Consistent ZIP output | setForceZip() |
The PDF password unlocks the input document; it is separate from your PDFCrowd API key.
By default, images, CSS and fonts are embedded in a single HTML file. The result preserves the PDF page layout; it does not reconstruct the original source HTML or create a responsive design.
The methods below use URL input; local files, bytes, and input streams have corresponding methods.
| Output | Async/await | Callbacks |
|---|---|---|
| Local file | convertUrlToFile() |
convertUrlToFile() |
| Buffer in memory | convertUrl() |
convertUrl() supplies a stream; collect its chunks into a Buffer. |
| Readable stream | convertUrlToStream() |
convertUrl() passes the response stream to data(stream). |
For large results, file or stream output avoids collecting the entire result in memory.
When saving a stream, wait for pipeline to finish and handle any error
before using the file. See the
stream examples.
For return values and completion rules, see Promise results and Callbacks in the reference.
This example converts a PDF to HTML, collects the result in a
Buffer,
and saves it locally as invoice.html:
import pdfcrowd from 'pdfcrowd'; import fs from 'node:fs'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); function saveResult(result) { fs.writeFileSync("invoice.html", result); } const result = await client.convertUrl("https://your-server.com/invoice.pdf"); saveResult(result); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; import fs from 'node:fs'; function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); function saveResult(result) { fs.writeFileSync("invoice.html", result); } const chunks = []; let failed = false; client.convertUrl("https://your-server.com/invoice.pdf", { data: (stream) => stream.on('data', (chunk) => chunks.push(chunk)), error: (message, statusCode) => { failed = true; handleError(new pdfcrowd.Pdfcrowd.Error(message, statusCode)); }, end: () => { if (failed) return; try { saveResult(Buffer.concat(chunks)); } catch (error) { handleError(error); } } }); } catch (error) { handleError(error); }
Setting an image, CSS or font mode to "separate" produces a ZIP archive with the HTML and its resources.
Save that result with a .zip extension, then extract it while retaining the relative directory structure.
isZippedOutput() reports whether the selected settings produce a ZIP archive.
When serving the result from a web application, use text/html; charset=utf-8 for HTML or application/zip for an archive.
Use try/catch around awaited conversions. In callback mode, handle errors in
the callback and catch synchronous validation errors from the initial call.
This example converts a PDF to HTML,
logging the HTTP status and reason code when available:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); const filePath = await client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.html" ); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. if (error instanceof pdfcrowd.Pdfcrowd.Error) { console.error("PDFCrowd error:", error.getStatusCode(), error.getReasonCode(), error.getMessage()); } else { console.error(String(error)); } }
import pdfcrowd from 'pdfcrowd'; function handleError(error) { // Handle the error in your application. if (error instanceof pdfcrowd.Pdfcrowd.Error) { console.error("PDFCrowd error:", error.getStatusCode(), error.getReasonCode(), error.getMessage()); } else { console.error(String(error)); } } try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.html", (error, filePath) => { if (error) { handleError(error); return; } console.log("Saved:", filePath); } ); } catch (error) { handleError(error); }
For stream output, handle errors both when obtaining the stream and when consuming it.
A pipeline reports failures while reading the response or writing the destination.
Conversion errors use pdfcrowd.Pdfcrowd.Error. Local file and stream operations
can also produce native errors; check the error type before using SDK-specific methods.
See the error-object reference for status, reason, and message accessors.
The SDK error's toString() includes available status and reason codes.
Use String(error) when logging an error of either type.
| Status | What it means | What to do |
|---|---|---|
400 | Invalid input, settings, or conversion failure | Read the reason code and correct the input or settings. |
401 | Missing credentials or an inactive license | Check your username, API key, and license status. |
403 | Suspended service or no credits remaining | Check your account and available credits. |
413 | Upload exceeds the 300 MB limit | Reduce the upload size. |
429 | Request rate limit reached | Wait and reduce the rate of new requests. |
430 | Concurrent request limit reached | Allow active requests to finish before starting more. |
503 | Temporary network issue | Check your retry policy before submitting another request. |
See all status and reason codes for specific explanations and Limits and Retries for retry behavior.
For job IDs, credit usage, and other conversion details, see the reference.
Request rate and concurrency limits depend on your license. Control how quickly
your application submits conversions and how many it runs at once. A
429 response concerns request rate; a 430 response
concerns requests already in progress. The maximum upload size is 300 MB.
The Node.js client automatically retries a request once when it receives HTTP
502 or 503. Use
setRetryCount()
to change that count, or set it to 0 to disable automatic retries.
Account for these retries when adding an application-level retry policy.
This example converts a PDF to HTML with debug logging enabled and logs the debug log URL when available. Use the input and settings from the conversion you are investigating.
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); try { client.setDebugLog(true); await client.convertUrlToFile("https://your-server.com/invoice.pdf", "invoice.html"); } finally { const debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl) console.info("Debug log:", debugLogUrl); } } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.PdfToHtmlClient("demo", "demo"); function finish(error) { if (error) handleError(error); const debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl) console.info("Debug log:", debugLogUrl); } try { client.setDebugLog(true); client.convertUrlToFile("https://your-server.com/invoice.pdf", "invoice.html", finish); } catch (error) { finish(error); } } catch (error) { handleError(error); }
The debug log contains conversion settings and processing details. You can also find logs in your conversion history. A local or connection failure may occur before a conversion log is available.
| Problem | Check |
|---|---|
| The PDF cannot be loaded | Check that the URL returns a PDF, rather than HTML or a login page, and is reachable from PDFCrowd's servers. For local files, check the path and read permissions. |
| The PDF requires a password | Set the input document's password with setPdfPassword(). |
| Images, fonts or styles are missing | If resource modes are set to "separate", extract the ZIP archive and retain its relative directory structure. |
| The layout does not adapt to the screen | The HTML preserves the PDF page layout. Responsive layouts require further work on the generated HTML and CSS. |
For help, contact support and include any available diagnostics, the client version, and enough detail to reproduce the problem.
The methods below were removed in SDK 7. For changes to Promise and callback usage, see the general upgrade notes.
| Removed method | Replacement |
|---|---|
setUserAgent() |
setClientUserAgent().
Use the same user-agent string for SDK requests to the API. |
error.getCode() |
error.getStatusCode()
returns the HTTP status code. |