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

@codelaw/rules-html

v0.4.3

Published

codelaw's rules for HTML (SR-RULE-PACKS)

Readme

@codelaw/rules-html · codelaw-rules-html

codelaw's rules for HTML — one of the first-party rule packs (SR-RULE-PACKS). The same files ship on npm as @codelaw/rules-html and on PyPI as codelaw-rules-html.

# codelaw.toml
extends = ["codelaw:html/recommended"]
preview = true   # every rule is `preview` until a corpus run promotes it

Presets

| preset | rules | ported from | |---|---|---| | html/recommended | 64 | html-validate 11.16.4 html-validate:recommended, without its layout rules and without the cosmetic rules its prettier and browser presets switch off (see below) | | html/a11y | 26 | html-validate 11.16.4 html-validate:a11y: every rule it turns on | | html/document | 5 | html-validate 11.16.4 html-validate:document: checks that only make sense for a complete page | | html/conventions | 3 | opt-in: the starter rule html/target-blank-rel, and HTMLHint's inline-style-disabled and inline-script-disabled | | html/security | 5 | the html pack's security rules: subresource integrity, reverse tabnabbing, inline scripts, password autocomplete, meta refresh; codelaw:sec-html/recommended extends it | | html/size | 1 | Size limits for pages and templates, opt-in: a line limit per file | | html/markers | 1 | TODO comments with a ticket (and a date when asked); opt in (SR-CONFIG decision 11a) |

html/a11y is a subset of html/recommended, as upstream; turn it on alone for an accessibility-only check. html/document adds to html/recommended. html/security gathers the pack's five security rules so that codelaw:sec-html/recommended (the security-html pack) can extend it instead of copying them.

Every rule is reimplemented, not vendored: the checks, messages and docs are written fresh, and each rule's ported_from: names the source rule. Every rule is a native: rule, sharing one model of the document (crates/codelaw-native/src/html_dom.rs): tree-sitter-html knows only a few of HTML's implied end tags, so the model rebuilds the element tree the way a browser (and html-validate) does, from the element table in data/.

Fix classes: 10 auto, 11 suggest, 51 manual.

Rules

