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

nori-lint

v0.4.0

Published

Lint SKILL.md files for common issues

Readme

nori-lint

An opinionated linter for SKILL.md files — follow best practices, don't configure slop.

npx nori-lint lint /path/to/SKILL.md

Opinionated how?

SKILL.md files are prompt-engineered instructions consumed by LLMs. Most LLMs will write verbose slop skills that do not work. Every wasted word burns context window space in every agent session, degrading agent ability and costing you money.

nori-lint enforces two principles:

  • Token efficiency: Don't waste tokens on things the LLM already knows (redundant explanations, obvious instructions, markdown formatting it doesn't render).
  • Structural discipline: Skills should be concise processes with required checklists, not sprawling reference manuals.

You can disable any rule you disagree with via configuration.

Ecosystem

nori-lint is part of a broader set of tools for building and managing AI agent configurations:

  • Nori Skillsets — Registry and CLI for downloading, publishing, and switching between packaged sets of AI agent skills. Teams can get private registries, which also support automatic skill generation from coding session transcripts.
  • Nori Sessions — Managed agent runtime platform for running AI coding agents in cloud environments with security, persistence, and integrations. Like Stripe or Ramp, but off the shelf and personalized to your org.
  • Nori — Homepage.

If you are struggling to adopt AI or are feeling AI FOMO, get in touch!

Installation

Requires Node.js 20+.

npm install -g nori-lint

Usage

Running nori-lint with no arguments shows help. Use --version to print the version.

Lint

nori-lint lint [path] [options]

Finds all SKILL.md files recursively under [path] (defaults to .) and reports violations. You can also pass a path to a single file.

| Option | Default | Description | |---|---|---| | --format <format> | text | Output format: text or json | | --config <path> | — | Path to config file |

Exit code 0 means no violations. Exit code 1 means violations were found.

Fix

nori-lint fix [path] [options]

Auto-fixes violations in place. Deterministic rules are fixed directly. LLM rule violations are batched into a single API call per file.

Note: When LLM rules are active, the fix command is non-deterministic — running it twice on the same file may produce different results. Static rule fixes are always deterministic.

| Option | Default | Description | |---|---|---| | --config <path> | — | Path to config file | | --dry-run | false | Show what would change without writing |

List

nori-lint list [options]

Lists all available lint rules with their descriptions and fixability.

| Option | Default | Description | |---|---|---| | --format <format> | text | Output format: text or json |

Rules

nori-lint has a two-tier rule system.

Static rules

These run without any API key. They are fast, deterministic, and pattern-based.

| Rule | Fixable | Description | |---|---|---| | bold_italics | Yes | Bold/italic markdown formatting wastes tokens for an LLM reader. | | consecutive_blank_lines | Yes | Multiple consecutive blank lines waste tokens. | | description_action | No | Description must indicate when to use the skill, not what it does. | | frontmatter | No | Valid YAML frontmatter with required fields per the agentskills.io spec. | | frontmatter_name_format | No | Name must be lowercase alphanumeric with hyphens. | | line_count | No | Files must not exceed 150 lines. | | markdown_links | Yes | Use bare URLs instead of [text](url) markdown link syntax. | | redundant_title | Yes | Title headings are redundant — the filename and frontmatter already identify the skill. | | required_tags | No | Every skill must contain at least one <required> block. | | trailing_whitespace | Yes | Trailing whitespace on lines wastes tokens. | | unclosed_tags | No | All opened XML-style tags must have matching closing tags. | | when_to_use | Yes | "When to Use" sections are redundant — this belongs in the description frontmatter field. |

LLM rules

These call the Anthropic API for semantic analysis. They only run when a config file with a valid anthropic_api_key is present.

| Rule | Description | |---|---| | cli_command_index | Flags CLI command reference lists — an LLM already knows these from training data. | | duplicate_section | Flags sections that cover substantially the same ground. | | first_person | The skill author should refer to themselves as "I/me/my", not "the user". | | negative_without_positive | "Don't do X" instructions must pair with a concrete "do Y instead". | | obvious_instructions | Flags generic instructions any LLM already follows ("write clean code", "handle errors"). | | process_not_integration | Skills should be step-by-step workflows, not reference manuals. | | redundant_explanation | Flags explanations of concepts an LLM already knows. | | skill_example_xml_tags | Behavioral examples must use <good_example>/<bad_example> tags. | | linkable_content | Checks that skill files link to external documentation instead of restating it inline. Uses web search to find canonical URLs. | | unexplained_url | URLs must have surrounding context explaining what they link to and why. |

Configuration

Create a .nori-lint.json file in your project root, or pass --config <path>.

{
  "anthropic_api_key": "sk-ant-your-api-key-here",
  "rules": {
    "disabled": ["obvious_instructions", "redundant_explanation"]
  }
}
  • anthropic_api_key — Required for LLM rules. Without it, only static rules run.
  • rules.enabled — Allowlist: only these rules run.
  • rules.disabled — Denylist: all rules except these run.
  • enabled and disabled are mutually exclusive.

The .nori-lint.json file is gitignored by default to avoid committing API keys. See .nori-lint.example.json for a template.