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

@pagopa/dx-savemoney

v0.1.6

Published

Azure resource analyzer for finding unused or cost-inefficient resources.

Downloads

187

Readme

DX Save Money

A TypeScript library for analyzing CSP (Cloud Service Provider) resources to identify potential cost inefficiencies and underutilized resources. It operates in read-only mode and does not modify, tag, or delete any resources; instead, it generates detailed reports to support FinOps decisions.

Supported Cloud Providers

✅ Azure

Full support for Azure resource analysis with intelligent detection and flexible reporting.

🚧 AWS (Coming Soon)

AWS support is planned for future releases. The architecture is designed to support multiple CSPs with provider-specific analyzers.

Architecture

The SaveMoney tool follows a modular architecture designed for multi-CSP support:

flowchart LR
    subgraph cli["CLI Layer"]
        CMDs[other cmds]
        CLI[savemoney]
    end
    subgraph pkg["Package Layer - @pagopa/dx-savemoney"]
        Config[Config Loader]
        Azure[Azure Analyzer]
        AWS[AWS Analyzer<br/>Coming Soon...]
    end
    subgraph svc["Azure Services"]
        ARM[Azure Resource Manager]
        Monitor[Azure Monitor Metrics]
        Identity[Azure Identity]
    end
    subgraph rsc["Azure Resources"]
        direction LR
        VM[Virtual Machines]
        Disk[Managed Disks]
        NIC[Network Interfaces]
        IP[Public IPs]
        ASP[App Service Plans]
        PE[Private Endpoints]
        SA[Storage Accounts]
        CA[Container Apps]
        SS[Static Web Apps]
    end
    CLI --> Config
    Config --> Azure
    Config -.-> AWS
    Azure --> ARM
    Azure --> Monitor
    Azure --> Identity
    ARM --> rsc
    Monitor --> rsc
    style CLI fill:#0078d4,color:#fff
    style Azure fill:#0078d4,color:#fff
    style AWS fill:#ccc,color:#666
    style Config fill:#107c10,color:#fff

Installation

npm install @pagopa/dx-savemoney
# or
pnpm add @pagopa/dx-savemoney
# or
yarn add @pagopa/dx-savemoney

Azure

Main Features

  • Multi-Subscription Analysis: Scans multiple Azure subscriptions in a single command.
  • Intelligent Detection: Uses Azure Monitor metrics (e.g. CPU, network traffic, transactions) to scientifically identify inactive resources.
  • Orphaned Resource Identification: Detects commonly "forgotten" resources like unattached disks, unassociated public IPs, and unused network interfaces.
  • Flexible Reporting: Offers multiple output formats:
    • table: A human-readable summary for the terminal.
    • json: Standard format for integration with other tools.
    • detailed-json: A comprehensive output with all resource metadata, ideal for in-depth analysis via AI or custom scripts.
  • Simplified Configuration: Supports configuration via files, command-line options, environment variables, or an interactive prompt.

Analyzed Resources

The tool analyzes the following Azure resource types with specific detection methods and risk levels:

| Resource Type | Detection Method | Cost Risk | What's Checked | | :---------------------- | :---------------------- | :-------: | :------------------------------------------------------------------------------------------------------------------ | | Virtual Machines | Instance View + Metrics | 🔴 High | Deallocated/stopped state, Low CPU usage (<1%), Low network traffic (<3MB per days) | | App Service Plans | API Details + Metrics | 🔴 High | No apps deployed, Very low CPU (<5%), Very low memory (<10%), Oversized Premium tier | | Container Apps | API Details + Metrics | 🟡 Medium | Not running state, Zero replicas configured, Low CPU (<0.001 cores), Low memory (<10MB), Low network traffic (<1MB) | | Managed Disks | API Details | 🟡 Medium | Unattached state, No managedBy property | | Public IP Addresses | API Details + Metrics | 🟡 Medium | Not associated with any resource, Static IP not in use, Very low network traffic (<~340KB per day) | | Network Interfaces | API Details | 🟡 Medium | Not attached to VM or Private Endpoint, No public IP assigned | | Private Endpoints | API Details | 🟡 Medium | No private link connections, Rejected/disconnected connections, No network interfaces | | Storage Accounts | Metrics | 🟡 Medium | Very low transaction count (<10 per days in timespan) | | Static Web Apps | Metrics | 🟢 Low | No traffic data available, Very low site hits (<100 requests in 30 days), Very low data transfer (<1MB in 30 days) |

