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

@snutsjs/core

v1.2.3

Published

AST-based test smell detection core for JavaScript and TypeScript projects.

Readme

@snutsjs/core

License: GPL v3

🎯 Goal

@snutsjs/core aims to be a robust and extensible static analysis tool designed to identify and report common "smells" or anti-patterns in JavaScript and TypeScript test files. By integrating with your development workflow, it helps maintain high-quality, readable, and effective test suites.

📦 Installation

npm install @snutsjs/core

🚀 Library Usage (Extension-Friendly)

import { DetectorRunner, detectors } from "@snutsjs/core";

const detectorInstances = Object.values(detectors).map((DetectorClass) => new DetectorClass());
const runner = new DetectorRunner(detectorInstances);

const smells = await runner.run("/absolute/path/to/example.test.ts");
console.log(smells);

👀 Runtime Watcher Entry

Use the runtime subpath when you want the side-effectful watcher behavior:

import "@snutsjs/core/runtime/watch";

The root package import is side-effect free and safe for VS Code extension integration.

CLI Usage

npx @snutsjs/core watch .

You can also point to a specific directory:

npx @snutsjs/core watch src

📁 Project Structure

├── lib/
│   ├── ast/                # AST (Abstract Syntax Tree) related services for parsing and querying
│   │   ├── ast.service.test.ts
│   │   └── ast.service.ts
│   ├── core/               # Core logic for detector runner and file watching
│   │   ├── detector.interface.ts
│   │   ├── detector-runner.test.ts
│   │   ├── detector-runner.ts
│   │   ├── watcher.test.ts
│   │   └── watcher.ts
│   ├── detectors/          # Collection of predefined test smell detectors
│   │   ├── anonymousTestLogic.ts
│   │   ├── anonymousTestLogic.test.ts
│   │   ├── commentsOnlyTestLogic.test.ts
│   │   ├── commentsOnlyTestLogic.ts
│   │   ├── conditionalTestLogic.test.ts
│   │   ├── conditionalTestLogic.ts
│   │   ├── identicalDescriptionTestLogic.test.ts
│   │   ├── identicalDescriptionTestLogic.ts
│   │   ├── index.ts
│   │   ├── overcommentedTestLogic.test.ts
│   │   └── overcommentedTestLogic.ts
│   ├── runtime/
│   │   └── watch.ts
│   ├── shared/             # Shared utilities, constants, and plugins
│   │   ├── aliases/        # Module aliases configuration
│   │   │   └── index.ts
│   │   ├── constants.ts
│   │   ├── logger/         # Logging utility
│   │   │   └── index.ts
│   │   └── plugins/        # Plugin system for extensibility
│   │       └── index.ts
│   ├── test/               # Internal testing utilities and builders
│   │   └── builders/
│   │       └── astNodeBuilder.ts
│   └── index.ts            # Main entry point for the library
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── eslint.config.js
├── jest.config.js
├── LICENSE
├── package.json
├── README.md
├── tsconfig.json
├── tsconfig.test.json
└── yarn.lock

License

This project is licensed under the GPL-3.0 License. See the LICENSE file for details.


✨ Features

  • 🔧 Static Analysis: Identifies anti-patterns in test files using AST parsing.
  • 💬 Extensible Detectors: Easily add new test smell detection logic.
  • 🛠️ Real-time File Watching: Monitors your codebase for changes and re-runs detectors automatically.
  • 🧪 Jest Testing: Integrated testing setup for robust development.
  • 💡 TypeScript Support: Built with TypeScript for type safety and improved developer experience.
  • 🚀 CLI Tool: Command-line interface for easy interaction.

🔌 Core Libraries

⚛️ Core

  • TypeScript: Primary language for the project.
  • @babel/parser: Used for parsing JavaScript/TypeScript code into an AST.
  • @babel/types: Utilities for working with Babel AST nodes.
  • esquery: Powerful tool for querying ASTs with CSS-like selectors.
  • chokidar: File system watcher for real-time monitoring of file changes.
  • commander: Node.js command-line interfaces made easy.

🧪 Testing

  • Jest: JavaScript testing framework.
  • ts-jest: TypeScript preprocessor for Jest.

🚀 Getting Started

🔧 Prerequisites

To run this project, you will need:

▶️ Run Project

  1. Clone this repository to your local machine.

  2. Install the project dependencies:

    yarn install
  3. To start watching your files for smelly tests, run:

    yarn start

    @snutsjs/core will automatically watch all files in the selected directory and its subdirectories and report findings.

📚 Build and Validate

yarn lint
yarn test
yarn typecheck
yarn build
npm pack --dry-run

🧾 Release Automation (Changesets)

Create a changeset:

yarn changeset

Version packages and changelog:

yarn version-packages

Publish to npm:

yarn release

GitHub Actions workflows are configured to run CI on pull requests and publish through Changesets on merges to main.


🧑‍💻 Contributing

Want to contribute? Here's how you can help:

  1. Create a new branch for your changes:
    git checkout -b feature/your-feature-name
  2. Implement your changes and commit them with a meaningful message (e.g., :sparkles: feat: Your message here):
    git commit -m "feat: Add new detector for unused imports"
  3. Push your branch to the remote repository:
    git push origin feature/your-feature-name
  4. Open a pull request and request a code review.

🔁 Git Workflow

Common Commands:

  • Create a new branch:
    git checkout -b your-branch-name
  • Switch to a branch:
    git checkout branch-name
  • Commit your changes:
    git commit -m "Your commit message"
  • Push changes to remote:
    git push
  • Pull updates from remote:
    git pull

📚 Development Setup

🧭 Path Aliases

This project uses path aliases for cleaner imports. Instead of relative paths like ../../../shared/constants, you can use:

// Before
import { MY_CONSTANT } from "../../../shared/constants";

// After
import { MY_CONSTANT } from "@/shared/constants";

Path aliases are configured in:

  • tsconfig.json - For TypeScript resolution
  • babel.config.js - For Babel transpilation (if applicable)
  • jest.config.js - For testing with Jest

🧪 Troubleshooting

TypeScript and Aliases Issues

If VS Code or Jest doesn't recognize path aliases:

  • Restart TypeScript server: Ctrl+Shift+P → "TypeScript: Restart TS Server"
  • Ensure tsconfig.json has correct baseUrl and paths configurations.
  • Run yarn tsc --noEmit to verify TypeScript configuration.

File Watcher Issues

If the file watcher (chokidar) doesn't seem to be picking up changes:

  • Ensure you are running yarn start from the project's root directory.
  • Check for any system-level file watch limits (e.g., fs.inotify.max_user_watches on Linux) that might be preventing chokidar from functioning correctly in large projects.