DEV Community

Hichem Bed
Hichem Bed

Posted on

Markdown to PDF in Node.js: The API Approach

Here's the usual Markdown-to-PDF pipeline developers end up building:

  1. Parse Markdown to HTML with marked or remark
  2. Wrap it in a full HTML document with inline styles
  3. Launch Puppeteer, navigate to the HTML, call page.pdf()
  4. Handle Puppeteer teardown so it doesn't leak memory
  5. Debug why code blocks don't have syntax highlighting
  6. Repeat for every new document type

It works. But it's a lot of moving parts to maintain.

The Simpler Path

npm install renderpdfs
Enter fullscreen mode Exit fullscreen mode
import RenderPDFs from 'renderpdfs';

const client = new RenderPDFs('rpdf_your_key');

const pdf = await client.generate({
  markdown: '# My Report\n\nHello **world**.',
});
Enter fullscreen mode Exit fullscreen mode

That's a Buffer containing your PDF. No intermediate HTML, no browser.

Real Use Case: Exporting User-Written Content as PDF

app.post('/export/pdf', authenticate, async (req, res) => {
  const { markdown, filename = 'export' } = req.body;

  if (!markdown || typeof markdown !== 'string') {
    return res.status(400).json({ error: 'markdown field required' });
  }

  const pdf = await client.generate({ markdown });

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}.pdf"`);
  res.send(pdf);
});
Enter fullscreen mode Exit fullscreen mode

Generating a Report from a Template

function buildReportMarkdown({ title, author, date, sections }) {
  const sectionText = sections
    .map(({ heading, content }) => `## ${heading}\n\n${content}`)
    .join('\n\n');

  return `# ${title}\n\n**Author:** ${author}\n**Date:** ${date}\n\n---\n\n${sectionText}`;
}

const markdown = buildReportMarkdown({
  title: 'Q1 Performance Report',
  author: 'Analytics Team',
  date: '2026-04-01',
  sections: [
    { heading: 'Revenue', content: 'Revenue increased **24%** quarter-over-quarter.' },
    { heading: 'User Growth', content: 'Monthly active users reached **12,400**.' },
  ],
});

const pdf = await client.generate({ markdown });
Enter fullscreen mode Exit fullscreen mode

Store and Get a Shareable URL

const { url } = await client.generate({ markdown, store: true });
return res.json({ downloadUrl: url });
Enter fullscreen mode Exit fullscreen mode

What Markdown Features Are Supported?

  • Headings, paragraphs, bold, italic, strikethrough
  • Ordered and unordered lists, nested lists
  • Fenced code blocks with language tags
  • Tables, blockquotes, horizontal rules
  • Inline HTML

Getting Started

npm install renderpdfs
Enter fullscreen mode Exit fullscreen mode

Free plan at renderpdfs.com: 100 PDFs/month, no credit card. Full API docs at renderpdfs.com/docs.

Top comments (0)