{"id":36498126,"url":"https://github.com/mnrendra/stack-trace","last_synced_at":"2026-01-15T02:56:08.029Z","repository":{"id":180627391,"uuid":"665401951","full_name":"mnrendra/stack-trace","owner":"mnrendra","description":"A lightweight stack trace utility to retrieve CallSite objects from a specific caller.","archived":false,"fork":false,"pushed_at":"2025-04-29T15:00:50.000Z","size":570,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-29T15:58:02.614Z","etag":null,"topics":["callsite","callsites","stack-trace","stack-trace-v8","stack-traces"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@mnrendra/stack-trace","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnrendra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-12T06:05:57.000Z","updated_at":"2025-04-25T21:49:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"5fc511dc-83f7-434d-9a2c-1bd90ef1f0b9","html_url":"https://github.com/mnrendra/stack-trace","commit_stats":{"total_commits":6,"total_committers":3,"mean_commits":2.0,"dds":"0.33333333333333337","last_synced_commit":"1eb80a3295241fa44f492995cf17ba18065cd69a"},"previous_names":["mnrendra/stack-trace"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/mnrendra/stack-trace","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnrendra%2Fstack-trace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnrendra%2Fstack-trace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnrendra%2Fstack-trace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnrendra%2Fstack-trace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnrendra","download_url":"https://codeload.github.com/mnrendra/stack-trace/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnrendra%2Fstack-trace/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28441780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"online","status_checked_at":"2026-01-15T02:00:08.019Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["callsite","callsites","stack-trace","stack-trace-v8","stack-traces"],"created_at":"2026-01-12T02:05:29.861Z","updated_at":"2026-01-15T02:56:08.023Z","avatar_url":"https://github.com/mnrendra.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @mnrendra/stack-trace\n\n[![version](https://img.shields.io/npm/v/@mnrendra/stack-trace?logo=nodedotjs)](https://www.npmjs.com/package/@mnrendra/stack-trace?activeTab=versions)\n[![downloads](https://img.shields.io/npm/dm/@mnrendra/stack-trace)](https://npm-stat.com/charts.html?package=@mnrendra/stack-trace)\n[![size](https://packagephobia.now.sh/badge?p=@mnrendra/stack-trace)](https://packagephobia.com/result?p=%40mnrendra%2Fstack-trace)\n[![coverage](https://codecov.io/github/mnrendra/stack-trace/graph/badge.svg?token=LSNMMJVQ77)](https://app.codecov.io/gh/mnrendra/stack-trace)\n[![scorecard](https://api.securityscorecards.dev/projects/github.com/mnrendra/stack-trace/badge)](https://securityscorecards.dev/viewer/?uri=github.com/mnrendra/stack-trace)\n[![release](https://github.com/mnrendra/stack-trace/actions/workflows/release.yml/badge.svg)](https://github.com/mnrendra/stack-trace/actions/workflows/release.yml)\n[![semantic](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/mnrendra/stack-trace/commits/main)\n[![license](https://img.shields.io/npm/l/@mnrendra/stack-trace)](https://github.com/mnrendra/stack-trace/blob/main/LICENSE)\n\nA lightweight [stack trace](https://v8.dev/docs/stack-trace-api) utility to retrieve `CallSite` objects from a specific caller.\n\n*Useful for debugging, logging, or building tools that need to trace call origins at runtime.*\n\n## Features\n- ✅ Supports both **ES Modules** and **CommonJS** from a single source - see [package](https://www.npmjs.com/package/@mnrendra/stack-trace?activeTab=code)\n- ✅ Minified and cleansed of unnecessary dependencies, files, and attributes - see [contents](https://www.npmjs.com/package/@mnrendra/stack-trace?activeTab=code)\n- ✅ Tiny package - see [size](https://bundlephobia.com/package/@mnrendra/stack-trace)\n- ✅ Well tested - see [coverage](https://app.codecov.io/gh/mnrendra/stack-trace)\n- ✅ Security checked - see [scorecard](https://securityscorecards.dev/viewer/?uri=github.com/mnrendra/stack-trace)\n- ✅ Verified all commits - see [signatures](https://github.com/mnrendra/stack-trace/commits/main)\n- ✅ Semantic versioning - see [commits](https://github.com/mnrendra/stack-trace/commits/main)\n- ✅ Actively maintained - [pull requests](https://github.com/mnrendra/stack-trace/pulls), [issues](https://github.com/mnrendra/stack-trace/issues), [discussions](https://github.com/mnrendra/stack-trace/discussions), and [contributions](https://github.com/mnrendra/stack-trace/blob/HEAD/CONTRIBUTING.md) are welcome!\n\n## Install\n```bash\nnpm i @mnrendra/stack-trace\n```\n\n## API Reference\n\n### `stackTrace`\nCaptures [v8 stack trace](https://v8.dev/docs/stack-trace-api) from a specific caller.\n\n#### Type\n```typescript\n(callee?: ((...args: any) =\u003e any) | null, options?: Options) =\u003e NodeJS.CallSite[]\n```\n\n#### Parameters\n| Name      | Type                              | Description                                                                                                                                                                                                          |\n|-----------|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `callee`  | `((...args: any) =\u003e any) \\| null` | Optional callee function to specify the caller. If `undefined` or `null`, tracing starts from the current caller.                                                                                                    |\n| `options` | `Options`                         | Optional options to affect the captured frames. By default, the `limit` option is set to `Infinity` to capture all frames. To capture only a specific number of frames, set the `limit` option to a positive number. |\n\n#### Return\n```typescript\nNodeJS.CallSite[]\n```\nArray of `CallSite` objects representing the captured stack trace frames.\n\n#### Options\n| Name    | Type     | Default    | Description                                                                                                                                                                                                                                                                                                                                |\n|---------|----------|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `limit` | `number` | `Infinity` | Specifies the number of stack frames to be collected by a stack trace. The default value is `Infinity`, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. |\n\n### `getCallerSite`\nGets the caller's `CallSite` object captured from [`stackTrace`](#stacktrace).\n\n#### Type\n```typescript\n(callee?: ((...args: any) =\u003e any) | null) =\u003e NodeJS.CallSite\n```\n\n#### Parameters\n| Name      | Type                              | Description                                                                                                       |\n|-----------|-----------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| `callee`  | `((...args: any) =\u003e any) \\| null` | Optional callee function to specify the caller. If `undefined` or `null`, tracing starts from the current caller. |\n\n#### Return\n```typescript\nNodeJS.CallSite\n```\nFirst `CallSite` object captured in the stack trace.\n\n### `extractFilePath`\nExtracts the file name from a `CallSite` object and converts it to a file path if the value is a file URL.  \n*This utility ensures that the returned value is an absolute path.*\n\n#### Type\n```typescript\n(callSite: NodeJS.CallSite) =\u003e string\n```\n\n#### Parameters\n| Name        | Type              | Description                                                  |\n|-------------|-------------------|--------------------------------------------------------------|\n| `callSite`  | `NodeJS.CallSite` | `CallSite` object captured from [`stackTrace`](#stacktrace). |\n\n#### Return\n```typescript\nstring\n```\nAbsolute path of the file name extracted from a `CallSite` object.\n\n#### Throws\nIf the extracted file name is not a string or not absolute.\n\n### `getCallerFile`\nGets the caller's file extracted from the result of [`getCallerSite`](#getcallersite) and ensures it returns an absolute path using [`extractFilePath`](#extractfilepath).\n\n#### Type\n```typescript\n(callee?: ((...args: any) =\u003e any) | null) =\u003e string\n```\n\n#### Parameters\n| Name      | Type                              | Description                                                                                                       |\n|-----------|-----------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| `callee`  | `((...args: any) =\u003e any) \\| null` | Optional callee function to specify the caller. If `undefined` or `null`, tracing starts from the current caller. |\n\n#### Return\n```typescript\nstring\n```\nAbsolute path of the caller's file.\n\n#### Throws\nIf the extracted file name is not a string or not absolute.\n\n### `getCallerDir`\nGets the caller's directory extracted from the result of [`getCallerFile`](#getcallerfile).\n\n#### Type\n```typescript\n(callee?: ((...args: any) =\u003e any) | null) =\u003e string\n```\n\n#### Parameters\n| Name      | Type                              | Description                                                                                                       |\n|-----------|-----------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| `callee`  | `((...args: any) =\u003e any) \\| null` | Optional callee function to specify the caller. If `undefined` or `null`, tracing starts from the current caller. |\n\n#### Return\n```typescript\nstring\n```\nAbsolute path of the caller's directory.\n\n#### Throws\nIf the extracted file name is not a string or not absolute.\n\n## Usage\n\n### ES Modules\n`/foo/callee.mjs`\n```javascript\nimport { dirname } from 'node:path'\n\nimport {\n  stackTrace,\n  getCallerSite,\n  extractFilePath,\n  getCallerFile,\n  getCallerDir\n} from '@mnrendra/stack-trace'\n\nconst callee = () =\u003e {\n  // `stackTrace`:\n  const [callSite1] = stackTrace()\n  const [callSite2] = stackTrace(callee, { limit: 1 }) // Pass the `callee` function as the callee.\n\n  console.log(callSite1.getFileName()) // Output: file:///foo/callee.mjs\n  console.log(callSite2.getFileName()) // Output: file:///foo/caller.mjs\n\n  console.log(callSite1.getFunctionName()) // Output: callee\n  console.log(callSite2.getFunctionName()) // Output: caller\n\n  // `getCallerSite`:\n  const callerSite1 = getCallerSite()\n  const callerSite2 = getCallerSite(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerSite1.getFileName() === callSite1.getFileName()) // Output: true\n  console.log(callerSite2.getFileName() === callSite2.getFileName()) // Output: true\n\n  console.log(callerSite1.getFileName()) // Output: file:///foo/callee.mjs\n  console.log(callerSite2.getFileName()) // Output: file:///foo/caller.mjs\n\n  console.log(callerSite1.getFunctionName() === callSite1.getFunctionName()) // Output: true\n  console.log(callerSite2.getFunctionName() === callSite2.getFunctionName()) // Output: true\n\n  console.log(callerSite1.getFunctionName()) // Output: callee\n  console.log(callerSite2.getFunctionName()) // Output: caller\n\n  // `extractFilePath`:\n  const filePath1 = extractFilePath(callerSite1)\n  const filePath2 = extractFilePath(callerSite2)\n\n  console.log(filePath1) // Output: /foo/callee.mjs\n  console.log(filePath2) // Output: /foo/caller.mjs\n\n  // `getCallerFile`:\n  const callerFile1 = getCallerFile()\n  const callerFile2 = getCallerFile(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerFile1 === filePath1) // Output: true\n  console.log(callerFile2 === filePath2) // Output: true\n\n  console.log(callerFile1) // Output: /foo/callee.mjs\n  console.log(callerFile2) // Output: /foo/caller.mjs\n\n  // `getCallerDir`:\n  const callerDir1 = getCallerDir()\n  const callerDir2 = getCallerDir(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerDir1 === dirname(filePath1)) // Output: true\n  console.log(callerDir2 === dirname(filePath2)) // Output: true\n\n  console.log(callerDir1) // Output: /foo\n  console.log(callerDir2) // Output: /foo\n}\n\nexport default callee\n```\n\n`/foo/caller.mjs`\n```javascript\nimport callee from './callee.mjs'\nconst caller = () =\u003e callee()\ncaller()\n```\n\n### CommonJS\n`/foo/callee.cjs`\n```javascript\nconst { dirname } = require('node:path')\n\nconst {\n  stackTrace,\n  getCallerSite,\n  extractFilePath,\n  getCallerFile,\n  getCallerDir\n} = require('@mnrendra/stack-trace')\n\nconst callee = () =\u003e {\n  // `stackTrace`:\n  const [callSite1] = stackTrace()\n  const [callSite2] = stackTrace(callee, { limit: 1 }) // Pass the `callee` function as the callee.\n\n  console.log(callSite1.getFileName()) // Output: /foo/callee.cjs\n  console.log(callSite2.getFileName()) // Output: /foo/caller.cjs\n\n  console.log(callSite1.getFunctionName()) // Output: callee\n  console.log(callSite2.getFunctionName()) // Output: caller\n\n  // `getCallerSite`:\n  const callerSite1 = getCallerSite()\n  const callerSite2 = getCallerSite(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerSite1.getFileName() === callSite1.getFileName()) // Output: true\n  console.log(callerSite2.getFileName() === callSite2.getFileName()) // Output: true\n\n  console.log(callerSite1.getFileName()) // Output: /foo/callee.cjs\n  console.log(callerSite2.getFileName()) // Output: /foo/caller.cjs\n\n  console.log(callerSite1.getFunctionName() === callSite1.getFunctionName()) // Output: true\n  console.log(callerSite2.getFunctionName() === callSite2.getFunctionName()) // Output: true\n\n  console.log(callerSite1.getFunctionName()) // Output: callee\n  console.log(callerSite2.getFunctionName()) // Output: caller\n\n  // `extractFilePath`:\n  const filePath1 = extractFilePath(callerSite1)\n  const filePath2 = extractFilePath(callerSite2)\n\n  console.log(filePath1) // Output: /foo/callee.cjs\n  console.log(filePath2) // Output: /foo/caller.cjs\n\n  // `getCallerFile`:\n  const callerFile1 = getCallerFile()\n  const callerFile2 = getCallerFile(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerFile1 === filePath1) // Output: true\n  console.log(callerFile2 === filePath2) // Output: true\n\n  console.log(callerFile1) // Output: /foo/callee.cjs\n  console.log(callerFile2) // Output: /foo/caller.cjs\n\n  // `getCallerDir`:\n  const callerDir1 = getCallerDir()\n  const callerDir2 = getCallerDir(callee) // Pass the `callee` function as the callee.\n\n  console.log(callerDir1 === dirname(filePath1)) // Output: true\n  console.log(callerDir2 === dirname(filePath2)) // Output: true\n\n  console.log(callerDir1) // Output: /foo\n  console.log(callerDir2) // Output: /foo\n}\n\nmodule.exports = callee\n```\n\n`/foo/caller.cjs`\n```javascript\nconst callee = require('./callee.cjs')\nconst caller = () =\u003e callee()\ncaller()\n```\n\n\u003e **Note**:\n\u003e\n\u003e - In ES Modules, `getFileName` returns a **file URL** (e.g., `file:///foo`), instead of a **file path** (`/foo`).  \n\u003e *To convert it to a file path, use either `url.fileURLToPath` or the `extractFilePath` utility.*\n\u003e\n\u003e - By default `stackTrace` will capture all caller's frames.  \n\u003e *To capture only a specific number of frames, set the `limit` option to a positive number.*\n\n### Examples\n\n1. **Call from a development project**\n\n`/foo/project-name/src/index.mjs`:\n```javascript\nimport { dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport {\n  stackTrace,\n  getCallerSite,\n  extractFilePath,\n  getCallerFile,\n  getCallerDir\n} from '@mnrendra/stack-trace'\n\n// `stackTrace`:\nconst caller1 = () =\u003e stackTrace()\nconst [callSite] = caller1()\nconst fileName = callSite.getFileName()\nconsole.log(fileName) // Output: file:///foo/project-name/src/index.mjs\nconsole.log(fileURLToPath(fileName)) // Output: /foo/project-name/src/index.mjs\n\n// `getCallerSite`:\nconst caller2 = () =\u003e getCallerSite()\nconst callerSite = caller2()\nconst callerFileName = callerSite.getFileName()\nconsole.log(callerFileName === fileName) // Output: true\nconsole.log(callerFileName) // Output: file:///foo/project-name/src/index.mjs\nconsole.log(fileURLToPath(callerFileName)) // Output: /foo/project-name/src/index.mjs\n\n// `extractFilePath`:\nconst filePath = extractFilePath(callerSite)\nconsole.log(filePath === fileURLToPath(callerFileName)) // Output: true\nconsole.log(filePath) // Output: /foo/project-name/src/index.mjs\n\n// `getCallerFile`:\nconst caller3 = () =\u003e getCallerFile()\nconst callerFile = caller3()\nconsole.log(callerFile === filePath) // Output: true\nconsole.log(callerFile) // Output: /foo/project-name/src/index.mjs\n\n// `getCallerDir`:\nconst caller4 = () =\u003e getCallerDir()\nconst callerDir = caller4()\nconsole.log(callerDir === dirname(filePath)) // Output: true\nconsole.log(callerDir) // Output: /foo/project-name/src\n```\n\n2. **Call from a production package**\n\n`/foo/consumer/node_modules/module-name/dist/index.cjs`:\n```javascript\n\"use strict\";\n\nconst { dirname } = require(\"node:path\");\n\nconst {\n  stackTrace,\n  getCallerSite,\n  extractFilePath,\n  getCallerFile,\n  getCallerDir\n} = require(\"@mnrendra/stack-trace\");\n\n// `stackTrace`:\nconst caller1 = () =\u003e stackTrace();\nconst [callSite] = caller1();\nconst fileName = callSite.getFileName();\nconsole.log(fileName); // Output: /foo/consumer/node_modules/module-name/dist/index.cjs\n\n// `getCallerSite`:\nconst caller2 = () =\u003e getCallerSite();\nconst callerSite = caller2();\nconst callerFileName = callerSite.getFileName();\nconsole.log(callerFileName === fileName); // Output: true\nconsole.log(callerFileName); // Output: /foo/consumer/node_modules/module-name/dist/index.cjs\n\n// `extractFilePath`:\nconst filePath = extractFilePath(callerSite);\nconsole.log(filePath === callerFileName); // Output: true\nconsole.log(filePath); // Output: /foo/consumer/node_modules/module-name/dist/index.cjs\n\n// `getCallerFile`:\nconst caller3 = () =\u003e getCallerFile()\nconst callerFile = caller3()\nconsole.log(callerFile === filePath) // Output: true\nconsole.log(callerFile) // Output: /foo/consumer/node_modules/module-name/dist/index.cjs\n\n// `getCallerDir`:\nconst caller4 = () =\u003e getCallerDir();\nconst callerDir = caller4();\nconsole.log(callerDir === dirname(filePath)); // Output: true\nconsole.log(callerDir); // Output: /foo/consumer/node_modules/module-name/dist\n```\n\n## Types\n\n### `Options`\n[`stackTrace`](#stacktrace)'s [options](#options) interface.\n\n```typescript\nimport {\n  type Options,\n  stackTrace\n} from '@mnrendra/stack-trace'\n\nconst options: Options = {\n  limit: 1\n}\n\nconst caller = (): NodeJS.CallSite[] =\u003e stackTrace(caller, options)\nconst callSites = caller()\nconsole.log(callSites.length) // Output: 1\n```\n\n## Security\n\nWe take security seriously in this project. If you discover a **vulnerability**, we strongly encourage you to report it in a responsible manner.\n\nPlease open a [Security Advisory](https://github.com/mnrendra/stack-trace/security/advisories/new) to report any vulnerabilities.\n\nFor more information, please refer to our [Security Policy](https://github.com/mnrendra/stack-trace/blob/HEAD/SECURITY.md).\n\n## Contributing\n\nWe appreciate your help in making this project better. Please follow the [guidelines](https://github.com/mnrendra/stack-trace/blob/HEAD/CONTRIBUTING.md) to ensure that your contributions are smoothly integrated.\n\n## License\n[MIT](https://github.com/mnrendra/stack-trace/blob/HEAD/LICENSE)\n\n## Author\n[@mnrendra](https://github.com/mnrendra)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnrendra%2Fstack-trace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnrendra%2Fstack-trace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnrendra%2Fstack-trace/lists"}