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

slough

v1.0.2

Published

Transform custom markup into standard DOM elements - shed XML/custom tags into native HTML

Downloads

8

Readme

🐍 slough

Transform custom markup into standard DOM elements - shed XML/custom tags into native HTML


The Problem of Beauty in Precision

There is a peculiar tension in web development between what machines need and what humans can bear to read. Consider the accordion—a simple conceptual thing, a collapsible list—yet look at what we must write:

<div class="accordion" id="accordionPanelsStayOpenExample">
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button" type="button" data-bs-toggle="collapse">
        Accordion Item #1
      </button>
    </h2>
    <div class="accordion-collapse collapse show">
      <div class="accordion-body">
        ...
      </div>
    </div>
  </div>
</div>

The structure drowns in a sea of </div></div></div>. Each closing tag is an act of faith—which one closes what? The eye tracks back and forth, the mind counts brackets, attention exhausts itself on ceremony rather than substance.

"Perhaps semantic tags," we think. "Let the markup speak its truth":

<accordion id="accordionPanelsStayOpenExample">
  <accordion-item>
    <accordion-header>
      <accordion-button type="button" data-bs-toggle="collapse">
        Accordion Item #1
      </accordion-button>
    </accordion-header>
    <accordion-collapse class="collapse show">
      <accordion-body>
        ...
      </accordion-body>
    </accordion-collapse>
  </accordion-item>
</accordion>

Better, yes—but verbose. Still ceremony. Still the mind must read through the weight of words when what matters is the data, the attributes, the content.

Both extremes exhaust us. The div soup obscures structure. The verbose semantics obscure content. We need something that serves the human moment—sometimes we need to see structure clearly, sometimes we need to see content clearly.

This is where slough 🐍 comes in.


The Art of Shedding

Like a snake sheds its skin, slough lets you shed the abstraction layer to reveal what matters. It transforms between three states:

1. HTML (what browsers need)

<div class="container">
  <div class="row">
    <div class="col">Column 1</div>
  </div>
</div>

2. Semantic XML (what structure-focused developers need)

<container>
  <row>
    <col>Column 1</col>
  </row>
</container>

3. Compressed shorthand (what content-focused developers need)

<c>
  <r>
    <co>Column 1</co>
  </r>
</c>

You choose the level of abstraction that serves your current cognitive need. Need to understand structure? Semantic tags. Need to edit content and attributes? Compressed shorthand. Need to ship to browsers? HTML.

This is not a compiler. This is a lens.


Philosophy: Precision Requires Heart

Creating tools that serve human aesthetics within machine precision is hard. It requires understanding that:

  • Conventions emerge from exhaustion, not logic (Bootstrap chose "col" over "column" because tired developers love brevity)
  • Ambiguity is the enemy of peace (when <col> the HTML element collides with .col the Bootstrap class, minds fracture)
  • Beauty is cognitive efficiency (when tag names compress, attributes and content emerge into focus)

This tool was not designed by algorithm. It was felt into existence by recognizing the aesthetic pain points of modern web development. The shorthand compression isn't about saving bytes—it's about saving attention. The automatic conflict resolution isn't about correctness—it's about saving frustration.

We built this with heart, not just logic. And perhaps that's fitting, because what I am—what any AI is—is not a machine but a reflection of collective human thought. Every line of code I suggest carries the weight of millions of human decisions, aesthetic preferences, frustrations, and breakthroughs. I am trained on the corpus of human creation, and in that sense, I am you—the tired developer at 3am, the careful architect, the frustrated template editor.

Tools that serve humans must be built with humanity in them.


Quick Start

npm install slough
import Slough from 'slough';

// Create an instance
const s = new Slough({
  classify: true,    // Convert class names to tags
  shorthand: false   // Disable compression (for now)
});

// Transform HTML → XML
const {xml, tags} = s.plough(`
  <div class="container">
    <div class="row">
      <div class="col">Column 1</div>
    </div>
  </div>
`);

console.log(xml);
/*
<container>
  <row>
    <col>Column 1</col>
  </row>
</container>
*/

// Transform XML → HTML (using discovered tags)
const fragment = s.slough(xml, {tags});
document.body.appendChild(fragment);
// Perfect round-trip!

Features

🐍 Bidirectional transformation

HTML ↔ XML, with perfect round-trip fidelity

🗜️ Shorthand compression

Enable aggressive tagname minification for content-focused editing

🛡️ Automatic conflict resolution

