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

@fulldotdev/check

v0.4.0

Published

Static checks of a built website's files: HTML and accessibility markup, links, assets and fragments, also in Markdown, feeds and web manifests, SEO tags, structured data syntax, sitemap and robots.txt, file sizes and sensitive files.

Readme

@fulldotdev/check

Static checks of a built website. Run it on the output folder after the build; it only reads the files in that folder. It runs none of their code, starts no browser or server and makes no requests.

  • HTML: html-validate with its standard and a11y rules, a nonempty title and the page's lang, a doctype, a label for each form control, and IDs that for, aria-labelledby, aria-describedby and other attributes name. An aria-controls may name what a script mounts, such as a closed dialog.
  • Links: every page and stylesheet, also those no other page links to, against the files in the build: links, images (also srcset), media, scripts, stylesheets, <link>s, meta refreshes, OpenGraph and Twitter URLs, SVG <use> and <image>, and CSS url()s and @imports in stylesheets, <style> and style attributes. Also the links and images of Markdown files and llms.txt, the links of RSS and Atom feeds, and a web manifest's start URL, icons, screenshots and shortcuts. #fragments of pages must name an ID or <a name>. Absolute links to the site's own origin are checked against the build.
  • SEO: each page has a valid lang, one nonempty meta description and one absolute canonical URL. Pages with robots noindex need no description or canonical; redirect pages (a meta refresh to a URL) need neither. A canonical URL of another page is that page's own canonical URL, not a redirect page or one with noindex. JSON-LD is valid JSON and an object or an array of objects, whose @ids are strings, @types strings or arrays of strings, @graphs objects or arrays of objects and @contexts URLs, objects or arrays of them.
  • Sitemap and robots.txt, when the build has them: robots.txt's sitemaps exist, and each sitemap URL is listed once, is a built page without noindex or a redirect, is its own canonical URL and is allowed by robots.txt. A lastmod, when present, is a W3C date no more than a day in the future.
  • Other files: llms.txt starts with an H1 title, a feed is XML and a web manifest a JSON object. Environment and credential files, private keys and version control folders are not in the build, also as dotfiles that hosts do not serve.
  • Other findings: an hreflang that is no language tag or x-default, a built page it points to that does not link back or has another lang, and indexable pages in the same language with the same title or meta description, unless their canonical URL is another page's. An indexable page, other than the homepage, that no other page links to, or that no sitemap lists when the build has one. A linked image over 1 MiB, or script, stylesheet or font over 500 KiB. A <link rel="preload"> without as, or a font's without crossorigin. A .DS_Store.

Install

It needs Node.js 24 or later:

npm install --save-dev @fulldotdev/check

Use

fulldev-check          # checks ./dist
fulldev-check build    # another folder
fulldev-check --json   # the issues as JSON
fulldev-check --fail-on warning # a stricter build threshold

Check and Fulldev Scan share condition defaults from @fulldotdev/check/policy:

  • critical: a missing internal navigation page, exposed credentials or private keys, a homepage with noindex, Googlebot blocked from the homepage, or an HTTP form submission.
  • warning: broken resources, missing titles, descriptions, labels or alt text, invalid SEO metadata, and file size budgets.
  • hint: HTML standard violations without a more specific impact rule, orphan pages, sitemap duplicates and unlisted pages.

Severity describes impact. A service agreement determines which warnings and hints must be handled; it does not change their severity. Critical findings always fail Check. The default threshold is critical; --fail-on warning also blocks warnings, and --fail-on hint blocks all findings. There is no threshold that permits critical findings.

It exits 1 at the selected threshold or when execution fails, 0 below that threshold, and 2 on wrong usage. Missing builds and other execution failures are errors on stderr, outside customer finding counts. Measurement limitations remain visible with limitation: true and do not count as customer defects.

Astro's error, warning and hint diagnostics remain separate source-code checks. Their labels and counts do not describe the same customer impact or coverage.

Version 0.4 changes the public severity values from error | warning to critical | warning | hint, adds condition code and confidence, and changes the default build threshold. Reclassified findings are not fixed defects. Scan groups occurrences and uses live evidence, so its counts can differ even with shared defaults. Its evidence-dependent severity overrides remain in Scan.

--json prints a sorted array of issues:

[
  {
    "rule": "links/broken",
    "code": "broken-pages",
    "severity": "critical",
    "confidence": "confirmed",
    "file": "about/index.html",
    "line": 12,
    "message": "Broken link: /contact/ (not in the build)"
  }
]

file is relative to the folder, line is there when known, and rule starts with html/, links/, seo/, sitemap/, robots/, llms/, feed/, manifest/, perf/, security/ or security/.

From code:

import { checkSite } from "@fulldotdev/check"

const issues = await checkSite({ dist: "dist" })

// Declare only known framework routes. These remain unverified until a live
// check confirms their response; missing static pages are still findings.
const hybridIssues = await checkSite({
  dist: "dist",
  serverRoutes: [/^\/vacancies\/?$/],
})

How it works

A link resolves as in a browser, against the page's URL or its <base href>, and points to the file a static host serves at its path: /about and /about/ find about/index.html and about.html, the query is ignored, percent-encoded characters are decoded, and letter case must match exactly, as on Linux hosts. Dotfiles other than those in .well-known are not served.

A fragment is found as a browser finds it, also percent-decoded; #, #top and text fragments (#:~:text=) need no ID. IDs inside <template> are not the page's.

The site's origin is that of the homepage's canonical URL, or else the one origin of all other canonical URLs.

Markdown is read as CommonMark: its inline, reference and image links count, and its frontmatter, code and HTML do not. Feeds are the files that pages link to as RSS or Atom, .rss and .atom files, and XML files with an RSS or Atom root; their URLs resolve against xml:base, and guids and IDs are not links. Web manifests are the files that pages link to as such and .webmanifest files.

An indexable page has no robots noindex, is no redirect page, is its own canonical URL and is not the 404.html that hosts serve for missing pages. A page links to another with a link, an area, a form or a meta refresh, also in a <template>.

Limits

  • Links to other hosts, HTTP statuses, links that JavaScript creates or handles, rendering, contrast and other computed styles are not checked; Fulldev Scan checks the live site.
  • The site is served from the root of its domain; a site under a subpath, such as https://example.com/docs/, is not supported.
  • Host features such as redirect rules, rewrites, custom headers and server routes are not emulated. The API can declare known serverRoutes as regular expressions; unresolved links to them are unverified measurements. All other missing paths remain findings. Hosted image services also need live verification.
  • Fragments of other files, such as an SVG's or a PDF's, and of redirect pages are not checked.
  • What JSON-LD's types and properties mean, and whether its IDs exist, is not checked.
  • Size budgets are those of the files, not what a browser downloads, which depends on the screen, srcset and compression.
  • Automated checks find part of the accessibility problems, not all.

License

MIT