| rule | fix | ported from | presets | |---|---|---|---| | html/area-alt | manual | html-validate/area-alt | recommended, a11y | | html/aria-hidden-body | suggest | html-validate/aria-hidden-body | recommended, a11y | | html/aria-label-misuse | manual | html-validate/aria-label-misuse | recommended, a11y | | html/attribute-allowed-values | manual | html-validate/attribute-allowed-values, htmlhint/src-not-empty | recommended | | html/attribute-misuse | manual | html-validate/attribute-misuse | recommended | | html/autocomplete-password | manual | html-validate/autocomplete-password | recommended, security | | html/button-type | suggest | html-validate/no-implicit-button-type, htmlhint/button-type-require | recommended, a11y | | html/close-attr | auto | html-validate/close-attr | recommended | | html/close-order | manual | html-validate/close-order, htmlhint/tag-pair | recommended | | html/deprecated | manual | html-validate/deprecated, htmlhint/tag-no-obsolete | recommended | | html/doctype-html | suggest | html-validate/doctype-html, htmlhint/doctype-html5 | recommended | | html/element-name | manual | html-validate/element-name | recommended | | html/element-permitted-content | manual | html-validate/element-permitted-content | recommended | | html/element-permitted-occurrences | manual | html-validate/element-permitted-occurrences | recommended | | html/element-permitted-order | manual | html-validate/element-permitted-order | recommended | | html/element-permitted-parent | manual | html-validate/element-permitted-parent | recommended | | html/element-required-ancestor | manual | html-validate/element-required-ancestor | recommended | | html/element-required-attributes | manual | html-validate/element-required-attributes, htmlhint/html-lang-require | recommended | | html/element-required-content | manual | html-validate/element-required-content, htmlhint/title-require | recommended | | html/empty-heading | manual | html-validate/empty-heading | recommended, a11y | | html/empty-title | manual | html-validate/empty-title | recommended, a11y | | html/fieldset-legend | manual | html-validate/wcag/h71 | recommended, a11y | | html/form-dup-name | manual | html-validate/form-dup-name | recommended | | html/form-submit | manual | html-validate/wcag/h32 | recommended, a11y | | html/hidden-focusable | manual | html-validate/hidden-focusable | recommended, a11y | | html/img-alt | manual | html-validate/wcag/h37, htmlhint/alt-require | recommended, a11y | | html/img-title | manual | html-validate/wcag/h67 | recommended, a11y | | html/input-attributes | suggest | html-validate/input-attributes | recommended | | html/input-image-alt | manual | html-validate/wcag/h36 | recommended, a11y | | html/link-text | manual | html-validate/wcag/h30 | recommended, a11y | | html/long-title | manual | html-validate/long-title | recommended | | html/map-dup-name | manual | html-validate/map-dup-name | recommended | | html/map-id-name | manual | html-validate/map-id-name | recommended | | html/meta-refresh | manual | html-validate/meta-refresh | recommended, a11y, security | | html/multiple-labeled-controls | manual | html-validate/multiple-labeled-controls | recommended, a11y | | html/no-abstract-role | manual | html-validate/no-abstract-role | recommended, a11y | | html/no-autoplay | suggest | html-validate/no-autoplay | recommended, a11y | | html/no-conditional-comment | manual | html-validate/no-conditional-comment | recommended | | html/no-deprecated-attr | manual | html-validate/no-deprecated-attr | recommended | | html/no-dup-attr | auto | html-validate/no-dup-attr, htmlhint/attr-no-duplication | recommended | | html/no-dup-class | auto | html-validate/no-dup-class | recommended | | html/no-duplicate-id | manual | html-validate/no-dup-id, htmlhint/id-unique | recommended, a11y | | html/no-implicit-close | suggest | html-validate/no-implicit-close | recommended | | html/no-implicit-input-type | suggest | html-validate/no-implicit-input-type | recommended | | html/no-multiple-main | manual | html-validate/no-multiple-main | recommended | | html/no-utf8-bom | manual | html-validate/no-utf8-bom | recommended | | html/no-raw-characters | auto | html-validate/no-raw-characters, htmlhint/spec-char-escape | recommended | | html/no-redundant-aria-label | auto | html-validate/no-redundant-aria-label | recommended, a11y | | html/no-redundant-for | auto | html-validate/no-redundant-for | recommended, a11y | | html/no-redundant-role | auto | html-validate/no-redundant-role | recommended, a11y | | html/prefer-button | manual | html-validate/prefer-button | recommended | | html/prefer-native-element | manual | html-validate/prefer-native-element | recommended, a11y | | html/prefer-tbody | auto | html-validate/prefer-tbody | recommended | | html/script-element | suggest | html-validate/script-element | recommended | | html/script-type | auto | html-validate/script-type | recommended | | html/tel-non-breaking | suggest | html-validate/tel-non-breaking | recommended | | html/text-content | manual | html-validate/text-content | recommended, a11y | | html/th-scope | manual | html-validate/wcag/h63 | recommended, a11y | | html/unique-landmark | manual | html-validate/unique-landmark | recommended, a11y | | html/unrecognized-char-ref | manual | html-validate/unrecognized-char-ref | recommended | | html/valid-autocomplete | manual | html-validate/valid-autocomplete | recommended, a11y | | html/valid-for | manual | html-validate/valid-for | recommended | | html/valid-id | manual | html-validate/valid-id | recommended | | html/void-content | suggest | html-validate/void-content | recommended | | html/heading-level | manual | html-validate/heading-level | document | | html/input-missing-label | manual | html-validate/input-missing-label, htmlhint/input-requires-label | document | | html/missing-doctype | suggest | html-validate/missing-doctype | document | | html/no-missing-references | manual | html-validate/no-missing-references | document | | html/require-sri | manual | html-validate/require-sri | document, security | | html/target-blank-rel | auto | — (starter rule) | conventions, security | | html/no-inline-style | manual | html-validate/no-inline-style, htmlhint/inline-style-disabled | conventions | | html/no-inline-script | manual | htmlhint/inline-script-disabled | conventions, security |

