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

@ttwtf/ng-parser

v1.6.0

Published

Advanced Angular parser with RAG-optimized output and extensible visitor architecture

Readme

ng-parser

Advanced Angular parser with RAG-optimized output and extensible visitor architecture.

License: MIT

Features

  • 🔍 Deep Angular Analysis - Components, Services, Modules, Directives, Pipes
  • 🧩 Two-Layer Architecture - Core parsing + Extensible custom visitors
  • 🎯 Modern Angular Support - Standalone components, Signals (Angular 18-20)
  • 📊 Knowledge Graph - Entities, relationships, hierarchical clustering
  • 🎨 Template & Style Analysis - Parse HTML templates and SCSS files with full dependency tracking
  • 🌐 Git Integration - Automatic source URLs for GitHub, GitLab, Bitbucket, Azure DevOps
  • 🎯 Global Styles - Auto-detect and parse global SCSS files (styles.scss, theme.scss, etc.)
  • 🤖 RAG Optimized - JSON outputs optimized for LLM consumption
  • Maintainable - Built on official @angular/compiler-cli
  • 🔌 Extensible - Create custom visitors for your analysis needs
  • 🛡️ Built-in Visitors - RxJS patterns, Security, Performance analysis

Installation

npm install @ttwtf/ng-parser

Peer Dependencies (automatically uses your project's Angular version):

npm install @angular/compiler @angular/compiler-cli @angular/core

Supported versions: Angular 18.x, 19.x, 20.x

Quick Start

CLI (Recommended)

# Parse an Angular project (core parsing only, fastest)
ng-parser parse ./src

# Enable specific visitors
ng-parser parse ./src --visitors rxjs,security

# Export to file
ng-parser parse ./src -o analysis.json

# Export all formats (JSON, SimpleJSON, HTML)
ng-parser parse ./src -f all -o ./output/my-project

See CLI Documentation for complete CLI reference.

Programmatic API

import { NgParser } from '@ttwtf/ng-parser';

const parser = new NgParser({ rootDir: './src' });
const result = await parser.parse();

console.log(`Found ${result.metadata.totalEntities} Angular entities`);
console.log(`Found ${result.metadata.totalRelationships} relationships`);

// Access parsed entities
for (const entity of result.entities.values()) {
  console.log(`[${entity.type}] ${entity.name}`);
}

With Built-in Visitors

import {
  NgParser,
  RxJSPatternVisitor,
  SecurityVisitor,
  PerformanceVisitor
} from '@ttwtf/ng-parser';

const parser = new NgParser({ rootDir: './src' });

// Register pattern extraction visitors
parser.registerVisitor(new RxJSPatternVisitor());
parser.registerVisitor(new SecurityVisitor());
parser.registerVisitor(new PerformanceVisitor());

const result = await parser.parse();

// Access visitor results (raw patterns, not evaluations)
const rxjsResults = result.customAnalysis.get('RxJSPatternVisitor');
console.log(`RxJS observables found: ${rxjsResults.totalObservables}`);
console.log(`In components: ${rxjsResults.observablesInComponents}`);

const securityResults = result.customAnalysis.get('SecurityVisitor');
console.log(`Security patterns found: ${securityResults.totalPatterns}`);
console.log(`By pattern:`, securityResults.byPattern);

Export to Multiple Formats

// JSON export (complete data, optimized)
const json = result.toJSON();

// SimpleJSON export (ng-analyzer compatible)
const simple = result.toSimpleJSON();

// HTML export (interactive D3.js visualization)
const html = result.toHTML();

Two-Layer Architecture

ng-parser uses a strict two-layer separation between parsing and analysis:

Layer 1: Core Angular Parsers (Built-in, Non-Extensible)

Pure extraction of Angular concepts with guaranteed quality:

  • ComponentParser - Standalone, signals, inputs/outputs, lifecycle
  • ServiceParser - Dependency injection, providedIn
  • ModuleParser - Declarations, imports, exports, providers
  • DirectiveParser - Inputs, outputs, standalone
  • PipeParser - Pure/impure, standalone
  • TemplateParser - HTML template analysis (inline & external)
  • StyleParser - SCSS @import and @use extraction
  • GitRemoteParser - Git repository detection and source URL generation

Role: Transform source code → structured data (AST, entities, relationships)

Layer 2: Custom Visitors (Extensible, User-Defined)

Pattern extraction from parsed entities - NO evaluation or recommendations:

  • RxJSPatternVisitor - Extracts Observable/Subject usage and lifecycle hooks
  • SecurityVisitor - Extracts innerHTML, eval(), HTTP URLs, potential secrets
  • PerformanceVisitor - Extracts change detection, trackBy, imports, constructors

Role: Extract additional patterns → structured facts (no judgments)

Important: Visitors perform extraction only. They don't evaluate severity, don't recommend fixes, and don't judge code quality. They simply identify and categorize patterns. Analysis/evaluation tools can be built on top of the extracted data.

Create your own visitors to extract domain-specific patterns!

Built-in Visitors

RxJSPatternVisitor

Extracts RxJS usage patterns:

const rxjsResults = result.customAnalysis.get('RxJSPatternVisitor');

console.log(`Total observables: ${rxjsResults.totalObservables}`);
console.log(`In components: ${rxjsResults.observablesInComponents}`);
console.log(`Components with ngOnDestroy:`, rxjsResults.componentsWithNgOnDestroy);
console.log(`Components without ngOnDestroy:`, rxjsResults.componentsWithoutNgOnDestroy);

// Access individual patterns
rxjsResults.patterns.forEach(pattern => {
  console.log(`${pattern.type} in ${pattern.entityName} - has ngOnDestroy: ${pattern.hasNgOnDestroy}`);
});

Extracts:

  • Observable/Subject/BehaviorSubject/ReplaySubject properties
  • Component lifecycle (presence of ngOnDestroy)
  • Location of each pattern

SecurityVisitor

Extracts security-relevant patterns:

const securityResults = result.customAnalysis.get('SecurityVisitor');

console.log(`Total patterns: ${securityResults.totalPatterns}`);
console.log(`By pattern:`, securityResults.byPattern);

// Example output: { innerHTML: 3, eval: 1, potential_secret: 2, http_url: 5 }

Extracts:

  • innerHTML/outerHTML usage
  • bypassSecurityTrust* calls
  • eval() and Function() usage
  • HTTP URLs (non-HTTPS)
  • Potential hardcoded secrets (API keys, passwords, tokens)
  • XSRF protection configuration

PerformanceVisitor

Extracts performance-relevant patterns:

const perfResults = result.customAnalysis.get('PerformanceVisitor');

console.log(`Total patterns: ${perfResults.totalPatterns}`);
console.log(`By pattern:`, perfResults.byPattern);

// Example output:
// {
//   change_detection_default: 15,
//   ngfor_without_trackby: 8,
//   function_in_template: 3
// }

Extracts:

  • Change detection strategy (Default/OnPush)
  • *ngFor with/without trackBy
  • Function calls in templates
  • HTTP calls in constructors
  • Loops in constructors
  • Large library imports (lodash, moment, rxjs)
  • Array operation chains
  • Storage operations in loops

Advanced Features

Template Analysis

Parse both inline and external HTML templates automatically:

// Component with external template
@Component({
  templateUrl: './my-component.html',
  // ...
})

// Parser automatically extracts:
const component = result.entities.get('component:...:MyComponent');
console.log(component.templateLocation);  // File path + Git URL
console.log(component.templateAnalysis);  // Analysis results

Extracted data:

  • Used components: Custom component selectors found in template
  • Used directives: Structural (*ngIf, *ngFor) and attribute directives
  • Used pipes: All pipes with names (| date, | async, custom pipes)
  • Bindings: Property [prop], event (click), two-way [(ngModel)], etc.
  • Template refs: #myRef references
  • Complexity score: Based on nesting depth and structural directives
{
  "templateAnalysis": {
    "usedComponents": ["app-child", "app-card"],
    "usedDirectives": ["*ngIf", "*ngFor", "appHighlight"],
    "usedPipes": ["date", "async", "customPipe"],
    "bindings": [
      {"type": "property", "name": "disabled", "expression": "!isValid"},
      {"type": "event", "name": "click", "expression": "onSave()"}
    ],
    "templateRefs": ["form", "input"],
    "complexity": 85
  }
}

Style Analysis

Parse SCSS files and extract dependencies:

// Component with styles
@Component({
  styleUrls: [
    './my-component.scss',
    './my-component-responsive.scss'
  ]
})

// Parser extracts all @import and @use statements
const component = result.entities.get('component:...:MyComponent');
console.log(component.styleAnalysis);

Extracted data:

  • @import statements: Path, full statement, line number, resolved path
  • @use statements: Path, namespace, statement, line number, resolved path
  • File locations: All style files with Git URLs
{
  "styleAnalysis": {
    "files": [
      {
        "filePath": "src/app/components/my-component.scss",
        "sourceUrl": "https://github.com/.../my-component.scss",
        "imports": [
          {
            "path": "../styles/mixins",
            "statement": "@import '../styles/mixins'",
            "line": 3
          }
        ],
        "uses": [
          {
            "path": "../styles/variables",
            "statement": "@use '../styles/variables' as vars",
            "namespace": "vars",
            "line": 1
          }
        ]
      }
    ]
  }
}

Global Styles

Automatically detects and parses global SCSS files:

Auto-detected files (no configuration needed):

  • styles.scss, style.scss
  • theme.scss
  • variables.scss, _variables.scss

Searched locations:

  • Project root
  • src/ directory
const result = await parser.parse();
console.log(result.metadata.globalStyles);
{
  "metadata": {
    "globalStyles": [
      {
        "filePath": "src/styles.scss",
        "sourceUrl": "https://github.com/.../src/styles.scss",
        "imports": [
          {"path": "./theme", "statement": "@import './theme'", "line": 2}
        ],
        "uses": [
          {"path": "sass:color", "statement": "@use 'sass:color'", "line": 1}
        ]
      }
    ]
  }
}

Git Integration

Automatic Git repository detection with source URLs:

Supported providers:

  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps

Features:

  • Auto-detects repository from .git directory
  • Generates source URLs for all files
  • Line-specific URLs for entities (e.g., #L42)
  • Branch-aware URLs
  • Works with SSH and HTTPS remotes
const result = await parser.parse();

console.log(result.metadata.repository);
// {
//   provider: 'github',
//   url: 'https://github.com/user/repo',
//   branch: 'main',
//   rootDir: '/path/to/project'
// }

// All entities include source URLs
const entity = result.entities.get('component:...:MyComponent');
console.log(entity.location.sourceUrl);
// "https://github.com/user/repo/blob/main/src/app/my-component.ts#L15"

Creating Custom Visitors

Extend ng-parser with your own pattern extraction:

import { BaseVisitor, type VisitorContext, type Entity } from '@ttwtf/ng-parser';
import * as ts from 'typescript';

interface MyPattern {
  pattern: 'my_pattern_type';
  entityName: string;
  location: any;
}

interface MyResult {
  patterns: MyPattern[];
  totalPatterns: number;
}

class MyCustomVisitor extends BaseVisitor<MyResult> {
  readonly name = 'MyCustomVisitor';
  readonly description = 'Extracts custom patterns';
  readonly priority = 50;
  readonly version = '1.0.0';

  private patterns: MyPattern[] = [];

  // Visit TypeScript AST nodes to extract patterns
  async visitNode(node: ts.Node, context: VisitorContext): Promise<void> {
    if (ts.isClassDeclaration(node)) {
      // Extract pattern - NO evaluation
      this.patterns.push({
        pattern: 'my_pattern_type',
        entityName: node.name?.getText() || 'unknown',
        location: { /* ... */ }
      });
    }
  }

  // Visit Angular entities to extract patterns
  async visitEntity(entity: Entity, context: VisitorContext): Promise<void> {
    if (entity.type === 'component') {
      // Extract fact about component
      const hasTemplate = !!entity.template;
      // Store the FACT, don't evaluate if it's good/bad
    }
  }

  getResults(): MyResult {
    return {
      patterns: this.patterns,
      totalPatterns: this.patterns.length
    };
  }

  reset(): void {
    super.reset();
    this.patterns = [];
  }
}

// Use it
parser.registerVisitor(new MyCustomVisitor());

Remember: Visitors should extract patterns, not evaluate them. Leave analysis and recommendations to separate tools that consume the extracted data.

Export Formats

JSON Export

Complete data export with all information:

const json = result.toJSON();

Contains: All entities, relationships, metadata, custom analysis, warnings, errors, metrics

Optimizations:

  • Removes empty arrays and default values
  • Optimized entity structure
  • Ready for LLM consumption

SimpleJSON Export

ng-analyzer compatible format:

const simple = result.toSimpleJSON();

Features:

  • Simplified structure for basic analysis
  • Compatible with legacy ng-analyzer tools
  • Lightweight output

HTML Export

Interactive visualization with D3.js:

const html = result.toHTML();

Features:

  • 🎨 Interactive D3.js force-directed dependency graph
  • 🔍 Searchable entity explorer
  • 📊 Visitor results dashboards (RxJS, Security, Performance)
  • 🔗 Clickable Git source URLs
  • 📱 Responsive design (mobile-friendly)
  • 💾 Self-contained (works offline, no build required)

Use cases:

  • Team onboarding - Visual learning for new developers
  • Architecture presentations - Interactive demos in meetings
  • Code reviews - Shareable offline documentation
  • CI/CD docs - Auto-generated project documentation

Examples

Complete working examples in examples/:

| Example | Description | |---------|-------------| | 01-quick-start.ts | Basic parsing with built-in visitors | | 02-custom-visitors.ts | Creating custom analysis visitors | | 03-complete-analysis.ts | Complete workflow with all features |

Run examples:

# Quick start
npx ts-node examples/01-quick-start.ts

# Custom visitors
npx ts-node examples/02-custom-visitors.ts

# Complete analysis
npx ts-node examples/03-complete-analysis.ts

Configuration

const parser = new NgParser({
  rootDir: './src',              // Required: source directory
  includeTests: false,           // Optional: include test files
  maxDepth: 20,                  // Optional: directory depth limit
});

Use Cases

  • 🤖 RAG/LLM Training - Generate structured documentation for AI models
  • 📊 Code Analysis Foundations - Extract patterns for analysis tools to evaluate
  • 🔍 Codebase Exploration - Understand large Angular projects structure
  • 🔒 Security Pattern Detection - Identify security-relevant code for auditing tools
  • Performance Pattern Detection - Extract patterns for performance analysis
  • 📝 Documentation - Auto-generate architecture docs from parsed entities
  • 🔄 Migration Analysis - Extract patterns to prepare for Angular upgrades
  • 🏗️ Analysis Tool Development - Build custom analyzers on top of extracted data

Requirements

  • Node.js ≥ 18.0.0
  • TypeScript ≥ 5.4.0
  • Angular ≥ 18.0.0 (peer dependency)

Documentation

Version Strategy

ng-parser uses peerDependencies to support multiple Angular versions with a single codebase:

  • ✅ Your project's Angular version is automatically used
  • ✅ No version conflicts
  • ✅ Supports Angular 18, 19, and 20
  • ✅ Minimal maintenance overhead

FAQ

Q: Can I analyze a specific file instead of the whole project? Currently ng-parser works at the project level. For single-file analysis, use TypeScript Compiler API directly.

Q: What if I only want specific visitors? Only register the visitors you need:

parser.registerVisitor(new SecurityVisitor()); // Only security analysis

Q: How do I access specific entity types?

const components = Array.from(result.entities.values())
  .filter(e => e.type === 'component');

Q: Can I use this in a CI/CD pipeline? Yes! ng-parser works great in automated workflows for code quality checks.

Contributing

Contributions welcome! Please read our Code Review Standards before submitting PRs.

License

MIT © [Your Name]

Support


Made with ❤️ for the Angular community