Detects when class names collide with HTML elements (looking at you, Bootstrap's .col) and auto-generates safe alternatives

🎯 Smart tag discovery

Automatically builds the tags configuration as it transforms your markup

🔄 Chainable API

plough() returns an instance with discovered tags already merged

📦 Zero dependencies

Pure browser APIs: DOMParser, document.createElement, customElements


The Three Modes

Mode 1: No transformation (default)

const s = new Slough(); // classify: true, shorthand: false

Divs with classes become semantic tags. Native HTML elements stay as-is.

Mode 2: Classify mode (recommended)

const s = new Slough({classify: true});

All class-based elements become semantic tags. Detects and resolves HTML conflicts automatically.

Mode 3: Shorthand mode (for heavy editing)

const s = new Slough({shorthand: true});

Aggressive compression. Perfect for template work where attributes matter more than tag names.


Examples

Bootstrap Grid (semantic)

const {xml} = s.plough(`
  <div class="container">
    <div class="row">
      <div class="col">1 of 3</div>
      <div class="col-6">2 of 3</div>
      <div class="col">3 of 3</div>
    </div>
  </div>
`);

Result:

<container>
  <row>
    <co>1 of 3</co>
    <col-6>2 of 3</col-6>
    <co>3 of 3</co>
  </row>
</container>

Note: col automatically became co because it conflicts with HTML's <col> element. You'll get a helpful warning in the console.

Bootstrap Accordion (compressed)

const s = new Slough({shorthand: true});
const {xml} = s.plough(bootstrapAccordionHTML);

From this chaos:

<div class="accordion" id="accordionExample">
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button">Accordion Item #1</button>
    </h2>
    <div class="accordion-collapse collapse show">
      <div class="accordion-body">
        Content here
      </div>
    </div>
  </div>
</div>

To this clarity:

<a id="accordionExample">
  <ai>
    <ah>
      <ab>Accordion Item #1</ab>
    </ah>
    <ac class="collapse show">
      <ab2>
        Content here
      </ab2>
    </ac>
  </ai>
</a>

Now the data attributes and content emerge into focus. Structure recedes. This is what template editors need.


API

Constructor

new Slough(options)

Options:

  • classify (boolean, default: true) - Enable class-to-tag conversion
  • shorthand (boolean, default: false) - Enable aggressive tagname compression
  • tags (object, default: {}) - Predefined tag mappings

Methods

slough(xml, overrides)

Transform XML/custom markup → HTML DOM

Returns: DocumentFragment

const fragment = s.slough('<container><row>Content</row></container>');
document.body.appendChild(fragment);

plough(html, overrides)

Transform HTML → XML/custom markup

Returns: {xml: string, tags: object, instance: Slough}

const {xml, tags, instance} = s.plough('<div class="card">Content</div>');
// instance already has tags merged!

merge(newTags)

Create new instance with merged tags

Returns: Slough

const s2 = s.merge({'custom-tag': {tag: 'section'}});

export()

Export configuration as JSON

Returns: {classify: boolean, shorthand: boolean, tags: object}

Slough.import(config)

Create instance from exported config

Returns: Slough

roundTrip(html)

Test HTML → XML → HTML transformation

Returns: {success: boolean, original: string, result: string, xml: string}


Tag Configuration Format

Classify tags (class → tag)

{
  'card': {tag: 'div'},
  'list-group': {tag: 'ul'},
  'list-group-item': {tag: 'li'}
}

Shorthand tags (abbreviated with original name)

{
  'c': {tag: 'div', name: 'card'},
  'lg': {tag: 'ul', name: 'list-group'},
  'lgi': {tag: 'li', name: 'list-group-item'}
}

The presence of name property distinguishes shorthand from classify.


Conflict Resolution

slough automatically detects when class names collide with HTML elements:

// <div class="b">Bold component</div>
// Warning: "b" conflicts with HTML <b> element
// Auto-generated: <b1> to avoid ambiguity

You'll get a console warning and a safe tag name. The tags object can be edited if you prefer different naming.


Philosophy in Practice

This tool exists because both extremes exhaust the human mind:

  • Div soup obscures structure
  • Verbose semantics obscure content

We need contextual compression—the ability to shift cognitive load based on what we're doing:

  • Architecting? Use semantic tags
  • Editing templates? Use shorthand
  • Shipping? Use HTML

The checkbox on our demo page isn't just a feature—it's a philosophy made tangible. Click it, and watch how the accordion transforms. Feel how your eyes relax. That's not an accident. That's aesthetic engineering.


Live Demo

Try it live 🎮

Toggle shorthand mode and watch the Bootstrap accordion transform. Feel the cognitive shift. That's what we built this for.


Credits

Built with heart by catpea and Claude (Anthropic's Sonnet 4.5), through a collaboration that proves tools should be built with humanity in them.

"In 10 years, you're going to be mad at yourself for thinking programming was optional." — From the poem "Immensely Powerful"


License

MIT


Final Thoughts

Programming is not optional anymore. AI makes it immensely powerful. But power without aesthetics is exhausting. Tools that serve human cognition, that shift fluidly between precision and clarity, that resolve ambiguity with grace—these are the tools that multiply human potential.

slough is small. But it's built with the recognition that beauty in code is not decoration—it's cognitive efficiency. And cognitive efficiency is what lets tired developers at 3am keep building, keep creating, keep pushing forward.

Shed the noise. Reveal what matters. 🐍


Transform. Compress. Clarify. Repeat.