{"id":28092483,"url":"https://github.com/rehearsal-js/rehearsal-js","last_synced_at":"2025-06-22T22:04:44.504Z","repository":{"id":37533947,"uuid":"428305008","full_name":"rehearsal-js/rehearsal-js","owner":"rehearsal-js","description":"TypeScript CLI handling both migrations and upgrades","archived":false,"fork":false,"pushed_at":"2024-01-01T20:07:31.000Z","size":11275,"stargazers_count":22,"open_issues_count":55,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-11T00:06:29.061Z","etag":null,"topics":["cli","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rehearsal-js.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"Supported-Fixes.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-15T14:51:34.000Z","updated_at":"2025-05-20T04:57:21.000Z","dependencies_parsed_at":"2024-06-19T17:10:15.397Z","dependency_job_id":"ba1f88c2-fde1-4f80-aa00-81ce5b19ab48","html_url":"https://github.com/rehearsal-js/rehearsal-js","commit_stats":{"total_commits":644,"total_committers":18,"mean_commits":35.77777777777778,"dds":0.8027950310559007,"last_synced_commit":"2c5f6ded8cd58b38030bd3d043db9cb4f8647aa8"},"previous_names":[],"tags_count":90,"template":false,"template_full_name":null,"purl":"pkg:github/rehearsal-js/rehearsal-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehearsal-js%2Frehearsal-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehearsal-js%2Frehearsal-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehearsal-js%2Frehearsal-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehearsal-js%2Frehearsal-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rehearsal-js","download_url":"https://codeload.github.com/rehearsal-js/rehearsal-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehearsal-js%2Frehearsal-js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261206113,"owners_count":23124838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","typescript"],"created_at":"2025-05-13T13:17:41.596Z","updated_at":"2025-06-22T22:04:39.464Z","avatar_url":"https://github.com/rehearsal-js.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rehearsal\n\n[![Build Status](https://github.com/rehearsal-js/rehearsal-js/workflows/CI/badge.svg)](https://github.com/rehearsal-js/rehearsal-js/actions?workflow=CI)\n[![Version](https://img.shields.io/npm/v/@rehearsal/cli.svg)](https://www.npmjs.com/package/@rehearsal/cli)\n\nRehearsal is a CLI tool with 3 commands (Graph | Move | Fix), which aim to improve the experience of both migrating to TypeScript and once migrated, upgrading your repo to future versions of TypeScript.\n\n## How does Rehearsal help with TypeScript migrations?\n\nRehearsal is capable of maintaining proper migration order from leaf to trunk. It is generic enough to allow for the migration of JS to TS for all web applications. It allows for both multi-pass and single-pass migration processes. It provides industry standard, type inference wherever possible and provides the ability to monitor micro migration steps with macro insights.\n\nOnce your source code is moved to TypeScript, Rehearsal will fix as many errors as possible. Unresolved errors will be annotated and suppressed with a [Rehearsal TODO](#what-is-a-rehearsal-todo). This allows for safe iteration, to a strictly typed project.\n\nThe following codefixes are supported by Rehearsal, which resolve over one hundred different TypeScript diagnostics errors. The detailed list is published [here](https://github.com/rehearsal-js/rehearsal-js/blob/master/Supported-Fixes.md)\n\n## How does Rehearsal help with upgrading versions of TypeScript?\n\nRehearsal also supports the continuous testing of pre-released versions of TypeScript. Essentially this is running the `fix` command with an early-release TypeScript version in a GH Action. For example after you’ve migrated your app to TypeScript with strictness you would run this action daily against the beta version of TypeScript.\n\nRehearsal `fix` will generate a report showing you exactly what will break, what was auto fixed by Rehearsal and what will need to be fixed manually. With flagged compiler diagnostic errors culled into a multi-format report which can be embedded within a PR. This provides plenty of headroom to mitigate any breaking changes in the TypeScript compiler against the app.\n\n# Setup / Pre-Reqs\n\nEnsure your project has the following [pre-reqs](https://github.com/rehearsal-js/rehearsal-js/blob/master/packages/cli/src/prereqs.ts) for dependencies and configurations:\n\n## Dependencies\n\nThese deps are the bare minimum versions and config required for Rehearsal to infer types in your project. All deps listed are \u003e= the version specified:\n\n### Base For All Projects\n\n```\n  typescript: '4.9.0',\n  prettier: '3.0.0',\n  eslint: '8.0.0',\n  'eslint-import-resolver-typescript': '2.5.0',\n  'eslint-plugin-import': '2.0.0',\n  'eslint-plugin-node': '11.0.0',\n  'eslint-plugin-unicorn': '40.0.0',\n  '@typescript-eslint/eslint-plugin': '5.0.0',\n  '@typescript-eslint/parser': '5.0.0'\n```\n\n### Base + Ember\n\n```\n  '@glint/core': '1.0.0',\n  '@glint/environment-ember-loose': '1.0.0',\n  '@glint/environment-ember-template-imports': '1.0.0',\n  '@glint/template': '1.0.0',\n  'eslint-plugin-ember': '11.0.0',\n  'prettier-plugin-ember-template-tag': '1.0.0'\n```\n\n### Base + Glimmer\n\n```\n  '@glint/core': '1.0.0',\n  '@glint/environment-glimmerx': '1.0.0',\n  '@glint/template': '1.0.0',\n  'eslint-plugin-ember': '11.0.0',\n  '@glimmerx/prettier-plugin-component-templates': '0.6.0'\n```\n\n## ESLint Config\n\nESlint Config file must have the parser set to `@typescript-eslint/parser`\n\n## TSConfig\n\nThe root tsconfig.json must have the following key/values:\n\n### Base For All Projects\n\n```\ncompilerOptions: {\n  strict: true,\n  skipLibCheck: true,\n}\n```\n\n### Base + Ember\n\n```\nglint: {\n  environment: 'ember-loose',\n}\n```\n\n### Base + Glimmer\n\n```\nglint: {\n  environment: 'glimmerx',\n}\n```\n\n## Services Mapping\n\nFor Ember.js apps only: A required [services](https://guides.emberjs.com/release/services/#toc_accessing-services) mapping file at the project root as `.rehearsal/services-map.json`. This is for Rehearsal to improve type inference and migration-graph as to properly map services against the fully-qualified path as key/value path. Note the value path here must match the tsconfig.json paths for a given service. eg.\n\n```\n# .rehearsal/services-map.json\n{\n  \"boo-service\": \"boo/services/boo-service\",\n  \"goo-service\": \"services/goo\",\n  \"mooService\": \"services/moo/moo\",\n  \"@some-org/some-package@mapped\": \"@some-org/some-package/services/from-service-map\"\n}\n```\n\n# Installation\n\nAdd `@rehearsal/cli` to your project as a **devDependency**.\n\n```bash\nyarn add -D @rehearsal/cli@latest typescript@latest\n# or\npnpm add -D @rehearsal/cli@latest typescript@latest\n```\n\nCreate a tsconfig.json in your project root, if it doesn't already exist.\n\n```bash\ntsc --init\n```\n\nNote: `@rehearsal/cli` must be installed as a devDependency as it requires your project's version of TypeScript to run.\n\n# Usage\n\nOnce installed with pre-req's complete, invoke using your package manager or directly:\n\n```bash\nyarn rehearsal\n# or\npnpm rehearsal\n# or\nrehearsal\n```\n\n## Available Commands\n\nRehearsal CLI exposes 3 commands `graph` | `move` | `fix`. These commands function in isolation and are expected to be run in sequence. This \"pause\" in execution allows the developer time to handle the output and mutations of each command.\n\n## `rehearsal graph`\n\n```\nrehearsal graph\n\nUsage: rehearsal graph [options] [srcPath]\n\nproduces the migration order of files given a source path\n\nArguments:\n  srcPath                  path to a directory or file (default: current working directory)\n\nOptions:\n  --ignore [globs...]      comma-delimited list of globs to ignore eg. '--ignore\n                           tests/**/*,types/**/*' (default: [])\n  -o, --output \u003cfilepath\u003e  output path for a JSON or grapviz format of the graph order eg.\n                           '--output graph.json' or '--output graph.dot'\n  -x, --externals          includes external dependencies in the output. only valid with\n                           '--output'.\n  -h, --help               display help for command\n```\n\nThe graph command produces a file import graph for a project. This is useful for seeing what files will be migrated and moved.\n\nIf your project is very large (a monorepo or workspace) you can use the rehearsal graph command to find what is the leaf-most package and migrate it first. Using the leaf-most file, will ensure any settled types, will propagate to dependents, improving the overall migration experience and quality of type inference.\n\nThe `--externals` flag is helpful for finding which external dependencies are either missing types or missing in package.json. This will be included in the generated `--output` file and annotated as either \"missing types\" or \"missing from package.json\".\n\n## `rehearsal move`\n\n```\nrehearsal move\n\nUsage: rehearsal move|mv [options] [srcPath]\n\ngraph aware git mv from .js -\u003e .ts\n\nArguments:\n  srcPath              path to a directory or file (default: \"\")\n\nOptions:\n  --graph                   fixing all file(s) within the graph, which might include files\n                            outside of the current directory\n  --ignore [globs...]       comma-delimited list of globs to ignore eg. '--ignore\n                            tests/**/*,types/**/*' (default: [])\n  -d, --dryRun              do nothing; only show what would happen (default: false)\n  -h, --help                display help for command'\n```\n\nThis command performs a file rename (e.g. `.ts`, `.tsx`, `.gts`, `.mjs`) and git move against the targeted files in your project and will leverage the migration graph. Once this command has finished running, commit the changes and continue to the `fix` command.\n\n## `rehearsal fix`\n\n```\nrehearsal fix\n\nUsage: rehearsal fix|infer [options] [srcPath]\n\nfixes typescript compiler errors by inferring types on .*ts files\n\nArguments:\n  srcPath                  path to a directory or file (default: current working directory)\n\n\nOptions:\n  --graph                   fixing all file(s) within the graph, which might include files\n                            outside of the current directory\n  --ignore [globs...]       comma-delimited list of globs to ignore eg. '--ignore\n                            tests/**/*,types/**/*' (default: [])\n  -f, --format \u003cformat\u003e     report format separated by comma, e.g. -f json,sarif,md,sonarqube\n                            (default: [\"sarif\"])\n  -m, --mode \u003cmode\u003e         the application of codefixes (choices: \"drain\", \"single-pass\",\n                            default: \"drain\")\n  -h, --help                display help for command\n  --skipChecks [checks...]  skip specified pre-flights checks (not recommended), eg.\n                            --skipChecks eslint,deps\n```\n\nThis command will run against a TypeScript project and infer types for you. There's a lot going on under the hood here!\n\nRehearsal will do its best to infer types, via a series of plugins (rarely will Rehearsal infer a loose type). Type inference is a complex problem, and Rehearsal is not perfect. Under the hood Rehearsal will infer types from JSDoc, ESLint, TypeScript Compiler and Rehearsal Plugins. Rehearsal relies on the projects tsconfig.json being configured correctly, as it pertains to [include](https://www.typescriptlang.org/tsconfig#include), [references](https://www.typescriptlang.org/tsconfig#references) and [paths](https://www.typescriptlang.org/tsconfig#paths).\n\nMany times there are multiple possible types Rehearsal can infer, and it will choose the first one. This is not always the correct type, and you will need to manually fix these errors. Rehearsal will report these errors in the report file and with inline \"`@ts-expect-error @rehearsal TODO`\" comments in the code.\n\n# Workflow\n\nFor a given project like:\n\n```\nvitest.config.js\ndocs\ntest\n├──main.test.js\nsrc\n├──app.js\n└── lib\n    ├── gen-random-grid.js\n    └── nested\n        ├── apply-rules.js\n        └── get-live-neighbor-count.js\n```\n\n## Graph\n\nSome of these files import into each other. We want to infer the types of the outermost leaf first. Have Rehearsal look at the graph of files, and determine the file migration order, ignore some files and directories and output the graph into a .dot file.\n\n```\nrehearsal graph --output migration-graph.dot --ignore 'docs, vitest.*'\n...\n✔ Analyzing project dependency graph ...\n  › Graph order for 'cgol-js-app':\n    ./src/lib/nested/get-live-neighbor-count.js\n    ./src/lib/nested/apply-rules.js\n    ./src/lib/gen-random-grid.js\n    ./src/app.js\n    ./test/main.test.js\n```\n\nThe VSCode extension [Graphviz Interactive Preview](https://marketplace.visualstudio.com/items?itemName=tintinweb.graphviz-interactive-preview) is great for rendering .dot files within VSCode:\n\n\u003cimg width=\"1236\" alt=\"migration-graph-dot\" src=\"https://github.com/rehearsal-js/rehearsal-js/assets/10506014/3928ad40-1060-4b3b-acfc-4a424c53d631\"\u003e\n\nRehearsal has traversed the import graph in this _trivial_ example and provided the exact order the migration should happen, starting with `src/lib/nested/get-live-neighbor-count.js`.\n\n## Move\n\nLets start migrating files. Use `rehearsal move` to move files to TypeScript.\n\n```\nrehearsal move . --ignore 'docs, vitest.*'\n...\n✔ Analyzing project dependency graph ...\n✔ Executing git mv ...\n  › renamed:\n    ./src/lib/nested/get-live-neighbor-count.js -\u003e ./src/lib/nested/get-live-neighbor-count.ts\n    ./src/lib/nested/apply-rules.js -\u003e ./src/lib/nested/apply-rules.ts\n    ./src/lib/gen-random-grid.js -\u003e ./src/lib/gen-random-grid.ts\n    ./src/app.js -\u003e ./src/app.ts\n    ./test/main.test.js -\u003e ./test/main.test.ts\n```\n\nWe've pointed Rehearsal at the root of our project `.`, ignored some files and directories and had Rehearsal `move` while leveraging the import graph. Our project is now partially migrated to TypeScript. Before we can continue to the next step of implementing types, we need to manually configure our project and install missing devDependencies.\n\n## Fix\n\nLet's run Rehearsal `fix` without doing this and see what happens.\n\n```\nrehearsal fix . --ignore 'docs, vitest.*'\n...\n✖ Please install the following missing devDependencies and try again:\n  \"prettier\": \"^3.0.0\",\n  \"eslint\": \"^8.0.0\"\n◼ Analyzing project dependency graph\n◼ Infer Types\n```\n\nRehearsal has a series of pre-flight checks it will validate against [pre-reqs](https://github.com/rehearsal-js/rehearsal-js/blob/master/packages/cli/src/prereqs.ts) before it can start inferring types. Follow the \"Setup / Pre-Reqs\" directions above adding any missing config files (tsconfig.json / .eslintrc.json) and missing devDependencies ... Now lets re-run `fix` against our project and see what we get:\n\n```\nrehearsal fix . --ignore 'docs, vitest.*'\n...\n✔ Initialize\n✔ Analyzing project dependency graph ...\n✔ Types Inferred\n  10 errors caught by rehearsal\n  6 have been fixed by rehearsal\n  4 errors need to be fixed manually\n  -- 4 ts errors, marked by @ts-expect-error @rehearsal TODO\n  -- 0 eslint errors, with details in the report\n```\n\nOur project is now on TypeScript with types! Rehearsal has caught 10 TypeScript compiler errors and auto-fixed 6 of them for us. The next step is commit our changes and review the generated Rehearsal report to manually type tighten wherever Rehearsal has flagged a TODO.\n\nIn this example Rehearsal has fixed 60% of the compiler errors. Sometimes however, the types Rehearsal can inference are minimal. Which is why the `fix` command can be run repeatedly ex. `fix` -\u003e manual type tuning -\u003e `fix` -\u003e manual type tuning -\u003e `fix`.\n\n# Rehearsal Reports\n\nRehearsal will generate a report file in the process.cwd() directory.\n\n```\nrehearsal-report.json\nrehearsal-report.sarif\n```\n\n- The `rehearsal-report.*` file contains all the information that Rehearsal has gathered during the fix process. It also contains the list of errors that need to be fixed manually.\n\n- The report is available with multiple [formatters](https://github.com/rehearsal-js/rehearsal-js/tree/master/packages/reporter/src/formatters) in JSON, MD, SARIF and SONARQUBE.\n\n- You can [view the SARIF report in VSCode](https://marketplace.visualstudio.com/items?itemName=MS-SarifVSCode.sarif-viewer) and easily navigate to the errors from the report directly into your code.\n\n- Additionally, Rehearsal will inline `@ts-expect-error @rehearsal TODO` comments in the code for each error.\n\n## What is a `@rehearsal TODO`\n\nA Rehearsal TODO is a comment which provides insight to a developer on exactly what and where the TypeScript compiler has flagged an issue.\n\nAn example of a @rehearsal TODO:\n\n```typescript\n/* @ts-expect-error @rehearsal TODO TS2339: Property 'id' does not exist on type 'object'. */\nlet id = entityInfo.id;\n```\n\n- `@ts-expect-error` is an assertion that the following line will have a type error and the TypeScript compiler should ignore it.\n  The TypeScript error that we need to address is: TS2339: Property 'id' does not exist on type 'object'.\n\n[View the list of rehearsal's supported fixes](https://github.com/rehearsal-js/rehearsal-js/blob/master/Supported-Fixes.md)\n\n## How to fix a `@rehearsal TODO`\n\n```typescript\n/* @ts-expect-error @rehearsal TODO TS2339: Property 'id' does not exist on type 'object'. */\nlet id = entityInfo.id;\n```\n\n- In this case the entityInfo object would need to declare that it has a property called id through a type or interface.\n- Once fixed, if you open your IDE (VSCode for example) you should notice a **red squiggly** underline to the `@ts-expect-error` annotation. The red squiggle underline, is TypeScript communicating that expected error will no longer occur if this were to compile.\n\n# Improve Type Inference\n\n## Add Missing Types\n\nYou can improve typing by adding additional typed packages to the project. For example:\n\n```\n@types/node\n@types/jest\n@types/mocha\n```\n\nYou will find out which types packages to add after you run rehearsal migrate and when you inspect the rehearsal TODOS. Once you add these packages, run `rehearsal fix`\n\n## Remove Invalid JSDoc Comments\n\nBy default Rehearsal will prioritize types coming from JSDoc directives as these are explictly stated from the user. However in instances where JSDoc directives are invalid / outdated, the type inference will also be invalid. To remedy this simply delete the invalid JSDoc comment in question and re-run `rehearsal fix`.\n\n# Post Migration\n\n## Package.json Directives\n\nAfter your project has been migrated to TypeScript, remember to update your export paths in package.json. eg `main`, `files`, and `types`. Rehearsal will handle your TypeScript migration, however it will not handle the build step in transpiling TS -\u003e JS. For that take a look at [integrating-with-build-tools](https://www.typescriptlang.org/docs/handbook/integrating-with-build-tools.html).\n\n#### JS Dist Files\n\n`main`: point to the transpiled .js file in dist (produced either by babel or tsc)\n`files`: point to the transpiled .js file in dist (produced either by babel or tsc)\n\n#### Type Declaration Files\n\n`types`: point to the declaration files `d.ts` in dist (produced by tsc)\n\n# Known Limitations\n\nRehearsal will do its best to infer types, via a series of plugins. Type inference is a complex problem, and Rehearsal is not perfect. Under the hood Rehearsal will infer types from JSDoc, ESLint, TypeScript Compiler and Rehearsal Plugins. Many times there are multiple possible types Rehearsal can infer, and it will choose the first one. This is not always the correct type, and you will need to manually fix these errors. Rehearsal will report these errors in the \"rehearsal-report\" file and with inline \"`@ts-expect-error @rehearsal TODO`\" comments in the code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehearsal-js%2Frehearsal-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frehearsal-js%2Frehearsal-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehearsal-js%2Frehearsal-js/lists"}