frontend-inferencer

Installation
SKILL.md
Contains Hooks

This skill uses Claude hooks which can execute code automatically in response to events. Review carefully before installing.

Frontend Inferencer Skill

Purpose

Infer frontend technologies by analyzing collected signals from JavaScript, DOM, HTML, and CSS analysis phases.

Input

Raw signals from Phase 2:

  • javascript_signals - Global variables, DOM attributes, bundle patterns
  • html_signals - Meta tags, script URLs, CSS classes
  • http_signals - Headers (for SPA indicators)

Technology Categories

JavaScript Frameworks

Technology Detection Signals Weight
React window.React, data-reactroot, /_next/ 30-40
Vue.js window.Vue, data-v-*, /_nuxt/ 30-40
Angular ng-version, _ngcontent-*, window.ng 30-40
Svelte window.__svelte, data-svelte-h 30-35
jQuery window.jQuery, window.$ 25-30
Alpine.js window.Alpine, x-data, x-init 25-30

Meta-Frameworks

Technology Detection Signals Implies Weight
Next.js NEXT_DATA, /_next/static/ React, Node.js 35-40
Nuxt.js window.NUXT, /_nuxt/ Vue.js, Node.js 35-40
Gatsby window.___gatsby React 35-40
Remix __remixContext React 35-40
SvelteKit __sveltekit Svelte 35-40
Astro data-astro-* - 30-35

CSS Frameworks

Technology Detection Signals Weight
Bootstrap btn btn-, container, navbar, col- 25-30
Tailwind CSS bg-, text-, flex, p-, m- 25-30
Material UI MuiButton, MuiGrid, MuiPaper 30-35
Ant Design ant-btn, ant-card, ant-table 30-35
Chakra UI chakra-* classes 25-30
Foundation button, callout, grid-x 25-30
Bulma button is-*, columns, hero 25-30

UI Component Libraries

Technology Detection Signals Weight
Radix UI data-radix-* 25-30
Headless UI data-headlessui-* 25-30
shadcn/ui Combination of Tailwind + Radix patterns 20-25

State Management

Technology Detection Signals Weight
Redux window.REDUX_DEVTOOLS_EXTENSION 25-30
MobX window.__mobxGlobal 25-30
Zustand Bundle patterns 20-25
Recoil Bundle patterns 20-25

Build Tools (from bundle patterns)

Technology Detection Signals Weight
Webpack /bundle.js, .chunk.js, /vendor.js 20-25
Vite /@vite/, .js?v= 25-30
Parcel /parcel-* 20-25
esbuild Bundle patterns 20-25
Rollup Bundle patterns 20-25

Inference Logic

def infer_frontend_technologies(signals):
    results = []

    # JavaScript Framework Detection
    for framework in FRAMEWORK_PATTERNS:
        score = 0
        evidence = []

        # Check global variables
        for global_var in framework.globals:
            if global_var in signals.javascript_signals.globals:
                score += framework.global_weight
                evidence.append(f"{global_var} detected")

        # Check DOM attributes
        for attr in framework.dom_attributes:
            if attr in signals.html_signals.dom_attributes:
                score += framework.dom_weight
                evidence.append(f"{attr} attribute found")

        # Check bundle patterns
        for pattern in framework.bundle_patterns:
            if pattern in signals.javascript_signals.script_urls:
                score += framework.bundle_weight
                evidence.append(f"Bundle pattern: {pattern}")

        if score > 0:
            results.append({
                "name": framework.name,
                "category": framework.category,
                "signals": evidence,
                "total_weight": score,
                "implies": framework.implies
            })

    # CSS Framework Detection
    for css_framework in CSS_FRAMEWORK_PATTERNS:
        matches = count_class_matches(
            signals.html_signals.css_classes,
            css_framework.patterns
        )

        if matches >= css_framework.min_matches:
            score = css_framework.base_weight + (matches * 2)
            results.append({
                "name": css_framework.name,
                "category": "CSS Framework",
                "signals": [f"{matches} class patterns matched"],
                "total_weight": score
            })

    return results

Output

{
  "skill": "frontend_inferencer",
  "results": {
    "technologies": [
      {
        "name": "React",
        "category": "JavaScript Framework",
        "version": "18.x (if detectable)",
        "signals": [
          {
            "type": "javascript_global",
            "value": "window.React detected",
            "source": "https://example.com",
            "weight": 30
          },
          {
            "type": "dom_attribute",
            "value": "data-reactroot found",
            "source": "https://example.com",
            "weight": 25
          }
        ],
        "total_weight": 55,
        "implies": []
      },
      {
        "name": "Next.js",
        "category": "Meta-Framework",
        "version": "13.x",
        "signals": [
          {
            "type": "javascript_global",
            "value": "__NEXT_DATA__ found",
            "source": "https://example.com",
            "weight": 35
          },
          {
            "type": "bundle_pattern",
            "value": "/_next/static/ paths",
            "source": "https://example.com",
            "weight": 30
          }
        ],
        "total_weight": 65,
        "implies": ["React", "Node.js"]
      },
      {
        "name": "Tailwind CSS",
        "category": "CSS Framework",
        "signals": [
          {
            "type": "css_classes",
            "value": "15 Tailwind class patterns matched (bg-*, text-*, flex, p-*, etc.)",
            "source": "https://example.com",
            "weight": 30
          }
        ],
        "total_weight": 30
      }
    ],
    "implied_technologies": [
      {
        "name": "Node.js",
        "implied_by": ["Next.js"],
        "confidence": "High"
      }
    ],
    "summary": {
      "primary_framework": "Next.js",
      "ui_library": "Tailwind CSS",
      "state_management": null,
      "build_tool": "Webpack (via Next.js)"
    }
  }
}

Version Detection

React

// From __REACT_DEVTOOLS_GLOBAL_HOOK__
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.get(1).version

// From React DevTools
window.React.version

Angular

<!-- From ng-version attribute -->
<app-root ng-version="16.2.0">

Next.js

// From __NEXT_DATA__
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).nextVersion

Vue.js

// From Vue instance
window.Vue.version

Confidence Calculation

Frontend Technology Confidence:

High (80-100%):
  - Direct framework global detected
  - Multiple supporting signals
  - Version information available

Medium (50-79%):
  - Bundle patterns match
  - DOM attributes present
  - No direct confirmation

Low (20-49%):
  - Only CSS class patterns
  - Single indirect signal
  - Job posting mention only

Error Handling

  • Missing signals: Return empty results for category
  • Conflicting signals: Include both with notes
  • Version detection failure: Omit version, continue
Related skills
Installs
12
GitHub Stars
250
First Seen
Mar 9, 2026