Generic Checks

All resources are also checked for:

  • Missing tags: Resources without tags are flagged as potentially unmanaged
  • Location mismatch: Resources not in the preferred location are reported

Prerequisites

  1. Node.js: Version 22 or higher.
  2. Azure Credentials: The library uses DefaultAzureCredential from @azure/identity, which supports various authentication methods:
    • Azure CLI (az login)
    • Managed Identity
    • Environment variables
    • Visual Studio Code
    • And more...

Usage

Quick Start

import { azure, loadConfig } from "@pagopa/dx-savemoney";

// Load configuration (from file, env vars, or interactive prompt)
const config = await loadConfig("./config.json");

// Run analysis and generate report
await azure.analyzeAzureResources(config, "table");

Configuration Inputs

The tool requires the following configuration:

| Input | Type | Required | Default | Description | | :------------------ | :--------- | :------: | :----------- | :----------------------------------------------------------- | | tenantId | string | ✅ | - | Azure Active Directory Tenant ID | | subscriptionIds | string[] | ✅ | - | Array of Azure subscription IDs to analyze | | preferredLocation | string | ❌ | italynorth | Preferred Azure region (resources elsewhere will be flagged) | | timespanDays | number | ❌ | 30 | Number of days to look back for metrics analysis | | verbose | boolean | ❌ | false | Enable detailed logging for each resource analyzed |

Output Formats

The tool supports multiple output formats for different use cases:

| Format | Description | Use Case | | :-------------- | :---------------------------------------------- | :----------------------------- | | table | Human-readable table in terminal | Quick visual inspection | | json | Structured JSON with resource summaries | Integration with other tools | | detailed-json | Complete JSON with full Azure resource metadata | AI analysis or deep inspection |

How to Load Configuration

The loadConfig() function loads configuration in the following priority order:

  1. Configuration file (pass file path as parameter)
  2. Environment variables (ARM_TENANT_ID, ARM_SUBSCRIPTION_ID)
  3. Interactive prompt (if no other configuration is found)

Example:

// From file
const config1 = await loadConfig("./config.json");

// From environment variables or prompt
const config2 = await loadConfig();

Configuration File Example

{
  "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "subscriptionIds": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"],
  "preferredLocation": "italynorth",
  "timespanDays": 30,
  "verbose": false
}

Usage Examples

Basic Usage
import { azure, loadConfig } from "@pagopa/dx-savemoney";

// Load from config file
const config = await loadConfig("./config.json");
await azure.analyzeAzureResources(config, "table");
Custom Configuration
import { azure } from "@pagopa/dx-savemoney";
import type { AzureConfig } from "@pagopa/dx-savemoney";

const config: AzureConfig = {
  tenantId: "your-tenant-id",
  subscriptionIds: ["sub-id-1", "sub-id-2"],
  preferredLocation: "italynorth",
  timespanDays: 30,
  verbose: true,
};

await azure.analyzeAzureResources(config, "json");
Generate Detailed Report
import { azure, loadConfig } from "@pagopa/dx-savemoney";

const config = await loadConfig();
// Generate detailed JSON with full resource metadata
await azure.analyzeAzureResources(config, "detailed-json");
Using Environment Variables
import { loadConfig, azure } from "@pagopa/dx-savemoney";

// Set environment variables
// ARM_TENANT_ID=xxx
// ARM_SUBSCRIPTION_ID=sub1,sub2

const config = await loadConfig(); // Will read from env vars
await azure.analyzeAzureResources(config, "json");

AWS (Coming Soon)

AWS support is planned for future releases with similar capabilities:

  • Multi-account analysis
  • Resource-specific detection algorithms
  • Flexible reporting formats
  • AWS-specific configuration options

The API will follow a similar pattern:

import { aws, loadAwsConfig } from "@pagopa/dx-savemoney";

const config = await loadAwsConfig("./aws-config.json");
await aws.analyzeAwsResources(config, "table");

Development

Type Checking

pnpm typecheck

Linting

pnpm lint        # Auto-fix issues
pnpm lint:check  # Check without fixing

Testing

pnpm test              # Run tests
pnpm test:watch        # Watch mode
pnpm test:coverage     # With coverage report

Formatting

pnpm format        # Format code
pnpm format:check  # Check formatting