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

@vellora/lint

v0.5.0

Published

Check and auto-fix HTML templates for the vellora HTML-to-PDF renderer, in your editor or CI.

Readme

@vellora/lint

Catch template problems while you write them, not when a customer opens a broken PDF.

npm license: MIT

vellora renders HTML to PDF without a browser, and it supports a documented subset of HTML and CSS. @vellora/lint checks your templates against that subset and rewrites the constructs that have a safe automatic fix. It's meant for your editor, your tests and CI. It never runs on your production render path unless you ask for it.

Install

npm install --save-dev @vellora/lint

Check a template

import { diagnose } from "@vellora/lint";

const report = diagnose(`<table><tr><td style="display:grid">a</td></tr></table>`);

report.conformant; // false
report.findings[0];
// {
//   rule: "flex-grid-in-td",
//   severity: "warning",
//   autoFixable: true,
//   location: { line: 1, col: 12 },
//   suggestedFix: "...",
//   snippet: "...",
//   compatLink: "...",
// }

diagnose(html) only reads. It never changes your HTML, touches the file system or goes to the network, so it's safe to call anywhere.

Fix it automatically

import { fix } from "@vellora/lint";

const { html, report } = fix(template);
// html: the rewritten template. Here the grid cell becomes a nested table,
// which vellora lays out reliably.
// report.findings[i].applied tells you which fixes ran.

The fixes are deterministic. Running fix() on its own output changes nothing, so it's safe to run on every commit.

Use it in CI

Fail the build when a template drifts out of the supported subset:

import { readFileSync } from "node:fs";
import { diagnose } from "@vellora/lint";

for (const file of ["templates/invoice.html", "templates/receipt.html"]) {
  const { conformant, findings } = diagnose(readFileSync(file, "utf8"));
  for (const f of findings) {
    console.log(`${file}:${f.location.line}:${f.location.col} ${f.severity} ${f.rule}`);
  }
  if (!conformant) process.exitCode = 1;
}

Prefer the terminal? @vellora/cli runs the same checks: vellora lint templates/invoice.html (exit code 1 when there are findings) and vellora fix templates/invoice.html --write.

The report format

interface Report {
  conformant: boolean;
  findings: Finding[];
}

interface Finding {
  rule: string; // stable id, e.g. "flex-grid-in-td"
  severity: "error" | "warning";
  autoFixable: boolean;
  location: { line: number; col: number };
  suggestedFix: string; // for humans
  snippet: string; // the offending source
  compatLink: string; // where the rule is documented
  feature?: string; // the strict render's rejection id, e.g. "css:transform"
  applied?: boolean; // set by fix()
}

People read suggestedFix and snippet. Scripts, CI and AI agents should rely on rule, severity, autoFixable, location, compatLink and feature.

feature is set exactly when a strict renderPdf rejects the construct, and it is the same id the VelloraUnsupportedError carries (element:canvas, css:transform, css:grid, …). A finding without it (an inline SVG, display:flex in a cell) renders.

How it relates to rendering

  • renderPdf(html) in vellora is strict by default: it never imports this package and never changes your HTML. Out-of-subset input throws a VelloraUnsupportedError with the line and column.
  • renderPdf(html, data, { strict: false }) loads this package and applies fix() before rendering, for when you'd rather get a PDF than an error.

The linter reports every element and CSS feature the strict render rejects: <script> (script-element), animation (css-animation), undrawn @page margin boxes (page-margin-box), the other denied elements (unsupported-element) and transform, transition, filter, backdrop-filter, perspective and display: grid (unsupported-css), and <link rel="stylesheet"> / @import, which vellora never loads (external-stylesheet). It cannot see rejections that depend on render options (images, fonts), on the @page cascade (css:page-varying-width) or on the engine's nesting limit, so a strict renderPdf per template in CI is still the final check. The full list is in COMPATIBILITY.md.

License

MIT. See LICENSE.