Renders Pug template to HTML or template function. Resolves source files of scripts, styles, images in Pug . Uses Pug template as entry point.
75
stars
105
commits
JavaScript
primary language
Mar 10, 2026
updated
The Pug Plugin generates static HTML or template function from Pug template containing source files of scripts, styles, images, fonts and other resources, similar to how it works in Vite. This plugin allows using a template file as an entry point.
The plugin resolves source files of assets in templates and replaces them with correct output URLs in the generated HTML. The resolved assets will be processed via Webpack plugins/loaders and placed into the output directory. You can use a relative path or Webpack alias to a source file.
A template imported in JS will be compiled into template function. You can use the template function in JS to render the template with variables in runtime on the client-side in the browser.
script and style source files directly in Pug:
link(href="./style.scss" rel="stylesheet")script(src="./app.tsx" defer="defer")href src srcset etc. using relative path or alias:
link(href="../images/favicon.svg" type="image/svg" rel=icon)img(src="@images/pic.png" srcset="@images/pic400.png 1x, @images/pic800.png 2x")link and script tags.:escape :code :highlight :markdown.See the full list of features.
โผ๏ธ Note
The
pug-pluginsince version5.0.0is essentially the html-bundler-webpack-plugin under the hood, pre-configured to use Pug templates. All features and options of html-bundler-webpack-plugin are now available inpug-plugin.
โ ๏ธ Warning
Compared to the version
4.x, in the new version5.xthe source asset file can be specified in a template without therequire()function. For compatibility, therequire()function is still supported.OLD syntax
link(href=require("./style.scss") rel="stylesheet")The asset path is relative to the partial template or can be as the webpack alias.
NEW syntax
link(href="./style.scss" rel="stylesheet")The asset path is relative to the entry template or can be as the webpack alias.
See the full list of the BREAKING CHANGES in v5.
Install the pug-plugin:
npm install pug-plugin --save-dev
Install additional packages for styles:
npm install css-loader sass sass-loader --save-dev
For example, there is the Pug template with source asset files ./src/views/index.pug:
html
head
//- relative path to SCSS source file
link(href="../scss/style.scss" rel="stylesheet")
//- relative path to TypeScript source file
script(src="../app/main.js" defer="defer")
body
h1 Hello World!
//- relative path to image source file
img(src="../assets/images/picture1.png")
//- Webpack alias as path (src/assets/images/) to image source file
img(src="@images/picture2.png")
The minimal webpack config:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
entry: {
// define many page templates here
index: 'src/views/index.pug', // => dist/index.html
},
js: {
// JS output filename
filename: 'js/[name].[contenthash:8].js',
},
css: {
// CSS output filename
filename: 'css/[name].[contenthash:8].css',
},
}),
],
module: {
rules: [
{
test: /\.(s?css|sass)$/,
use: ['css-loader', 'sass-loader'],
},
{
test: /\.(ico|png|jp?g|webp|svg)$/,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash:8][ext][query]',
},
},
],
},
};
Warning
No additional pug or html loaders required.
The generated HTML contains URLs of the output filenames:
<html>
<head>
<link href="css/style.05e4dd86.css" rel="stylesheet" />
<script src="js/main.f4b855d8.js" defer="defer"></script>
</head>
<body>
<h1>Hello World!</h1>
<img src="img/picture1.58b43bd8.png" />
<img src="img/picture2.bd858b43.png" />
</body>
</html>
The Pug plugin has all the options of the HTML Bundler Plugin, plus a few options specific to Pug plugin.
prettyType: 'auto'|boolean|Object Default: false
The Pug compiler generate minimized HTML.
For formatting generated HTML is used the js-beautify with the following default options:
{
html: {
indent_size: 2,
end_with_newline: true,
indent_inner_html: true,
preserve_newlines: true,
max_preserve_newlines: 0,
wrap_line_length: 120,
extra_liners: [],
space_before_conditional: true,
js: {
end_with_newline: false,
preserve_newlines: true,
max_preserve_newlines: 2,
space_after_anon_function: true,
},
css: {
end_with_newline: false,
preserve_newlines: false,
newline_between_rules: false,
},
},
}
Possible values:
false - disable formattingtrue - enable formatting with default options'auto' - in development mode enable formatting with default options, in production mode disable formatting,
use prettyOptions to customize options{} - enable formatting with custom options, this object are merged with default optionsprettyOptionsType: Object Default: null
When the pretty option is set to auto or true, you can configure minification options using the prettyOptions.
Why the Pug Plugin since v5.0 based on html-bundler-webpack-plugin?
2021
The history of the creation of the pug-plugin began back in October 2021.
In late 2021 I implemented the @webdiscus/pug-loader as ะฐ replacement for pug-loader because pug-loader was outdated and had many issues.
2022
Until 2022 html-webpack-plugin had no alternative.
Using html-webpack-plugin caused me pain and suffering to configure webpack for rendering Pug templates containing various assets.
In early 2022, I started developing the pug-plugin as a complete replacement for html-webpack-plugin and many other "crutches".
During the year, the pug-plugin has gained a lot of useful features and was able to replace the html-webpack-plugin, mini-css-extract-plugin and many other plugins and loaders.
2023
Based on the pug-plugin code I decided to develop a universal html-bundler-webpack-plugin that would support all the most popular template engines, such as Eta, EJS, Handlebars, Nunjucks, Pug, TwigJS, and would be extendable for other template engines, e.g., LiquidJS.
During the year, this plugin has gained even more useful features and absorbed all the functionality of the pug-plugin and the @webdiscus/pug-loader.
2024
In early 2024, the pug-plugin completely switched to the universal code of html-bundler-webpack-plugin.
Starting from version 5.0, the pug-plugin is the html-bundler-webpack-plugin unter the hood, pre-configured for Pug templates with the pre-installed pug package.
The config of pug-plugin >= v5.0:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
entry: {
index: 'src/views/home.pug',
},
}),
],
};
The above configuration is equivalent to:
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
plugins: [
new HtmlBundlerPlugin({
entry: {
index: 'src/views/home.pug',
},
preprocessor: 'pug', // <= enable using Pug templating engine
}),
],
};
The heart of
pug-pluginnow beats in thehtml-bundler-webpack-plugin.
@webdiscus/pug-loader->pug-plugin->html-bundler-webpack-plugin->pug-plugin
JavaScript
61.1%
HTML
16.8%
Pug
13.5%
SCSS
4.9%
CSS
3.7%
Renders Pug template to HTML or template function. Resolves source files of scripts, styles, images in Pug . Uses Pug template as entry point.
75
stars
105
commits
JavaScript
primary language
Mar 10, 2026
updated
The Pug Plugin generates static HTML or template function from Pug template containing source files of scripts, styles, images, fonts and other resources, similar to how it works in Vite. This plugin allows using a template file as an entry point.
The plugin resolves source files of assets in templates and replaces them with correct output URLs in the generated HTML. The resolved assets will be processed via Webpack plugins/loaders and placed into the output directory. You can use a relative path or Webpack alias to a source file.
A template imported in JS will be compiled into template function. You can use the template function in JS to render the template with variables in runtime on the client-side in the browser.
script and style source files directly in Pug:
link(href="./style.scss" rel="stylesheet")script(src="./app.tsx" defer="defer")href src srcset etc. using relative path or alias:
link(href="../images/favicon.svg" type="image/svg" rel=icon)img(src="@images/pic.png" srcset="@images/pic400.png 1x, @images/pic800.png 2x")link and script tags.:escape :code :highlight :markdown.See the full list of features.
โผ๏ธ Note
The
pug-pluginsince version5.0.0is essentially the html-bundler-webpack-plugin under the hood, pre-configured to use Pug templates. All features and options of html-bundler-webpack-plugin are now available inpug-plugin.
โ ๏ธ Warning
Compared to the version
4.x, in the new version5.xthe source asset file can be specified in a template without therequire()function. For compatibility, therequire()function is still supported.OLD syntax
link(href=require("./style.scss") rel="stylesheet")The asset path is relative to the partial template or can be as the webpack alias.
NEW syntax
link(href="./style.scss" rel="stylesheet")The asset path is relative to the entry template or can be as the webpack alias.
See the full list of the BREAKING CHANGES in v5.
Install the pug-plugin:
npm install pug-plugin --save-dev
Install additional packages for styles:
npm install css-loader sass sass-loader --save-dev
For example, there is the Pug template with source asset files ./src/views/index.pug:
html
head
//- relative path to SCSS source file
link(href="../scss/style.scss" rel="stylesheet")
//- relative path to TypeScript source file
script(src="../app/main.js" defer="defer")
body
h1 Hello World!
//- relative path to image source file
img(src="../assets/images/picture1.png")
//- Webpack alias as path (src/assets/images/) to image source file
img(src="@images/picture2.png")
The minimal webpack config:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
entry: {
// define many page templates here
index: 'src/views/index.pug', // => dist/index.html
},
js: {
// JS output filename
filename: 'js/[name].[contenthash:8].js',
},
css: {
// CSS output filename
filename: 'css/[name].[contenthash:8].css',
},
}),
],
module: {
rules: [
{
test: /\.(s?css|sass)$/,
use: ['css-loader', 'sass-loader'],
},
{
test: /\.(ico|png|jp?g|webp|svg)$/,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash:8][ext][query]',
},
},
],
},
};
Warning
No additional pug or html loaders required.
The generated HTML contains URLs of the output filenames:
<html>
<head>
<link href="css/style.05e4dd86.css" rel="stylesheet" />
<script src="js/main.f4b855d8.js" defer="defer"></script>
</head>
<body>
<h1>Hello World!</h1>
<img src="img/picture1.58b43bd8.png" />
<img src="img/picture2.bd858b43.png" />
</body>
</html>
The Pug plugin has all the options of the HTML Bundler Plugin, plus a few options specific to Pug plugin.
prettyType: 'auto'|boolean|Object Default: false
The Pug compiler generate minimized HTML.
For formatting generated HTML is used the js-beautify with the following default options:
{
html: {
indent_size: 2,
end_with_newline: true,
indent_inner_html: true,
preserve_newlines: true,
max_preserve_newlines: 0,
wrap_line_length: 120,
extra_liners: [],
space_before_conditional: true,
js: {
end_with_newline: false,
preserve_newlines: true,
max_preserve_newlines: 2,
space_after_anon_function: true,
},
css: {
end_with_newline: false,
preserve_newlines: false,
newline_between_rules: false,
},
},
}
Possible values:
false - disable formattingtrue - enable formatting with default options'auto' - in development mode enable formatting with default options, in production mode disable formatting,
use prettyOptions to customize options{} - enable formatting with custom options, this object are merged with default optionsprettyOptionsType: Object Default: null
When the pretty option is set to auto or true, you can configure minification options using the prettyOptions.
Why the Pug Plugin since v5.0 based on html-bundler-webpack-plugin?
2021
The history of the creation of the pug-plugin began back in October 2021.
In late 2021 I implemented the @webdiscus/pug-loader as ะฐ replacement for pug-loader because pug-loader was outdated and had many issues.
2022
Until 2022 html-webpack-plugin had no alternative.
Using html-webpack-plugin caused me pain and suffering to configure webpack for rendering Pug templates containing various assets.
In early 2022, I started developing the pug-plugin as a complete replacement for html-webpack-plugin and many other "crutches".
During the year, the pug-plugin has gained a lot of useful features and was able to replace the html-webpack-plugin, mini-css-extract-plugin and many other plugins and loaders.
2023
Based on the pug-plugin code I decided to develop a universal html-bundler-webpack-plugin that would support all the most popular template engines, such as Eta, EJS, Handlebars, Nunjucks, Pug, TwigJS, and would be extendable for other template engines, e.g., LiquidJS.
During the year, this plugin has gained even more useful features and absorbed all the functionality of the pug-plugin and the @webdiscus/pug-loader.
2024
In early 2024, the pug-plugin completely switched to the universal code of html-bundler-webpack-plugin.
Starting from version 5.0, the pug-plugin is the html-bundler-webpack-plugin unter the hood, pre-configured for Pug templates with the pre-installed pug package.
The config of pug-plugin >= v5.0:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
entry: {
index: 'src/views/home.pug',
},
}),
],
};
The above configuration is equivalent to:
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
plugins: [
new HtmlBundlerPlugin({
entry: {
index: 'src/views/home.pug',
},
preprocessor: 'pug', // <= enable using Pug templating engine
}),
],
};
The heart of
pug-pluginnow beats in thehtml-bundler-webpack-plugin.
@webdiscus/pug-loader->pug-plugin->html-bundler-webpack-plugin->pug-plugin
JavaScript
61.1%
HTML
16.8%
Pug
13.5%
SCSS
4.9%
CSS
3.7%