HTML to Jade for projects that never moved to Pug
Jade is the name the Pug template engine used until 2016, when a trademark problem forced the rename. The jade package on npm is now deprecated, yet many older Express applications, admin panels and build scripts still render .jade views and pin that package. This HTML to Jade converter is meant for those codebases: paste a piece of HTML and get markup you can drop into an existing Jade view without upgrading anything first.
It runs the same converter as the HTML to Pug converter. Starting a new template, or working in a project that already depends on pug? Use that page, which covers the modern workflow and all output details. Stay here when the target file ends in .jade and the goal is to fit into legacy code.
Why the output is safe in old Jade files
The converter only writes the core syntax that Jade and Pug have in common:
- Nesting by indentation, with no closing tags.
#idand.classshorthand, withdivleft out when a shorthand is present.- Attributes in parentheses, separated by commas unless you switch that off.
doctype htmlfor an HTML5 doctype.- Dot blocks such as
script.for script, style and preformatted content. - HTML comments turned into
//comments.
It never produces the !!! doctype shorthand, JavaScript code lines or interpolation inside attribute values. Because of that, a view you extend today will not need edits for these constructs if the project is upgraded to Pug later.
Example: adding a form to a legacy view
<form action="/login" method="post">
<!-- sign-in form -->
<label for="user">User name</label>
<input id="user" name="user" required>
<p>Forgot it? <a href="/reset">Reset your password</a>.</p>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
<script>
document.getElementById('user').focus();
</script>
With the default options the converter returns:
form(action="/login", method="post")
// sign-in form
label(for="user") User name
input#user(name="user", required)
p Forgot it? #[a(href="/reset") Reset your password].
button.btn.btn-primary(type="submit") Sign in
script.
document.getElementById('user').focus();
The link inside the paragraph became #[a(href="/reset") Reset your password]. That is tag interpolation, a later addition to the language that the earliest Jade releases do not understand. If an old project rejects it, move the inline element onto its own line under the paragraph, write the surrounding words as piped text (|), and check the spacing in the rendered page.
Jade vs Pug: differences that matter when migrating
| Topic | Legacy Jade projects | Pug |
|---|---|---|
| npm package | jade (deprecated) | pug |
| File extension | .jade | .pug |
| Express setting | app.set('view engine', 'jade') | app.set('view engine', 'pug') |
| Doctype | often !!! or !!! 5 | doctype html only |
| Values inside attributes | early Jade interpolated a(href="/u/#{id}") | write JavaScript instead: a(href="/u/" + id) |
When the upgrade happens, the usual order is: install pug and remove jade, rename the view files, change the view engine setting, then search the templates for !!! and for #{ inside parentheses. Markup produced by this converter is already in the Pug-compatible form, so only hand-written legacy parts need attention.
Choosing options for an existing Jade codebase
- Indent – two spaces, four spaces or a tab. Look at the view you are editing and match it, because indentation must be consistent within a file and a pasted block with a different style will not nest correctly.
- Commas between attributes – on by default. Commas have always been valid attribute separators, so leaving them on is the conservative choice for old Jade versions.
- Attribute quotes – double or single. Pick whatever the surrounding templates use so diffs stay small.
- Remove comments – a
//comment is rendered into the final HTML. If internal notes should not reach the browser, strip them here or change them to//-afterwards.
Text that contains #{ or #[ is escaped with a backslash, for example p Price: \#{price}, so Jade prints the characters instead of trying to evaluate them.
Checking the converted markup
Tidy messy source first with the HTML formatter, since clean nesting gives clean Jade. After converting, paste the result into the Jade to HTML converter to render it back and compare it with the original. If the legacy app is being rewritten as React components rather than kept on Jade, the HTML to JSX converter is the more useful target.
The conversion runs in your browser; the HTML you paste is not sent to a server.