{"id":15170784,"url":"https://github.com/relaxedjs/relaxed","last_synced_at":"2025-05-14T01:05:44.774Z","repository":{"id":37450984,"uuid":"126147399","full_name":"RelaxedJS/ReLaXed","owner":"RelaxedJS","description":"Create PDF documents using web technologies","archived":false,"fork":false,"pushed_at":"2022-09-01T08:18:18.000Z","size":853,"stargazers_count":11803,"open_issues_count":52,"forks_count":426,"subscribers_count":183,"default_branch":"master","last_synced_at":"2025-04-03T06:05:56.431Z","etag":null,"topics":["chromium","converter","html","pdf-document","pug","scss"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RelaxedJS.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-21T08:33:48.000Z","updated_at":"2025-04-02T18:55:40.000Z","dependencies_parsed_at":"2022-07-09T09:30:21.439Z","dependency_job_id":null,"html_url":"https://github.com/RelaxedJS/ReLaXed","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RelaxedJS%2FReLaXed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RelaxedJS%2FReLaXed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RelaxedJS%2FReLaXed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RelaxedJS%2FReLaXed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RelaxedJS","download_url":"https://codeload.github.com/RelaxedJS/ReLaXed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248202002,"owners_count":21064244,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chromium","converter","html","pdf-document","pug","scss"],"created_at":"2024-09-27T08:22:58.374Z","updated_at":"2025-04-10T10:47:43.958Z","avatar_url":"https://github.com/RelaxedJS.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\u003cimg width='270px' src=\"https://github.com/RelaxedJS/ReLaXed/raw/master/logo-blue.png\" /\u003e\u003c/p\u003e\n\n# ReLaXed\n\n[![Build Status](https://travis-ci.org/RelaxedJS/ReLaXed.svg?branch=master)](https://travis-ci.org/RelaxedJS/ReLaXed)\n\nReLaXed creates PDF documents interactively using HTML or [Pug](https://pugjs.org/api/getting-started.html) (a shorthand for HTML). It allows complex layouts to be defined with CSS and JavaScript, while writing the content in a friendly, minimal syntax close to Markdown or LaTeX.\n\nHere it is in action in the Atom editor:\n\n\u003cp align='center'\u003e\u003cimg src=\"https://i.imgur.com/4N4fSYY.gif\" title=\"source: imgur.com\" /\u003e\u003c/p\u003e\n\nAnd here are a few output examples:\n\n\u003ctable\u003e\n  \u003ctr align=\"center\"\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/book/book.pdf\"\u003e\n        \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/book/book_screenshot.png\" /\u003e\n      \u003c/a\u003e\n      Book -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/book/\"\u003e source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/book/book.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/letter/letter.pdf\"\u003e\n        \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/letter/letter_screenshot.png\" /\u003e\n      \u003c/a\u003e\n      Letter -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/letter/\"\u003e Source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/letter/letter.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/resume/resume.pdf\"\u003e\n        \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/resume/resume_screenshot.png\" /\u003e\n      \u003c/a\u003e\n      Resume -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/resume/\"\u003e Source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/resume/resume.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/business-card/business-card.pdf\"\u003e\n      \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/business-card/businesscard_screenshot.png\" /\u003e\u003c/a\u003e\n      Visit card -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/business-card/\"\u003e Source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/business-card/business-card.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctr align=\"center\"\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/slides/slides.pdf\"\u003e\n        \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/slides/slides_screenshot.png\" /\u003e\n      \u003c/a\u003e\n      Slides -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/slides/\"\u003e Source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/slides/slides.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"25%\"\u003e\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/report/report.pdf\"\u003e\n        \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/report/report_screenshot.png\" /\u003e\n      \u003c/a\u003e\n      Report -\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/report/\"\u003e Source \u003c/a\u003e /\n      \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/report/report.pdf\"\u003e PDF \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"25%\"\u003e\n       \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/paper/paper.pdf\"\u003e\n         \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/paper/paper_screenshot.png\" /\u003e\n       \u003c/a\u003e\n       Paper -\n       \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/paper/\"\u003e Source \u003c/a\u003e /\n       \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/paper/paper.pdf\"\u003e PDF \u003c/a\u003e\n     \u003c/td\u003e\n   \u003ctd width=\"25%\"\u003e\n     \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/poster/poster.pdf\"\u003e\n       \u003cimg src=\"https://github.com/RelaxedJS/ReLaXed-examples/raw/master/examples/poster/poster_screenshot.png\" /\u003e\n     \u003c/a\u003e\n     Poster -\n     \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/tree/master/examples/poster/\"\u003e Source \u003c/a\u003e /\n     \u003ca href=\"https://github.com/RelaxedJS/ReLaXed-examples/blob/master/examples/poster/poster.pdf\"\u003e PDF \u003c/a\u003e\n   \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nReLaXed has support for Markdown, LaTeX-style mathematical equations (via [MathJax](https://www.mathjax.org/)), CSV conversion to HTML tables, plot generation (via [Vega-Lite](https://vega.github.io/vega-lite/) or [Chart.js](https://www.chartjs.org/)), and diagram generation (via [mermaid](https://mermaidjs.github.io/)). Many more features can be added simply by importing an existing JavaScript or CSS framework.\n\n## Installing ReLaXed\n\nInstall ReLaXed via [NPM](https://www.npmjs.com/) with this command (do not use ``sudo``):\n\n```\nnpm i -g relaxedjs\n```\n\nThis will provide your system with the ``relaxed`` command. If the installation fails, refer to the [troubleshooting page](https://github.com/RelaxedJS/ReLaXed/wiki/Troubleshooting). You can also use ReLaXed via Docker (see [this repository](https://github.com/jonathanasquier/ReLaXed-docker/blob/master/Dockerfile))\n\n\n## Getting started\n\nTo start a project, create a new document ``my_document.pug`` with the following Pug content:\n\n```pug\nh1 My document's title\np A paragraph in my document\n```\n\nThen start ReLaXed from a terminal:\n\n```\nrelaxed my_document.pug\n```\n\nReLaXed will generate ``my_document.pdf`` from ``my_document.pug``, then watch its directory and subdirectories so that every time a file changes, ``my_document.pdf`` will be re-generated.\n\nIt is also possible to generate the PDF file just once, with no sub-sequent file-watching, with this command:\n\n```\nrelaxed my_document.pug --build-once\n```\n\nTo go further:\n\n- Read more about [usage and options](https://github.com/RelaxedJS/ReLaXed/wiki/Command-line-options) of the ``relaxed`` command.\n- Learn more about the capabilities of the [Pug language](https://pugjs.org/api/getting-started.html)\n- Learn how to use or write [ReLaXed plugins](https://github.com/RelaxedJS/ReLaXed/wiki/Plugins)\n- Browse the [examples](https://github.com/RelaxedJS/ReLaXed-examples)\n- Read about our [recommended setup](https://github.com/RelaxedJS/ReLaXed/wiki/Tips-and-recommendations) to use ReLaXed\n- read about [special file rendering](https://github.com/RelaxedJS/ReLaXed/wiki/Special-file-renderings) in ReLaxed\n- Read [these comparisons](https://github.com/RelaxedJS/ReLaXed/wiki/ReLaXed-vs-other-solutions) between ReLaXed and other document-editing systems\n\n## Why yet another PDF document creator?\n\nMany of us prefer markup languages (Markdown, LaTeX, etc.) to GUI document-editors like MS Office or Google Docs. This is because markup languages make it easier to quickly write documents in a consistent style.\n\nHowever, Markdown is limited to the title/sections/paragraphs structure, and LaTeX has obscure syntax and errors that also make it difficult to stray from the beaten track.\n\nOn the other hand, web technologies have never looked so good.\n\n- Beautiful CSS frameworks make sure your documents look clean and modern.\n- There are JavaScript libraries for pretty much anything: plotting, highlight code, rendering equations...\n- Millions of people (and growing) know how to use these.\n- Shorthand languages like Pug and SCSS are finally making it fun to write HTML and CSS.\n- (Headless) web browsers can easily turn web documents into PDF, on any platform.\n\nReLaXed is an attempt at finding the most comfortable way to leverage this for desktop PDF creation.\n\n## How ReLaXed works\n\nReLaXed consists of a few lines of code binding together other software. It uses [Chokidar](https://github.com/paulmillr/chokidar) to watch the file system. When a file is changed, several JavaScript libraries are used to compile SCSS, Pug, Markdown, and diagram files (mermaid, flowchart.js, Chart.js) into an HTML page which is then printed to a PDF file by a headless instance of Chromium (via [Puppeteer](https://github.com/GoogleChrome/puppeteer)).\n\n\u003cp align=\"center\"\u003e\u003cimg width='600px' src=\"https://github.com/RelaxedJS/ReLaXed/raw/master/docs/relaxed_stack.png\" /\u003e\u003c/p\u003e\n\n## Using it as a Node Module\n**MasterToPDF.js** is exposed by default as main package, which can be used directly.\n\nAn Example: \n\n```javascript\nconst { masterToPDF } = require('relaxedjs');\nconst puppeteer = require('puppeteer');\nconst plugins = require('relaxedjs/src/plugins');\nconst path = require('path');\n\nclass HTML2PDF {\n  constructor() {\n    this.puppeteerConfig = {\n      headless: true,\n      args: [\n        '--no-sandbox',\n        '--disable-translate',\n        '--disable-extensions',\n        '--disable-sync',\n      ],\n    };\n\n    this.relaxedGlobals = {\n      busy: false,\n      config: {},\n      configPlugins: [],\n    };\n\n    this._initializedPlugins = false;\n  }\n\n  async _initializePlugins() {\n    if (this._initializedPlugins) return; // Do not initialize plugins twice\n    for (const [i, plugin] of plugins.builtinDefaultPlugins.entries()) {\n      plugins.builtinDefaultPlugins[i] = await plugin.constructor();\n    }\n    await plugins.updateRegisteredPlugins(this.relaxedGlobals, '/');\n\n    const chrome = await puppeteer.launch(this.puppeteerConfig);\n    this.relaxedGlobals.puppeteerPage = await chrome.newPage();\n    this._initializedPlugins = true;\n  }\n\n  async pdf(templatePath, json_data, tempHtmlPath, outputPdfPath) {\n    await this._initializePlugins();\n    if (this._initializedPlugins) {\n      // Paths must be absolute\n      const defaultTempHtmlPath = tempHtmlPath || path.resolve('temp.html');\n      const defaultOutputPdfPath =\n        outputPdfPath || path.resolve('output.pdf');\n\n      await masterToPDF(\n        templatePath,\n        this.relaxedGlobals,\n        defaultTempHtmlPath,\n        defaultOutputPdfPath,\n        json_data\n      );\n    }\n  }\n}\n\nmodule.exports = new HTML2PDF();\n```\nUsage:\n\n```javascript\nconst HTML2PDF = require('./HTML2PDF.js');\n(async () =\u003e {\n    await HTML2PDF.pdf('./template.pug', {\"a\":\"b\", \"c\":\"d\"});\n})();\n```\n\n\n## Contribute!\n\nReLaXed is an open-source framework originally written by [Zulko](https://github.com/Zulko) and released on [Github](https://github.com/RelaxedJS/ReLaXed) under the ISC licence. Everyone is welcome to contribute!\n\nFor bugs and feature requests, open a Github issue. For support or Pug/HTML-related questions, ask on Stackoverflow or on the brand new [reddit/r/relaxedjs](https://www.reddit.com/r/relaxedjs/) forum, which can be used for any kind of discussion.\n\n**Projects members:**\n\n- [@Zulko](https://github.com/Zulko) (Owner)\n- [@Drew-S](https://github.com/Drew-S) (architecture, plugins)\n- [@DanielRuf](https://github.com/DanielRuf)\n- [@benperiton](https://github.com/benperiton)\n\n## License\n\n[ISC](https://github.com/RelaxedJS/ReLaXed/blob/master/LICENCE.txt)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxedjs%2Frelaxed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelaxedjs%2Frelaxed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxedjs%2Frelaxed/lists"}