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

@waitingliou/ts-otel-weaver

v1.1.7

Published

Zero-touch business-logic tracing and OpenTelemetry automatic instrumentation for TypeScript via compile-time AST weaving

Readme

@waitingliou/ts-otel-weaver

TypeScript Build Status License: Apache 2.0 OpenTelemetry npm version

An automatic instrumentation tool, complimentary to OpenTelemetry to enable tracing in your business logic without messing up your codebase.

Specification

A TypeScript transformer that automatically instruments your business logic methods (class-level) with OpenTelemetry spans at compile time through AST weaving, achieving true "application-level transparency" as described in Google's Dapper paper.

  • Zero-touch: No code changes required in your business logic
  • Deep Tracing: Automatically traces all method calls, including private methods
  • Minimal Runtime Overhead: Instead of runtime monkey-patch → compile-time patching

Design Philosophy

This transformer uses a strategically designed AST visitor that specifically targets class-level method declarations to achieve optimal performance and precision in business logic tracing.

Design Principles:

  • Precision over Volume: Focuses on business logic methods in classes where most application logic resides
  • Performance Optimization: Avoids instrumenting every function to prevent span explosion and performance degradation
  • Strategic Targeting: Selectively instruments ts.isMethodDeclaration nodes which typically contain core business operations
  • Noise Reduction: Excludes utility functions, helpers, and nested functions that would create excessive telemetry noise

Benefits:

  • Low Overhead: Minimal performance impact by avoiding over-instrumentation
  • Scalable Monitoring: Maintains manageable trace volumes even in large applications
  • Clear Insights: Provides actionable observability into your application's business logic flow

This intentional scope limitation ensures you get high-value tracing data without overwhelming your observability infrastructure or impacting application performance.

OpenTelemetry Compatible: This package follows OpenTelemetry Semantic Conventions and integrates seamlessly with the OpenTelemetry ecosystem.

Installation

# Install as development dependency (compile-time only)
npm install @waitingliou/ts-otel-weaver --save-dev

[!IMPORTANT] This package is a compile-time TypeScript transformer that modifies your code during the build process. The generated JavaScript code has no runtime dependency on this package - only on @opentelemetry/api.

Usage:

1. Configure TypeScript Compiler

Add the transformer to your project's tsconfig.json:

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "@waitingliou/ts-otel-weaver/transformer",
        "include": [
          "**/*Service.ts",
          "**/*Repository.ts"
        ],
        "exclude": [
          "**/*.test.ts",
          "**/*.spec.ts"
        ],
        "instrumentPrivateMethods": true,
        "spanNamePrefix": "myapp",
        "autoInjectTracer": true
      }
    ]
  }
}

2. Install and Configure ts-patch

ts-patch patches your local TypeScript installation so the official tsc can load custom transformers from compilerOptions.plugins.

# Install ts-patch as development dependency  
npm install ts-patch --save-dev
npx ts-patch install -s

I recommend adding a postinstall step to your npm scripts to ensure teammates automatically set up ts-patch after installing dependencies:

"scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "test": "jest",
    "postinstall": "ts-patch install -s"
},

3. Add OpenTelemetry Dependencies

Install OpenTelemetry API as a production dependency (required at runtime):

# Runtime dependency for generated instrumentation code
npm install @opentelemetry/api

4. Configuration Options

Complete tsconfig.json Compile Plugin Configuration Example

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "@waitingliou/ts-otel-weaver/transformer",
        "include": [
          "**/*Service.ts",
          "**/*Repository.ts",
          "src/business/**/*.ts"
        ],
        "exclude": [
          "**/*.test.ts",
          "**/*.spec.ts",
          "**/node_modules/**"
        ],
        "instrumentPrivateMethods": true,
        "spanNamePrefix": "myapp",
        "autoInjectTracer": true,
        "commonAttributes": {
          "service.name": "user-management-service",
          "service.version": "1.2.0",
          "deployment.environment": "production"
        },
        "includeMethods": ["create*", "updateUser", "get?ser"],
        "excludeMethods": ["toString", "test*", "deprecated"],
        "debug": false,
        "logLevel": "warn",
        "maxMethodsPerFile": 50
      }
    ]
  }
}

