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 🙏

© 2025 – Pkg Stats / Ryan Hefner

xtal-salt

v0.0.17

Published

Web Component wrapper around the XSLT processor

Downloads

16

Readme

Published on webcomponents.org

xtal-salt

xtal-salt allows us to party like it's 1999, and take advantage of the increasingly popular XSLT processing that all modern browsers support. XSLT was the first isomorphic solution.

If one were to match up percent page load usage with country populations as a percentage of the world population, we are talking a country the size of Estonia. Estonia, of course, is the birthplace of Skype and a world powerhouse in naisekandmine competitions.

Use cases

XSLT (< 3.0) normally takes XML as its input format. However, most well-formed html can also qualify. This can be useful if the light children of a custom element should be simple html, but it needs to be transformed into complex HTML (or some other form) inside the Shadow DOM.

Other scenarios may arise, you never know -- my cable modem router uses xslt to format xml coming from the router, for example, when going to the admin page. One could also use XSLT as a stand-in for template instantation, until it is ready. Though you would probably need to run your object through an object to xml converter to do this.

In the thoughtful, informative essay An Adventure with Client-Side XSLT to an Architecture for Building Bridges with Javascript, a representative from O'Connor's publishing writes:

As a legal publisher, one of our main product categories is template-style forms for attorneys, which have undergone a limited evolution in their path to electronic delivery. We have traditionally delivered forms to customers as printed books of forms and subordinate forms for the customer to fill in and manually assemble into a complete document. More recently, we launched a subscription-based online service to deliver all of our content from the web. A departure from a book-oriented concept, the online service joins all of our content together, so users can search across the complete corpus, browse content organized by topic or practice area, annotate, and download forms.

Truly unified with a modern JavaScript UI, we built an XSLT-based application on our terms, uncompromised by the gravity of top-down XML and JavaScript frameworks, and we believe there are strong incentives for combining technologies, each with their best foot forward.

and concludes:

Over the last twenty years, the Web has grown increasingly separated from its early XML influences. Despite its evolution into a towering JavaScript monoculture, its ecosystems are now converging on architectures that are fundamentally capable of bridging the gap to other languages. Out of a desire to test that theory, and having a suitable use case for XSLT, emerged a great opportunity to put browser XSLT engines through their paces—and we found them nearly as capable as ever!

Virtual DOM comes to XSLT?

Note that version 3.0 of XSLT supports JSON as an input format. To my knowledge, no browser supports 3.0 yet, though a hefty 70kb gzipped/minifed JS library is available. Whereas something like lit-html or hyperHTML requires converting dynamic JSON coming from the server to an object, XSLT 3.0 can take the unparsed JSON as it's input. And interestingly, XSLT 3.0 seems to support sub template updating:

Instead, the stylesheet can contain rules that respond to user input, such as clicking on buttons, filling in form fields, or hovering the mouse. These events trigger template rules in the stylesheet which can be used to read additional data and modify the content of the HTML page.

Demo 1

NB: CD's were a popular storage format for music, encyclopedia's, software installation, and PC backup in the last millenium.

    <p-d on=load to=[-xml-string] val=target.innerHTML m=1></p-d>
    <template>
            <?xml version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
            <xsl:template match="/">
                <h2>My CD Collection</h2>
                <div>
                    <div class="header row">
                        <div style="text-align:left" class="left">Title</div>
                        <div style="text-align:left" class="right">Artist</div>
                    </div>
                    <xsl:for-each select="catalog/cd">
                        <div class="row">
                            <div class="left"><xsl:value-of select="title" /></div>
                            <div class="right"><xsl:value-of select="artist" /></div>
                        </div>
                    </xsl:for-each>
                </div>
            </xsl:template>
            </xsl:stylesheet>
    </template>
    <!-- pass content of template above to xslString prop of next element -->
    <p-d on=load to=[-xsl-string] val=target.innerHTML m=1></p-d>
    <xtal-salt -xml-string -xsl-string></xtal-salt>
    <div></div>
    <style>
            .header .left,.header .right{
                font-weight: 800;
            }
            .row{
                display: flex;
                flex-direction: row;
            }
            .left{
                flex:1 50%;
            }
            .right{
                flex:2 50%
            }
        </style>
    <script type="module" src="https://cdn.pika.dev/xtal-salt/0.0.16/"></script>
    <script type="module" src="https://cdn.pika.dev/pass-down"></script>
</div>

Demo 2

What's interesting here is that the XML input is an already parsed HTMLDocument node. We try to pass that parsed node to xtal-salt, so that xtal-salt doesn't need to reparse the "xml". This works for Chrome and Safari, but not Firefox and Edge. For the latter two browsers, the xml is stringified and reparsed.

        <div>
            <ul>
                <li>1</li>
                <li>2</li>
            </ul>
        </div>
        <p-d on="load" to="xtal-salt" prop="xml" val="target.firstElementChild" m="1"></p-d>
        <template>
            <?xml version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

                <xsl:template match="/">
                    <div>
                        <xsl:for-each select="ul/li">
                            <div>const x<xsl:value-of select="."></xsl:value-of> = <xsl:value-of select="."></xsl:value-of>;</div>
                        </xsl:for-each>
                    </div>

                </xsl:template>
            </xsl:stylesheet>
        </template>
        <p-d on="load" to="xtal-salt" prop="xslString" val="target.innerHTML"></p-d>
        <xtal-salt></xtal-salt>
        <div role="target"></div>
    </my-non-existent-element>
    <script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    <script type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/xtal-salt.iife.js"></script>
    <script type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/p-all.iife.js"></script>
</div>

Demo 3 -- Light Children Metamorphosis

Based on CSS-Only Nested Dropdown Navigation (ARIA).

NB: This example works in Chrome and Edge, but not yet Firefox. WIP.

Viewing Your Element

$ npm install
$ npm run serve

or

<script>

Running Tests

WIP