node package manager
Stop writing boring code. Discover, share, and reuse within your team. Create a free org »



npm version build status downloads js-standard-style

Print GitHub Markdown to PDF using headless Chrome.


Print to dist/letter.pdf then log a completion message.

const letterpress = require('letter-press')
const letter = fs.readFileSync(path.join(__dirname, ''))
letterpress.print('letter', letter)
  .then(() => console.log('🐈  done'))

Example: Print multiple letters using a template

Print letters to dist/*.pdf based on a Markdown template and some data (e.g. mailing list).

const letterpress = require('letter-press')
const letter = (sender, recipient) =>
`Dear ${recipient},
Here is some **bold text**. *Winky face*.
Yours sincerely,
const list = [
  { id: 'letter1', sender: 'Your Secret Lesbian Admirer', recipient: 'John' }
  // ...
const press = await letterpress.launch()
const jobs = []
list.forEach(item => {
  const markdown = letter(item.sender, item.recipient)
  const job = press.print(, markdown)
await Promise.all(jobs)


letterpress.print(id, markdown, [opts])

Print the given markdown string to PDF.

Return: Promise

Writes the following files:


Launch a new Press.

Return: Promise of Press

Press.prototype.print(id, markdown, [opts])

Print the given markdown string to PDF.

Return: Promise of Press

Writes the following files:

The returned Promise resolves with the Press object so that calls can be chained (e.g. letterpress.launch then press.print then press.close). It is not necessary to wait for a print to resolve before calling print again - print scheduling is all handled under the hood.


Close this Press. Call after all prints have resolved or if an error is caught.


These options can be set at launch and/or for each print.

opts.path Path to output folder. Default: dist

opts.quiet Only log when something goes awry. Default: false

opts.markdown Options passed to markdown-it: new MarkdownIt(opts). API

opts.template Path to pug template file used when generating HTML. The template must contain a !=content, and may contain a !=title. Default: Template File

opts.pug Options passed to pug: pug.renderFile. API

opts.pdf Options passed to puppeteer: page.pdf(opts). API