Configuration Options Reference

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | include | string[] | ✅ | - | Glob patterns for files to instrument. Supports standard glob syntax: **/*Service.ts, src/business/**/*.ts | | exclude | string[] | ❌ | ["**/*.test.ts", "**/*.spec.ts", "**/node_modules/**"] | Glob patterns for files to skip. Takes priority over include | | instrumentPrivateMethods | boolean | ❌ | false | Include methods starting with _ (underscore). Example: _privateMethod | | spanNamePrefix | string | ❌ | "ts-otel-weaver" | Prefix for all span names. Final span: {prefix}.{ClassName}.{methodName} | | autoInjectTracer | boolean | ❌ | true | Automatically add import { trace } from "@opentelemetry/api" to instrumented files | | commonAttributes | Record<string, string> | ❌ | {} | Key-value pairs added to ALL spans. Use for service metadata, environment info, etc. | | includeMethods | string[] | ❌ | [] | Method name patterns to instrument. Supports exact names and glob patterns (*, ?). Highest priority - only these methods will be instrumented if specified | | excludeMethods | string[] | ❌ | ["constructor", "toString", "valueOf", "toJSON", "inspect"] | Method name patterns to skip. Supports exact names and glob patterns (*, ?). Ignored if includeMethods is set | | debug | boolean | ❌ | false | Enable detailed transformation logs during compilation | | logLevel | 'none' \| 'error' \| 'warn' \| 'info' \| 'debug' | ❌ | 'warn' | Control console output verbosity | | maxMethodsPerFile | number | ❌ | 100 | Safety limit to prevent accidentally instrumenting too many methods |

Supported Function Types

This transformer automatically detects and properly instruments various TypeScript method types based on the design principles outlined in the Specification section.

Function Type Support Matrix

| Function Type | Status | Scope | Sync | Async | Generator | Example | |--------------|--------|-------|------|-------|-----------|---------| | Class Methods | ✅ Supported | Class | ✅ | ✅ | ✅ | getUser(id: string): User | | Private Methods | ✅ Supported | Class | ✅ | ✅ | ✅ | private _validateUser(user: User) | | Static Methods | ✅ Supported | Class | ✅ | ✅ | ✅ | static getInstance(): UserService | | Async Methods | ✅ Supported | Class | ❌ | ✅ | ✅ | async createUser(data: UserData) | | Generator Methods | ✅ Supported | Class | ✅ | ✅ | ✅ | *generateSequence(count: number) | | Async Generators | ✅ Supported | Class | ❌ | ✅ | ✅ | async *processUsers() | | Arrow Function Properties | 🎯 Excluded by Design | Class | ❌ | ❌ | ❌ | getUser = (id: string) => {} | | Function Expressions | 🎯 Excluded by Design | Class | ❌ | ❌ | ❌ | getUser: () => User = function() {} | | Standalone Functions | 🎯 Excluded by Design | Global | ❌ | ❌ | ❌ | function getUserById(id: string) | | Arrow Functions | 🎯 Excluded by Design | Global | ❌ | ❌ | ❌ | const processUser = (user) => {} | | Nested Functions | 🎯 Excluded by Design | Function | ❌ | ❌ | ❌ | Functions inside other functions | | Object Methods | 🎯 Excluded by Design | Object | ❌ | ❌ | ❌ | const obj = { method() {} } |

Auto-generated spans structure examples

When you call a method, it automatically generates a tracing structure like:

myapp.UserService.getUser
├──  myapp.UserService.createUser
│   ├── myapp.CacheService.get
│   ├── myapp.UserService._validateUserData (private method)
│   ├── myapp.UserRepository.save
│   │   ├── myapp.UserRepository._validateUser
│   │   └── myapp.UserRepository._persistUser  
├── myapp.UserService._processUserData
│   ├── myapp.ValidationService.validate
│   └── myapp.TransformService.transform
└── myapp.NotificationService.sendWelcome

Examples

| Name | Description | |--------|------| | Honojs | not done yet |

Debugging and Verification

Compile and check:

npm run build

# check import
head -5 dist/your-service.js
# should see:
# import { trace, SpanStatusCode, SpanKind } from "@opentelemetry/api";
# const tracer = trace.getTracer("@waitingliou/ts-otel-weaver");

📋 Requirements

Development Dependencies

  • Node.js >= 18.0.0
  • TypeScript >= 4.5.0
  • ts-patch for transformer integration

Runtime Dependencies

  • @opentelemetry/api >= 1.9.0 (for generated instrumentation code)

📄 License

Apache-2.0 License - see LICENSE file for details.

🙏 Acknowledgments

  • Inspired by runtime monkey-patching of OpenTelemetry Instrumentation libraries
  • Thanks to @Pathors. As a intern in @Pathors, I was inspired with the idea of developing this tool during the process of integrating OTel.
  • Leverages TypeScript Compiler API for AST transformations

🔗 Related Projects