npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

htmml

v1.0.4

Published

HTTML templating language to HTML converter

Readme

HTMML template language for HTML email

HTMML is a very simple template language we use to make it easier to write mosaico master templates. Given the master template language uses a lot of inline styles, you end up writing a lot of repeating HTML code.

HTMML processing does this:

  • Looks for <default selector="" attr1="" attr2=""> tags, run the selector as a CSS/jQuery selector to find matching tags in the HTML and add the other attributes to those tags.
<template-def>
<default selector=".right" align="right">
</template-def>
<p class="right">hello</p>

will be translated to

<p class="right" align="right">hello</p>

It's like CSS inlining, but applied to HTML elements and HTML attributes!

  • <template-def><template> the template-def tag contains template definitions and will be removed once template have been processed.

  • <template tag="tagname"> the template tag defines a new template that will be applied whenever the given tag is found in the html. Each <template> tag contains zero, one or more <def> tags and one <tmpl> tag. The <def attr="attrname"> tags define attributes supported by the template. Their selector="" attributes define which tags inside the <tmpl> section will be altered when this attribute is declared for this template. The rest of the <def> attributes will be added to the matched tags. A special {{attributename}} is available in the attributes defined to use the value of the attribute from the template caller.

An example, when this template is defined

<template-def>
<template tag="mytemplate">
  <def attr="myattr" selector="table, .myclass" mynewattribute="{{myattr}}" />
  <tmpl>
  	<table><tr><td class="myclass">{{replacedcontent}}</td></tr></table>
  </tmpl>
</template>
</template-def>

The following code

<mytemplate myattr="somevalue">some content</mytemplate>

will be translated to

<table mynewattribute="somevalue"><tr><td class="myclass" mynewattribute="somevalue">some content</td></tr></table>
  • Custom tags (and their templates) can be nested as long as {{replacedcontent}} is used in their <template><tmpl> definition.

  • Not every <def> attribute is handled in the same way

    • style or addStyle attributes will ADD the defined style to the style declaration of the matched tag, instead of replacing it.
    • class attribute will ADD new classes to the classes defined in the matched tag, instead of replacing it.
    • addAttributeName and addAttributeValue are special attributes that can be used to add dynamically defined attributes to the matched tags.
  • A <repeater> tag is available and will simply repeat the content according to the arguments. Any html attribute found in the repeater will be read, splitted by comma (,) and will be available as a {{variable}} in the content of the repeater, so:

<repeater var1="yellow,red,green" var2="10,20,30">
  <p style="color: {{var1}}">{{var2}}</p>
</repeater>

will be translated to

  <p style="color: yellow">10</p>
  <p style="color: red">20</p>
  <p style="color: green">30</p>
  • Last thing: HTMML does someting tricky in order to deal with your conditional comments contents. Outlook conditional comments are often needed in email HTML code and this makes you write HTML code in special HTML comments. Being comments it is not really considered HTML by anyone but Outlook. But we want to do our HTMML stuff also on conditional comments contents, so HTMML will "unescape" them to bring them to HTML, then apply its own template rules/logic, and then bring back them to comments. The tags found inside comments will be prefixed by "CC-" before being extracted and they never create nesting, so:
<template tag="cctest">
<def attr="myattr" style="color: {{myattr}}" />
<tmpl>
<!--[if (ie)]><table><tr><td><!-->
<p>my content</p>
<!--[if (ie)]></td></tr></table><!-->
</tmpl>
</template>

Will be temporarily translated to

<template tag="cctest">
<def attr="myattr" selector="cc-table" style="color: {{myattr}}" />
<def attr="wrongattr" selector="cc-table p" align="right" />
<tmpl>
<replacedcc condition="(ie)"><!-- cc:start --><cc-table><cc-tr><cc-td><!-- cc:end --></cc-td></cc-tr></cc-table></replacedcc>
<p>my content</p>
<replacedcc condition="(ie)"><cc-table><cc-tr><cc-td><!-- cc:start --></cc-td></cc-tr></cc-table><!-- cc:end --></replacedcc>
</tmpl>
</template>

The def rules will be applied on this new "template" and then a reverse process is applied to bring back them to their original "conditional comment" form. So the <def attr="wrongattr"> won't be applied, because in the "replaced" form the p is not INSIDE the cc-table because conditional comments do not create nesting levels. So, given that template and this tag:

<cctest myattr="red" wrongattr="somethingelse" />

the result of HTMML translation will be

<!--[if (ie)]><table style="color: red"><tr><td><!-->
<p>my content</p>
<!--[if (ie)]></td></tr></table><!-->

You see the style have been applied to the table, even if it was in a comment.

Done

The "HTMML" specification is complete. They are 200 lines of code and this matched my templating needs better than existing HTML template language.

HTMML users

We developed HTMML in order to improve maintenance of our Mosaico Versafix-1 master template