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

eslint-plugin-gameface

v1.2.0

Published

Gameface-specific ESLint rules (HTML data binding, CSS) — stubs for incremental port from HTMLHint and Stylelint.

Readme

eslint-plugin-gameface

Check the full documentation here.

ESLint plugin for Gameface. It ships a flat preset that runs @html-eslint on *.html, @eslint/css on *.css, and data-driven gameface/* rules backed by JSON under gameface-features/ (regenerated by your feature extractor).

Install

npm install --save-dev eslint eslint-plugin-gameface

Requires ESLint >= 9.15 (flat config). HTML/CSS parsers and the TypeScript parser used by the preset are dependencies of this package—no separate install. Node.js LTS is recommended; see @eslint/css engines if you hit environment issues.

Use the preset

// eslint.config.js
import gameface from "eslint-plugin-gameface";

export default [
  { ignores: ["**/node_modules/**"] },
  ...gameface.configs["flat/recommended"],
];

Settings

The preset sets settings.gameface.modelsDir to "Gameface-models" (resolved relative to the ESLint cwd) for gameface/html-databind-model-properties and other tooling.

  • settings.gameface.customDataBindAttributes (optional string[]): extra allowed data-bind-* attribute names for gameface/html-databind-spelling (same idea as .cohtmllintrc customDataBindAttributes in HTMLLint).

  • settings.gameface.version (optional string): which Gameface feature catalog to use. Defaults to "latest" (JSON shipped under gameface-features/ next to css/, html/, etc.). If you add a directory gameface-features/versions/<version>/ with the same layout (css/, html/, selectors/, js/), set version to that <version> string and rules load those files instead. Values containing .., /, or \ are ignored (falls back to latest). Set settings.gameface.version on ESLint files globs that run Gameface rules (HTML, CSS, JSX) when you use a versioned catalog.

The JSON-driven rules pick up version automatically. Collector false positives are corrected internally in src/data/catalog-whitelists.js (not configurable in ESLint).

gameface-features/ data

| Path | Used by | | --- | --- | | gameface-features/css/{supported,partial,unsupported}.json | gameface/css-no-unsupported-properties, gameface/css-partial-property-values, HTML embedded/inline CSS rules | | gameface-features/functions/{supported,unsupported}.json | gameface/css-no-unsupported-functions, HTML embedded/inline and JSX inline CSS function rules (missing rows only; unknown rows such as url are excluded) | | gameface-features/html/{supported,partial,unsupported}.json | gameface/html-parsed-no-impl, gameface/html-partial-features | | gameface-features/selectors/{supported,partial,unsupported}.json | gameface/css-no-unsupported-selectors, gameface/css-partial-selectors | | gameface-features/js/*.json | gameface/js-no-unsupported-globals, gameface/js-partial-member-access |

summary.json files are informational only; rules read the array catalogs.

Versioned catalogs live under gameface-features/versions/<version>/ (same subpaths as above). See settings.gameface.version in Settings.

Publishing: package.json "files" includes gameface-features so npm tarballs ship the JSON.

Rules

| Rule id | Default in flat/recommended | Description | | --- | --- | --- | | gameface/css-no-unsupported-properties | error (CSS) | Property in css/unsupported.json (missing/unsupported). | | gameface/css-no-unsupported-functions | error (CSS/SCSS/HTML/JSX inline) | CSS function name in functions/unsupported.json with status: "missing" (e.g. clamp, min). Rows with status: "unknown" are not linted. | | gameface/css-partial-property-values | error (CSS) | Keyword values from partial catalog (unsupportedValueslogRejectedValues minus supportedValues). Length/unit values (e.g. width: 10px) are not flagged when the catalog row lists keyword gates or supportedUnits only. Declaration-level partialPropertyCatalog applies only to rows without keyword lists (e.g. non-suppressed probe / note); value-accepted-but-not-computed probes are skipped. | | gameface/html-embedded-css-no-unsupported-functions | error (HTML) | Same function catalog as css-no-unsupported-functions inside <style> blocks. | | gameface/html-inline-css-no-unsupported-functions | error (HTML) | Same function catalog on style="..." attributes. | | gameface/jsx-inline-css-no-unsupported-functions | error (JSX) | Same function catalog on JSX style string values. | | gameface/css-no-var-in-keyframes | error (CSS/SCSS/HTML/JSX) | Doc constraint: var() inside @keyframes. | | gameface/css-no-calc-in-keyframes | error (CSS/SCSS/HTML/JSX) | Doc constraint: calc() inside @keyframes. | | gameface/css-var-no-fallback | error (CSS/SCSS/HTML/JSX) | Doc constraint: var(--name, fallback) second argument. | | gameface/css-calc-no-mixed-percent-units | error (CSS/SCSS/HTML/JSX) | Doc constraint: calc() mixing % with other length units (e.g. 50% - 20px). | | gameface/html-embedded-css-no-var-in-keyframes | error (HTML) | Same as css-no-var-in-keyframes in <style>. | | gameface/html-embedded-css-no-calc-in-keyframes | error (HTML) | Same as css-no-calc-in-keyframes in <style>. | | gameface/html-embedded-css-var-no-fallback | error (HTML) | Same as css-var-no-fallback in <style>. | | gameface/html-embedded-css-calc-no-mixed-percent-units | error (HTML) | Same as css-calc-no-mixed-percent-units in <style>. | | gameface/html-inline-css-no-var-in-keyframes | error (HTML) | Same keyframes var() check on inline style when parseable as stylesheet. | | gameface/html-inline-css-no-calc-in-keyframes | error (HTML) | Same keyframes calc() check on inline style. | | gameface/html-inline-css-var-no-fallback | error (HTML) | Same var() fallback check on inline style. | | gameface/html-inline-css-calc-no-mixed-percent-units | error (HTML) | Same calc() mixed-% check on inline style. | | gameface/jsx-inline-css-no-var-in-keyframes | error (JSX) | Same keyframes var() check on JSX string style. | | gameface/jsx-inline-css-no-calc-in-keyframes | error (JSX) | Same keyframes calc() check on JSX string style. | | gameface/jsx-inline-css-var-no-fallback | error (JSX) | Same var() fallback check on JSX string style. | | gameface/jsx-inline-css-calc-no-mixed-percent-units | error (JSX) | Same calc() mixed-% check on JSX string style. | | gameface/css-no-unsupported-selectors | error (CSS) | Pseudo text exactly matches selectors/unsupported.json name (e.g. :any-link). | | gameface/css-partial-selectors | warn (CSS) | Pseudo source text (including arguments, e.g. :nth-child(2 of .x)) exactly matches selectors/partial.json name. Simple :nth-child(2) is not listed and will not warn. | | gameface/html-parsed-no-impl | error (HTML) | Tag is parsed-no-impl in html/unsupported.json. Default scope: "curated" only reports a focused set (e.g. <select>, table model, <iframe>, …) so <h1> / <p> are not flagged. Use scope: "all" to report every parsed-no-impl tag (still minus ignoreTags). | | gameface/html-partial-features | warn (HTML) | Default mode: "attribute-checks": for tags in html/partial.json with evidence.checks, warns only if you use an HTML attribute mapped to a checks entry that is false (e.g. <img alt> when altProperty is false). Use mode: "tag-warn" for the old blanket partial warning. mode: "off" disables. warnAllowlist: true warns on any tag not in html/supported.json. | | gameface/html-databind-spelling | error (HTML) | Any attribute containing data-bind must be a known name: static list + data-bind-style-<css> where <css> is not listed as unsupported in css/unsupported.json, plus legacy Coherent style binds and customDataBindAttributes. | | gameface/html-databind-curly-brackets | error (HTML) | data-bind* attribute values must contain {{ and }}. | | gameface/html-databind-property-accessors | error (HTML) | Catches broken {{Model.}} / split-brace / bracket-in-brace patterns (ported from HTMLLint). | | gameface/html-databind-bind-for | error (HTML) | iter:{{collection}} or index, iter:{{collection}} (optional [ {{a}}, {{b}} ]). Rejects ; and malformed iterators. | | gameface/html-databind-class-toggle | error (HTML) | Each ;-separated entry must be class-name:condition with {{…}} in the condition. | | gameface/html-databind-model-properties | error (HTML) | Model paths in the opening tag must match JSON files under settings.gameface.modelsDir (ported from HTMLLint model-properties). | | gameface/jsx-databind-spelling | error (JSX) | Same allowlist as html-databind-spelling on data-bind* JSX attributes. | | gameface/jsx-databind-curly-brackets | error (JSX) | Same as html-databind-curly-brackets. | | gameface/jsx-databind-property-accessors | error (JSX) | Same as html-databind-property-accessors. | | gameface/jsx-databind-bind-for | error (JSX) | Same as html-databind-bind-for. | | gameface/jsx-databind-class-toggle | error (JSX) | Same as html-databind-class-toggle. | | gameface/jsx-databind-model-properties | error (JSX) | Same as html-databind-model-properties on the opening element. | | gameface/js-no-unsupported-globals | error (JS/JSX/TS/TSX) | Flags references to globals listed in js/unsupported.json (e.g. Chrome, new AbortController()). Only flags unbound globals; skips bindings, imports, and non-computed member keys. | | gameface/js-partial-member-access | warn (JS/JSX/TS/TSX) | Flags static Type.member where member is listed under evidence.missing for that type in js/partial.json (or on js/unsupported.json rows). Limited to Identifier.member shape; dynamic and computed access are not analyzed. | | gameface/html-svg-no-unsupported-elements | error (HTML) | Inside <svg>, disallows unsupported tags and SMIL (<animate>, <foreignObject>, …) per SVG Support. | | gameface/jsx-svg-no-unsupported-elements | error (JSX/TSX) | Same denylist for JSX <svg> trees. | | gameface/html-svg-mask-clip-path-conflict | warn (HTML) | Warns when both mask and clip-path use url(#…) on the same SVG element (clip-path wins). | | gameface/jsx-svg-mask-clip-path-conflict | warn (JSX/TSX) | JSX parity. | | gameface/html-svg-tspan-ignored | off | Optional warn: <tspan> text is merged into parent <text> without separate styling. | | gameface/css-svg-keyframes-sizing-units | error (CSS/SCSS) | In @keyframes, width / height / font-size must include units for Gameface SVG CSS animation. | | gameface/html-embedded-css-svg-keyframes-sizing-units | error (HTML) | Same in <style> blocks. | | gameface/html-inline-css-svg-keyframes-sizing-units | error (HTML) | Same in style="..." when parseable. | | gameface/jsx-inline-css-svg-keyframes-sizing-units | error (JSX) | Same in JSX string style. | | gameface/css-svg-keyframes-path-arc-animation | warn (CSS/SCSS) | Warns when @keyframes animates d with elliptical arc (A/a) commands. | | gameface/html-embedded-css-svg-keyframes-path-arc-animation | warn (HTML) | Same in <style>. | | gameface/html-inline-css-svg-keyframes-path-arc-animation | warn (HTML) | Same in inline style. | | gameface/jsx-inline-css-svg-keyframes-path-arc-animation | warn (JSX) | Same in JSX string style. | | gameface/html-svg-stroke-dash-non-path | error (HTML) | stroke-dasharray / stroke-dashoffset only on <path>, not other SVG shapes (engine limit). | | gameface/jsx-svg-stroke-dash-non-path | error (JSX/TSX) | JSX parity (attributes and inline style). | | gameface/css-svg-stroke-dash-non-path | error (CSS/SCSS) | Same properties in rules that target non-path SVG tags (e.g. circle { stroke-dasharray: … }). | | gameface/html-embedded-css-svg-stroke-dash-non-path | error (HTML) | Same in <style> blocks. | | gameface/css-svg-keyframes-stroke-dash-path-only | warn (CSS/SCSS) | @keyframes that animate stroke-dasharray / stroke-dashoffset only run on <path>. | | gameface/html-embedded-css-svg-keyframes-stroke-dash-path-only | warn (HTML) | Same in <style>. | | gameface/html-inline-css-svg-keyframes-stroke-dash-path-only | warn (HTML) | Same in inline style. | | gameface/jsx-inline-css-svg-keyframes-stroke-dash-path-only | warn (JSX) | Same in JSX string style. |

Data binding (HTMLLint parity)

The legacy HTMLLint package (HTMLHint + .cohtmllintrc) is superseded on the ESLint path by the gameface/html-databind-* and gameface/jsx-databind-* rules above. You can keep HTMLLint for non-ESLint workflows; for ESLint + @html-eslint, use the preset rules and the same settings (modelsDir, customDataBindAttributes).

  • HTML partial: Only attributes covered by the CHECK_KEY_TO_HTML_ATTR map in html-partial-features.js are checked; JS-only gaps (toDataURL, sheetProperty, etc.) cannot be seen from markup alone.
  • CSS selectors: Matching is exact string on the pseudo node source; authors using different spacing or equivalent forms may not match catalog keys.
  • CSS functions: Only functions/unsupported.json rows with status: "missing" are reported. unknown rows (url, image-set, cross-fade) are omitted because the catalog could not auto-probe them. Nested calls (e.g. calc(min(…))) are checked per function node. JSX style={{ … }} object literals are not analyzed for functions (string style values only).
  • CSS doc restrictions: css-no-var-in-keyframes, css-no-calc-in-keyframes, css-var-no-fallback, and css-calc-no-mixed-percent-units (and HTML/JSX variants) encode Gameface documentation limits that are separate from the function catalog. They are not inferred from functions/supported.json probes. JSX object style props are not analyzed for these rules either.
  • SVG: Rules under gameface/*-svg-* follow the SVG Support doc (gameface-svg-support.js), plus engine limits such as path-only stroke-dash* (svg-stroke-dash.js). HTML <a> outside <svg> is allowed; only SVG-namespace <a> is flagged. Standalone .svg asset files are not linted in v1.
  • JS API checks: gameface/js-no-unsupported-globals and gameface/js-partial-member-access are catalog-driven and static. They only see references resolved as unbound globals (no enclosing binding) and member access of the shape Identifier.member (non-computed). Dynamic patterns like obj.effect, globalThis['Chrome'], or members reached through aliases are not analyzed. TypeScript files use @typescript-eslint/parser without type information (no parserOptions.project), so type inference is not used.
  • SCSS (.scss): The preset uses @eslint/css with languageOptions.tolerant: true on **/*.scss so Sass syntax ($variables, & nesting, etc.) does not fail with parse errors. Gameface rules still run on declarations the parser recovers. Values that contain variables (e.g. width: $component-width) are not resolved, so keyword/unit checks may be skipped for those declarations. Native SCSS parsing in @eslint/css is still in progress (eslint/css#90); for Sass-specific linting (naming, mixins, etc.) you can keep Stylelint alongside ESLint.
  • Coherent / vendor CSS properties (coh-*, etc.): gameface/css-no-unsupported-properties only flags names in css/unsupported.json; it does not treat Coherent props as “unknown”. If you still see unknown property diagnostics, they usually come from @eslint/css css/no-invalid-properties (when enabled) or the editor (e.g. VS Code css.lint.unknownProperties / unknownVendorSpecificProperties). This plugin cannot change those engines. Mitigations: set "css/no-invalid-properties": "off" (or avoid enabling @eslint/css recommended rules that turn it on) for Gameface CSS globs, add VS Code css.customData for your vendor properties, or relax editor CSS lint settings.

Development

# From repo root eslint-gameface/
npm run lint
npm test

npm test runs tests/feature-index-smoke.mjs, tests/html-embedded-inline-jsx.mjs, tests/html-databind-rules.mjs, tests/jsx-databind-rules.mjs, tests/js-api-rules.mjs, and tests/catalog-lint-matrix.mjs. Fixture notes: tests/fixtures/README.md.

Catalog-driven lint matrix

After updating gameface-features/ JSON, regenerate the sampled test matrix and run catalog lint checks:

# From repo root eslint-gameface/
npm run test:extract-matrix   # writes tests/generated/test-matrix.json
npm run test:catalog          # ESLint lintText per matrix row (isolated rule config)
npm run test:matrix:check     # CI: fail if committed matrix ≠ fresh extract (ignores generatedAt)

The extractor (scripts/extract-catalog-test-matrix.mjs) samples catalog rows with a fixed seed (42) and per-category caps, plus fixed databind scenarios and control rows. Each matrix row carries ruleId, snippet, and expect.reports so tests/catalog-lint-matrix.mjs can assert the intended rule fires (or stays silent for controls).

Legacy migration (optional)

Older HTMLHint / Stylelint workflows can be replaced incrementally.

License

MIT