A comprehensive example showcasing how to achieve application-level transparency in OTel tracing using @waitingliou/tsc-otel-instrumentation - automatic, non-invasive OpenTelemetry instrumentation for your Hono.js project running on Bun runtime.
Primary Goals
- Show how to achieve clean business logic without manual instrumentation
- Provide a complete example of
@waitingliou/tsc-otel-instrumentationintegration - Demonstrate basic observability stack (traces + logs)
Who Is This For?
- Developers learning OpenTelemetry and automatic instrumentation
- Teams, Organizations seeking non-invasive tracing approaches
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Web Framework | Hono.js | 4.8+ | Lightweight, fast web framework |
| Runtime | Bun | Latest | JavaScript/TypeScript runtime (for execution) |
| Language | TypeScript | 5.0+ | Type-safe development |
| Compiler | TypeScript Compiler (tsc) | 5.0+ | |
| Instrumentation | @waitingliou/tsc-otel-instrumentation | 1.1.7+ | Automatic class method tracing |
| Observability | OpenTelemetry | Latest | Distributed tracing standard |
| Trace Backend | Grafana Cloud Tempo | Cloud | Trace storage and visualization |
Why not Bun's transpiler?
@waitingliou/tsc-otel-instrumentation is a TypeScript compiler plugin that hooks into tsc's AST transformation pipeline. Bun's TypeScript transpiler (written in Zig for speed) doesn't support TypeScript's plugin system.
Build pipeline:
Source TypeScript → tsc (with ts-patch) → Instrumented JavaScript → Bun runtime
↑
tsc-otel-instrumentation
AST transformation
Use tsc to compile, then Bun to run.
This example follows Clean Architecture principles to demonstrate real-world usage:
┌────────────────────────────────────────┐
│ Controllers (HTTP Handlers) │
│ - Handle requests/responses │
└─────────────┬──────────────────────────┘
│ Dependency Injection
┌─────────────▼──────────────────────────┐
│ Use Cases (Business Logic Services) │ ← Automatically instrumented
│ - UserService, NotificationService │
└─────────────┬──────────────────────────┘
│ Interfaces (Ports)
┌─────────────▼──────────────────────────┐
│ Repositories (Data Access) │ ← Automatically instrumented
│ - UserRepository, SocialLinkRepo │
└────────────────────────────────────────┘
- Node.js >= 18.0.0
- Bun >= 1.0.0 (install from bun.sh)
- Grafana Cloud account (free tier available)
# Install dependencies
bun installCreate .env file:
# Application Configuration
NODE_ENV=production
PORT=3002
# OpenTelemetry - Get from Grafana Cloud → Connections → OTLP
OTEL_EXPORTER_OTLP_ENDPOINT=...
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <your-base64-token>"
# Grafana Cloud Credentials (for logs if using Loki)
GRAFANA_HOST=https://logs-prod-XXX.grafana.net
GRAFANA_USERNAME=123456
GRAFANA_CLOUD_TOKEN=glc_xxxxxxxxxxxxxxxxxxxxxHow to get credentials:
- Visit grafana.com and sign up
- Navigate to Connections → Add new connection
- Select OpenTelemetry (OTLP) for traces
- Select Loki for logs
- Copy credentials to
.env
# Step 1: Compile TypeScript with tsc (applies instrumentation)
bun run build
# Step 2: Run the compiled JavaScript with Bun
bun run start:bun
# Or for development with hot reload
bun run devServer starts at http://localhost:3002
Happy tracing! 🎉
Achieve application-level transparency in your TypeScript projects with zero code pollution.
