{"id":47291865,"url":"https://github.com/async3619/foresthouse","last_synced_at":"2026-04-01T19:03:08.625Z","repository":{"id":344600607,"uuid":"1182362875","full_name":"async3619/foresthouse","owner":"async3619","description":"TypeScript-first Node.js CLI for source import trees, React usage trees, and package dependency trees.","archived":false,"fork":false,"pushed_at":"2026-03-28T09:49:40.000Z","size":382,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"dev","last_synced_at":"2026-03-28T10:51:48.763Z","etag":null,"topics":["cli","dependency-graph","import-tree","monorepo","nextjs","nodejs","react","static-analysis","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/async3619.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-15T12:21:44.000Z","updated_at":"2026-03-28T09:49:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/async3619/foresthouse","commit_stats":null,"previous_names":["async3619/foresthouse"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/async3619/foresthouse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async3619%2Fforesthouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async3619%2Fforesthouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async3619%2Fforesthouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async3619%2Fforesthouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/async3619","download_url":"https://codeload.github.com/async3619/foresthouse/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async3619%2Fforesthouse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291017,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli","dependency-graph","import-tree","monorepo","nextjs","nodejs","react","static-analysis","typescript"],"created_at":"2026-03-16T09:06:36.892Z","updated_at":"2026-04-01T19:03:08.612Z","avatar_url":"https://github.com/async3619.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# foresthouse 🌲🏠\n\n[![npm version](https://img.shields.io/npm/v/foresthouse.svg?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/foresthouse)\n[![codecov](https://img.shields.io/codecov/c/github/async3619/foresthouse?style=flat\u0026colorA=000000\u0026colorB=000000)](https://codecov.io/gh/async3619/foresthouse)\n[![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json\u0026style=flat\u0026colorA=000000\u0026colorB=000000)](https://codspeed.io/async3619/foresthouse?utm_source=badge)\n[![license](https://img.shields.io/npm/l/foresthouse?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/foresthouse)\n\n`foresthouse` is a modern TypeScript-first Node.js CLI that can print source import trees, React usage trees, and package-manifest dependency trees.\n\n## Installation\n\n```bash\nnpm install -g foresthouse\n```\n\nYou can also run it without a global install:\n\n```bash\nnpx foresthouse --help\npnpm dlx foresthouse --help\nyarn dlx foresthouse --help\nbunx foresthouse --help\n```\n\n## What it does\n\n- Analyzes source import trees from JavaScript and TypeScript entry files (`.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs`, `.mts`, `.cts`)\n- Resolves local imports, re-exports, `require()`, and string-literal dynamic `import()`\n- Honors the nearest `tsconfig.json` or `jsconfig.json`, including `baseUrl` and `paths`\n- Expands sibling workspace packages by default, including their own `tsconfig` alias rules\n- Analyzes React component and hook usage trees from explicit entry files or inferred Next.js app and pages routes\n- Shows React tree changes relative to a Git ref or range with `foresthouse react --diff`\n- Reads `package.json` manifests to show package-level dependency trees for single packages and monorepos\n- Shows dependency-tree changes relative to a Git ref or range with `foresthouse deps --diff`\n- Prints an ASCII tree by default, or JSON with `--json`\n- Colorizes ASCII output automatically when the terminal supports ANSI colors\n\n## Usage\n\n```text\nUsage:\n  $ foresthouse \u003ccommand\u003e [options]\n\nCommands:\n  deps \u003cdirectory\u003e     Analyze package.json dependencies from a package directory.\n  import [entry-file]  Analyze an entry file and print its dependency tree.\n  react [entry-file]   Analyze React usage from an entry file.\n\nFor more info, run any command with the `--help` flag:\n  $ foresthouse deps --help\n  $ foresthouse import --help\n  $ foresthouse react --help\n\nOptions:\n  -h, --help     Display this message\n  -v, --version  Display version number\n```\n\n### Commands\n\n- `foresthouse import \u003centry-file\u003e`: analyzes a JavaScript or TypeScript entry file and prints a dependency tree by following imports, re-exports, `require()`, and dynamic `import()`.\n- `foresthouse react [entry-file]`: analyzes React component, hook, and render relationships and prints a React usage tree. It also supports automatic Next.js entry discovery with `--nextjs`, plus Git-based tree diffs with `--diff`.\n- `foresthouse deps \u003cdirectory\u003e`: reads `package.json` manifests and workspace structure from a package directory and prints a package dependency tree. Use `--diff` to show only changes relative to a Git ref or range.\n\n### Example\n\n```bash\nnode dist/cli.mjs import src/main.ts --cwd test/fixtures/basic\n```\n\nOutput:\n\n```text\nsrc/main.ts\n├─ src/app.tsx\n│  ├─ src/shared/util.ts\n│  └─ src/components/button.tsx\n├─ src/widget-loader.ts\n│  └─ [dynamic] src/widgets/chart.ts\n```\n\n### `foresthouse import --help`\n\nAnalyzes a source dependency tree from a single entry file. You can provide the entry with either a positional argument or `--entry`, and use `--json` for machine-readable output.\n\n```text\nUsage:\n  $ foresthouse import \u003centry-file\u003e [options]\n\nOptions:\n  --entry \u003cpath\u003e       Entry file to analyze.\n  --cwd \u003cpath\u003e         Working directory used for relative paths.\n  --config \u003cpath\u003e      Explicit tsconfig.json or jsconfig.json path.\n  --include-externals  Include packages and Node built-ins in the tree.\n  --no-workspaces      Do not expand sibling workspace packages into source subtrees. (default: true)\n  --project-only       Restrict traversal to the active tsconfig.json or jsconfig.json project.\n  --unused             Include imports that are never referenced.\n  --json               Print the dependency tree as JSON.\n  -h, --help           Display this message\n```\n\n### `foresthouse react --help`\n\nAnalyzes React component and hook usage relationships. You can provide an entry file directly, or use `--nextjs` to discover Next.js route entries automatically.\n\n```text\nUsage:\n  $ foresthouse react [entry-file] [options]\n\nOptions:\n  --diff \u003cgit-ref-or-range\u003e  Show only React tree changes relative to a Git revision or range.\n  --cwd \u003cpath\u003e     Working directory used for relative paths.\n  --config \u003cpath\u003e  Explicit tsconfig.json or jsconfig.json path.\n  --nextjs         Infer Next.js page entries from app/ and pages/ when no entry is provided.\n  --filter \u003cmode\u003e  Limit output to `component`, `hook`, or `builtin` usages.\n  --builtin        Include built-in HTML nodes in the React tree.\n  --no-workspaces  Do not expand sibling workspace packages into source subtrees. (default: true)\n  --project-only   Restrict traversal to the active tsconfig.json or jsconfig.json project.\n  --json           Print the React usage tree as JSON.\n  -h, --help       Display this message\n```\n\nReact diff mode compares React usage graphs rather than raw file text diffs. A single ref like `--diff HEAD~3` compares that tree to the current working tree, while ranges such as `HEAD~3..HEAD` or `origin/dev...HEAD` compare two committed Git trees.\n\nExample React diff output:\n\n```text\n~ apps/site/pages/index.tsx:21:45\n~ \u003cHome /\u003e [component] (apps/site/pages/index.tsx)\n└─ ~ \u003cHero /\u003e [component] (apps/site/src/features/Main/Hero/Hero.tsx)\n   └─ + useForm() [hook] (react-hook-form)\n```\n\nIn this example, the page entry itself is unchanged as source text, but its reachable React graph changed because `\u003cHero /\u003e` started calling `useForm()`.\n\n### `foresthouse deps --help`\n\nAnalyzes package-level dependency trees for both single-package projects and monorepos. Use `--diff` to show only dependency changes relative to a Git ref or range.\n\n```text\nUsage:\n  $ foresthouse deps \u003cdirectory\u003e [options]\n\nOptions:\n  --diff \u003cgit-ref-or-range\u003e  Show only dependency-tree changes relative to a Git revision or range.\n  --json                     Print the package tree as JSON.\n  -h, --help                 Display this message\n```\n\nCommon examples:\n\n- `foresthouse import src/main.ts`\n- `foresthouse import --entry src/main.ts --cwd test/fixtures/basic`\n- `foresthouse react src/App.tsx`\n- `foresthouse react src/App.tsx --diff origin/dev...HEAD`\n- `foresthouse react pages/index.tsx --cwd . --diff HEAD~3..HEAD`\n- `foresthouse react --nextjs --cwd .`\n- `foresthouse deps .`\n- `foresthouse deps ./packages/a`\n- `foresthouse deps . --diff origin/dev...HEAD`\n\n## Benchmark\n\n\u003cdetails\u003e\n\u003csummary\u003eEnvironment\u003c/summary\u003e\n\n```\n+----------+--------------+\n| Metric   | Value        |\n+----------+--------------+\n| Platform | darwin arm64 |\n| Node     | v24.14.0     |\n| CPU      | Apple M2 Max |\n| Cores    | 12           |\n| Memory   | 32.0 GB      |\n+----------+--------------+\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eforesthouse deps\u003c/code\u003e\u003c/summary\u003e\n\n```\n+-----------+---------+-----------------+---------+---------+----------+----------+-------------------------------------------+\n| Target    | Options | Project         | LOC     | Status  | Median   | P95      | Note                                      |\n+-----------+---------+-----------------+---------+---------+----------+----------+-------------------------------------------+\n| directory | (none)  | supabase-studio | 493,979 | ok      | 184.37ms | 216.11ms |                                           |\n| directory | (none)  | cal-com-web     | 218,466 | ok      | 182.89ms | 196.84ms |                                           |\n| directory | (none)  | outline-app     | 87,658  | ok      | 171.15ms | 172.83ms |                                           |\n| directory | (none)  | dub-web         | 345,285 | ok      | 181.13ms | 186.52ms |                                           |\n| directory | (none)  | commerce        | 3,968   | skipped | -        | -        | Package manifest is missing a valid name. |\n| directory | (none)  | formbricks-web  | 247,895 | ok      | 171.78ms | 181.43ms |                                           |\n| directory | (none)  | platforms       | 1,308   | skipped | -        | -        | Package manifest is missing a valid name. |\n| directory | (none)  | t3-nextjs       | 711     | ok      | 173.51ms | 184.11ms |                                           |\n+-----------+---------+-----------------+---------+---------+----------+----------+-------------------------------------------+\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eforesthouse import\u003c/code\u003e\u003c/summary\u003e\n\n```\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n| Target | Options         | Project         | LOC     | Status | Median    | P95       | Note |\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n| entry  | (none)          | supabase-studio | 493,979 | ok     | 1014.23ms | 1413.45ms |      |\n| entry  | --project-only  | supabase-studio | 493,979 | ok     | 782.13ms  | 838.64ms  |      |\n| entry  | --no-workspaces | supabase-studio | 493,979 | ok     | 782.02ms  | 833.00ms  |      |\n| entry  | (none)          | cal-com-web     | 218,466 | ok     | 1042.08ms | 1109.40ms |      |\n| entry  | --project-only  | cal-com-web     | 218,466 | ok     | 284.00ms  | 426.76ms  |      |\n| entry  | --no-workspaces | cal-com-web     | 218,466 | ok     | 250.25ms  | 320.31ms  |      |\n| entry  | (none)          | outline-app     | 87,658  | ok     | 600.36ms  | 840.67ms  |      |\n| entry  | (none)          | dub-web         | 345,285 | ok     | 259.89ms  | 309.41ms  |      |\n| entry  | --project-only  | dub-web         | 345,285 | ok     | 253.14ms  | 254.04ms  |      |\n| entry  | --no-workspaces | dub-web         | 345,285 | ok     | 257.75ms  | 259.07ms  |      |\n| entry  | (none)          | commerce        | 3,968   | ok     | 199.93ms  | 205.46ms  |      |\n| entry  | (none)          | formbricks-web  | 247,895 | ok     | 333.93ms  | 405.91ms  |      |\n| entry  | --project-only  | formbricks-web  | 247,895 | ok     | 313.35ms  | 342.89ms  |      |\n| entry  | --no-workspaces | formbricks-web  | 247,895 | ok     | 296.93ms  | 355.40ms  |      |\n| entry  | (none)          | platforms       | 1,308   | ok     | 189.81ms  | 199.19ms  |      |\n| entry  | (none)          | t3-nextjs       | 711     | ok     | 217.94ms  | 247.73ms  |      |\n| entry  | --project-only  | t3-nextjs       | 711     | ok     | 202.47ms  | 215.69ms  |      |\n| entry  | --no-workspaces | t3-nextjs       | 711     | ok     | 200.04ms  | 200.67ms  |      |\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eforesthouse react\u003c/code\u003e\u003c/summary\u003e\n\n```\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n| Target | Options         | Project         | LOC     | Status | Median    | P95       | Note |\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n| entry  | (none)          | supabase-studio | 493,979 | ok     | 1333.58ms | 1494.41ms |      |\n| entry  | --project-only  | supabase-studio | 493,979 | ok     | 996.02ms  | 1059.62ms |      |\n| entry  | --no-workspaces | supabase-studio | 493,979 | ok     | 1005.37ms | 1137.48ms |      |\n| nextjs | (none)          | supabase-studio | 493,979 | ok     | 3059.37ms | 3534.34ms |      |\n| nextjs | --project-only  | supabase-studio | 493,979 | ok     | 2602.21ms | 2716.90ms |      |\n| nextjs | --no-workspaces | supabase-studio | 493,979 | ok     | 2716.09ms | 3007.85ms |      |\n| entry  | (none)          | cal-com-web     | 218,466 | ok     | 1832.85ms | 1859.41ms |      |\n| entry  | --project-only  | cal-com-web     | 218,466 | ok     | 244.83ms  | 347.60ms  |      |\n| entry  | --no-workspaces | cal-com-web     | 218,466 | ok     | 242.31ms  | 249.87ms  |      |\n| nextjs | (none)          | cal-com-web     | 218,466 | ok     | 4418.86ms | 5438.14ms |      |\n| nextjs | --project-only  | cal-com-web     | 218,466 | ok     | 1400.78ms | 1498.16ms |      |\n| nextjs | --no-workspaces | cal-com-web     | 218,466 | ok     | 1405.46ms | 1452.13ms |      |\n| entry  | (none)          | outline-app     | 87,658  | ok     | 931.17ms  | 946.86ms  |      |\n| entry  | (none)          | dub-web         | 345,285 | ok     | 265.47ms  | 273.70ms  |      |\n| entry  | --project-only  | dub-web         | 345,285 | ok     | 266.99ms  | 268.79ms  |      |\n| entry  | --no-workspaces | dub-web         | 345,285 | ok     | 265.71ms  | 276.33ms  |      |\n| nextjs | (none)          | dub-web         | 345,285 | ok     | 1568.90ms | 1964.85ms |      |\n| nextjs | --project-only  | dub-web         | 345,285 | ok     | 1589.73ms | 1624.88ms |      |\n| nextjs | --no-workspaces | dub-web         | 345,285 | ok     | 1507.13ms | 1859.47ms |      |\n| entry  | (none)          | commerce        | 3,968   | ok     | 213.42ms  | 218.10ms  |      |\n| nextjs | (none)          | commerce        | 3,968   | ok     | 222.09ms  | 227.03ms  |      |\n| entry  | (none)          | formbricks-web  | 247,895 | ok     | 381.40ms  | 391.71ms  |      |\n| entry  | --project-only  | formbricks-web  | 247,895 | ok     | 321.40ms  | 331.36ms  |      |\n| entry  | --no-workspaces | formbricks-web  | 247,895 | ok     | 323.95ms  | 327.12ms  |      |\n| nextjs | (none)          | formbricks-web  | 247,895 | ok     | 1118.63ms | 1303.93ms |      |\n| nextjs | --project-only  | formbricks-web  | 247,895 | ok     | 1041.12ms | 1062.49ms |      |\n| nextjs | --no-workspaces | formbricks-web  | 247,895 | ok     | 1055.21ms | 1107.24ms |      |\n| entry  | (none)          | platforms       | 1,308   | ok     | 201.30ms  | 205.59ms  |      |\n| nextjs | (none)          | platforms       | 1,308   | ok     | 202.98ms  | 209.47ms  |      |\n| entry  | (none)          | t3-nextjs       | 711     | ok     | 231.38ms  | 234.95ms  |      |\n| entry  | --project-only  | t3-nextjs       | 711     | ok     | 212.96ms  | 214.89ms  |      |\n| entry  | --no-workspaces | t3-nextjs       | 711     | ok     | 212.09ms  | 218.98ms  |      |\n| nextjs | (none)          | t3-nextjs       | 711     | ok     | 232.97ms  | 233.53ms  |      |\n| nextjs | --project-only  | t3-nextjs       | 711     | ok     | 211.67ms  | 215.33ms  |      |\n| nextjs | --no-workspaces | t3-nextjs       | 711     | ok     | 211.65ms  | 215.49ms  |      |\n+--------+-----------------+-----------------+---------+--------+-----------+-----------+------+\n```\n\n\u003c/details\u003e\n\n## Development\n\n```bash\ncorepack enable\npnpm install\npnpm run test:unit\npnpm run test:e2e\npnpm run check\n```\n\n- Unit tests live next to source files as `src/**/*.spec.ts`.\n- End-to-end command tests live under `e2e/`.\n- Benchmarks live next to analyzers as `src/**/*.bench.ts` and run with `pnpm exec vitest bench --run --config vitest.bench.config.ts`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync3619%2Fforesthouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasync3619%2Fforesthouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync3619%2Fforesthouse/lists"}