PDFPipe

Comparison

PDFPipe vs Carbone.io

Carbone generates PDFs and Office documents from LibreOffice templates (.docx, .odt). The workflow requires uploading a template file, storing a template ID, posting a data payload to a render endpoint, receiving a render ID, then downloading the result in a second request. PDFPipe uses plain HTML as the template format and returns the PDF in a single synchronous call.

FeatureCarbone.ioPDFPipe
Template formatLibreOffice .docx / .odtAny HTML template engine
Template workflowUpload → store template ID → render → pollCompile HTML inline, POST once
CSS supportWord styles onlyFull modern CSS, Grid, Flexbox, custom fonts
Version controlFile uploads, not diff-ableHTML files live in your repo
JavaScript in templateNoYes (rendered server-side before POST)
Free tier100 renders/month500 renders/month
Synchronous responseNo (renderID polling)Yes (PDF bytes returned directly)
Self-host optionCarbone Community Edition (Node.js)No (hosted only)
Stored document URLNo (download by renderId)Yes (store: true returns stable URL)

The template upload loop

Carbone's API requires four steps: upload the .docx template, store the returned template ID, POST a render request with a data object, then download the result using the render ID. That is two round-trips minimum, and in practice templates must be re-uploaded after changes, which complicates CI/CD pipelines and preview deployments.

PDFPipe takes a single POST. Your HTML template is compiled in-process using whatever engine you already use (Handlebars, Jinja2, Liquid, string interpolation), then sent in the request body. No upload step, no ID to persist, no second fetch.

Code comparison

Carbone.io
// Carbone.io: upload a .docx template file to the API,
// then fill it with a JSON payload — returns the rendered PDF.
// Requires separate template upload/management steps.

const formData = new FormData();
formData.append("template", fs.createReadStream("./invoice.docx"));

const upload = await fetch("https://api.carbone.io/template", {
  method: "POST",
  headers: { "carbone-version": "4" },
  body: formData,
});
const { data: { templateId } } = await upload.json();

const render = await fetch(`https://api.carbone.io/render/${templateId}`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.CARBONE_KEY}`,
    "carbone-version": "4",
  },
  body: JSON.stringify({
    data: { customer: "Acme Corp", total: 1200, dueDate: "2026-07-01" },
    convertTo: "pdf",
  }),
});
const { data: { renderId } } = await render.json();

const pdf = await fetch(`https://api.carbone.io/render/${renderId}`);
// Save pdf.body stream...
PDFPipe
// PDFPipe: send HTML directly — no template upload, no render ID polling.
// Your template is an HTML string compiled server-side however you like.

import Handlebars from "handlebars";
import { readFileSync } from "fs";

const tmpl = Handlebars.compile(readFileSync("./invoice.html", "utf-8"));
const html = tmpl({ customer: "Acme Corp", total: 1200, dueDate: "2026-07-01" });

const resp = await fetch("https://api.pdfpipe.xyz/v1/pdf", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PDFPIPE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ html, options: { format: "A4" } }),
});

const pdfBytes = await resp.arrayBuffer();
// Done — one round-trip, PDF in hand.

Template format trade-offs

Carbone's .docx format works well for output that must be editable by non-technical staff in Microsoft Word or LibreOffice. The template stays in a familiar word processor, and business users can adjust layouts without touching code.

HTML templates are a better fit when the design is owned by an engineer or designer, when the layout uses modern CSS (Flexbox, Grid, variable fonts, custom colors), or when the template must be reviewed in pull requests alongside the rest of the application. HTML is diff-able, testable, and deployable through the same CI pipeline that ships the application.

When Carbone is the better choice

  • +You need editable .docx output, not just PDF.
  • +Non-technical users must be able to edit templates in Word without code changes.
  • +You need the self-hostable Community Edition to keep all processing on-premise.
  • +You are already generating Word documents and want PDF as a side output, not the primary format.

Pricing

PlanCarbone.ioPDFPipe
Free100 renders/mo500 renders/mo
Starter€19/mo, 10k renders$19/mo, 3k renders
Growth€79/mo, 50k renders$49/mo, 15k renders
Scale€149/mo, 200k renders$149/mo, 50k renders

Try PDFPipe free

500 renders a month. No card required. PDF bytes in one HTTP call.