The four starter-catalogue rules (SR-RULE-PACKS decision 8): html/img-alt (↔ wcag/h37), html/no-duplicate-id (↔ no-dup-id) and html/button-type (↔ no-implicit-button-type) match html-validate rules and sit in html/recommended; html/target-blank-rel matches none and forms html/conventions. The other ported rules keep html-validate's names, except its WCAG technique rules, which are named for what they check (wcag/h30 → html/link-text, h32 → form-submit, h36 → input-image-alt, h63 → th-scope, h67 → img-title, h71 → fieldset-legend).

Not ported, and why

| upstream rule | why | |---|---| | html-validate attr-case, element-case | never: layout — case-only style belongs to the formatter | | html-validate attr-delimiter, attr-spacing, no-trailing-whitespace | never: layout — whitespace belongs to the formatter | | html-validate attr-quotes, doctype-style | never: layout — quoting and the doctype's case belong to the formatter (also switched off by its prettier preset) | | html-validate attribute-boolean-style, attribute-empty-style, void-style, no-self-closing | never: cosmetic — how disabled, alt="" and void tags are spelled is the formatter's call (switched off by its browser and prettier presets) | | html-validate deprecated-rule, no-unused-disable | about html-validate's own configuration and inline directives; codelaw reports its own | | html-validate svg-focusable | switched off in every upstream preset (it only matters for Internet Explorer) | | html-validate no-inline-style in recommended | moved to the opt-in html/conventions: its browser preset switches it off, and it is a style policy, not a correctness check | | HTMLHint attr-lowercase, tagname-lowercase, attr-value-double-quotes, attr-value-single-quotes, attr-whitespace, attr-no-unnecessary-whitespace, space-tab-mixed-disabled, tag-self-close, empty-tag-not-self-closed, attr-sorted | never: layout | | HTMLHint head-script-disabled, script-disabled, style-disabled, id-class-ad-disabled, id-class-value, href-abs-or-rel, attr-unsafe-chars, attr-value-not-empty, attr-value-no-duplication, tagname-specialchars, tags-check | house policy without a correctness reason, or covered by a ported rule (tags-check by the content-model rules, tagname-specialchars by html/element-name) | | HTMLHint h1-require, main-require, meta-charset-require, meta-description-require, meta-viewport-require, link-rel-canonical-require, frame-title-require, form-method-require | page-level SEO or policy checks html-validate's presets don't have; candidates for a later html/strict |

How the ports differ

| rule | difference | |---|---| | all | the document model is rebuilt from tree-sitter-html's tokens with html-validate's implied-end-tag and implied-element rules; markup tree-sitter can't parse at all (a raw < in text) is treated as text | | all | attribute values holding template code ({{ }}, <% %>, ${ }, {% %}) are treated as unknown and not checked, as html-validate does for its framework transforms | | html/element-permitted-content | obsolete elements are left to html/deprecated instead of being reported again wherever they appear | | html/close-order | reports unclosed elements and stray end tags; html-validate also reports the end tag that closed past them, which repeats the first finding | | html/missing-doctype | only files with an <html> element are checked; fragments and partials are not documents | | html/no-implicit-close | the suggest fix writes the end tag after the element's last content | | html/prefer-tbody | the fix wraps the rows when they are next to each other; otherwise the rule only reports | | html/heading-level | sectioning roots are matched by tag or [attr="value"] selectors only | | html/require-sri | no include/exclude URL options yet | | html/no-utf8-bom | manual: the mark is in the file's bytes, outside the text a fix edits; only the file itself is checked, not an HTML region of another file |

Data

| table | source | |---|---| | data/html/elements.json | html-validate 11.16.4's html5 element metadata (MIT): content categories, content models, permitted parents and order, required and deprecated attributes, attribute value enumerations, implied end tags, ARIA implicit roles. Its JavaScript callbacks are rewritten as JSON conditions ({"attr": "href"}, {"ancestor": ["map"]}, {"if": …, "then": …, "else": …}) that html_dom.rs evaluates. | | data/html/entities.json | the named character references html-validate 11.16.4 ships (MIT), following the WHATWG table | | data/html/input-attributes.json | which <input> types each attribute applies to, from html-validate 11.16.4's input-attributes rule (MIT) |

See NOTICE.

Upstream versions

  • html-validate 11.16.4 (MIT) — presets recommended, a11y, document, prettier, browser; rule docs at https://html-validate.org/rules/.
  • HTMLHint 1.9.2 (MIT) — cross-checked for rules html-validate lacks.