Stacks

Rename a symbol across the repo in TypeScript with Atlas (2026)

Updated 8 min read

To rename a symbol across a TypeScript repo with Atlas, never start with find-and-replace. Atlas runs the lsp tool's findReferences operation on the symbol first, which returns the authoritative callsite list from the TypeScript language server, including the imports resolved through path aliases in tsconfig.json that a text search would miss. Atlas then runs grep for the old name to catch the occurrences the type system never sees: string literals, JSDoc comments, docs, and config. The mechanical renames go through edit with replaceAll where the match is unambiguous per file, and where a single occurrence must change, edit enforces uniqueness and throws Found multiple matches for oldString rather than corrupting the file. Finally Atlas compiles and runs vitest through bash, then greps once more for the old name to prove zero remaining hits. pnpm resolves the workspace, and prettier normalizes the result.

Why is find-and-replace dangerous for a TypeScript rename?

A rename is where naive find-and-replace does the most damage. In a 2026 TypeScript monorepo, searching for the identifier User matches UserProfile, useUser, a route string in src/routes.ts, and a comment. Atlas avoids all four failure modes by asking the TypeScript language server for the real reference set through the lsp tool's findReferences operation.

TypeScript's rename problem has two halves that pull in opposite directions. The type system knows things text search cannot: that an import in src/api/client.ts resolved through the @app/* path alias in tsconfig.json points at the same declaration as a relative import three packages away, and that a re-export in an index.ts barrel file is the same symbol under a different name. Text search knows things the type system cannot: that the old name also appears in a template literal, in a Zod schema key, in a test fixture in tests/fixtures/, and in the README. Atlas uses the lsp tool's findReferences to get the true reference set from the language server, and grep to catch strings and docs the compiler does not see. Neither tool alone is sufficient for a TypeScript rename.

How does Atlas use findReferences on a TypeScript symbol?

Atlas runs the lsp tool's findReferences operation on the symbol to get the authoritative callsite list from the language server. In 2026, for an exported function in src/lib/auth.ts, that returns every import site across a pnpm workspace, including the ones routed through tsconfig.json path aliases and barrel re-exports, which is exactly the set grep cannot reconstruct.

findReferences is the first step because it is the only step that is provably complete with respect to the TypeScript compiler. It resolves declaration merging, so an interface augmented in two files is one symbol. It resolves the @app/* alias in tsconfig.json, so an import from @app/lib/auth and one from ../../lib/auth are the same reference. It resolves re-exports through index.ts barrels. Atlas indexes code by AST declarations using tree-sitter, not blind line windows, which is why the snippets Atlas shows you around each reference are whole functions rather than three lines of context. What findReferences will not find is anything outside the type system, which is why grep runs next rather than not at all.

How do you catch TypeScript occurrences that tsc cannot see?

Atlas runs grep for the old name to catch the occurrences that live outside the type system: strings, comments, docs, and config. In a 2026 TypeScript project that means package.json scripts, .env keys, JSDoc @param tags, snapshot files under __snapshots__, and any name used as a string key in a Zod schema or a Prisma model.

TypeScript is a type system layered over JavaScript, and the layer below is full of untyped strings. A renamed constant AUTH_TOKEN_KEY will still appear as the string "AUTH_TOKEN_KEY" in a localStorage call, in a vitest snapshot under __snapshots__/, and in an OpenAPI spec. A renamed React component will still appear in a lazy import path and in a Storybook title. Atlas greps for the old name specifically to find those, because leaving them behind produces the worst class of bug: the code compiles, prettier is happy, and the behavior is wrong at runtime. Atlas searches code with hybrid semantic and keyword retrieval fused by reciprocal rank fusion, so codebase_search can also surface the conceptual matches where the old name was paraphrased rather than repeated.

What stops Atlas from renaming the wrong TypeScript occurrence?

Atlas's edit tool enforces uniqueness. Where a single occurrence must change, edit throws Found multiple matches for oldString unless you add context or opt into replaceAll. In a TypeScript file where the identifier appears 7 times and only 1 should change, an ambiguous match is an error rather than a silent corruption.

Atlas applies the mechanical renames with edit using replaceAll where the match is unambiguous per file, which handles the common case: a module that imports the symbol and uses it 5 times, all of which should change. Where the case is not clean, edit refuses. Found multiple matches for oldString forces you to add surrounding context, which in TypeScript usually means including the import statement or the enclosing function signature so the match is pinned. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, and Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so a 40-file rename arrives as 40 reviewable diffs, not as a fait accompli.

How do you prove a TypeScript rename is complete?

Atlas proves a TypeScript rename is complete by compiling and testing with bash, then grepping once more for the old name to show zero remaining hits. Running tsc, then vitest, then a final grep is a 3-step proof: the compiler says the types resolve, vitest says the behavior held, and grep says no stale string survives.

The final grep is the step people skip and the step that catches the residue. After edit has applied the renames and pnpm has resolved the workspace, run tsc through bash: a zero-error compile means every reference findReferences knew about was updated. Then run vitest: a green suite means the runtime behavior, including the string-keyed paths tsc never checked, still works. Then grep the old name across the repo, including .md, .json, and __snapshots__. Zero hits is the proof. Run prettier last so the diff is clean. Atlas reads git branches, status, and diffs, and can stage and create commits on your behalf, so the finished rename becomes one reviewable commit.

Step by step

  1. 01Run atlas in a project with a tsconfig.json so Atlas can read your type definitions, path aliases, and strictness settings.
  2. 02Run the lsp tool's findReferences operation on the symbol to get the authoritative callsite list from the TypeScript language server, including path-alias and barrel re-export references.
  3. 03Run grep for the old name to catch occurrences outside the type system: string literals, JSDoc comments, __snapshots__ files, package.json scripts, and docs.
  4. 04Apply the mechanical renames with edit using replaceAll where the match is unambiguous per file.
  5. 05Where a single occurrence must change, edit enforces uniqueness: it throws Found multiple matches for oldString unless you add context or opt into replaceAll.
  6. 06Review each unified diff Atlas surfaces before it writes, since Atlas computes a unified diff for every file edit and surfaces it for approval before writing.
  7. 07Compile with tsc and run vitest through bash; pnpm resolves the workspace so a monorepo rename is checked across packages.
  8. 08Grep once more for the old name to prove zero remaining hits, then run prettier so the final diff is clean.

Frequently asked questions

how to rename a symbol across an entire TypeScript monorepo
Run Atlas's lsp tool findReferences operation first for the authoritative callsite list from the TypeScript language server, then grep for the old name to catch strings and docs. Apply renames with edit using replaceAll, then verify with tsc, vitest, and a final grep.
why does find and replace break TypeScript renames
Text search matches substrings like UserProfile when you meant User, and misses imports resolved through tsconfig.json path aliases and index.ts barrels. Atlas uses the lsp tool's findReferences for the compiler's real reference set and grep only for what the compiler cannot see.
what does Found multiple matches for oldString mean in Atlas
Atlas's edit tool enforces uniqueness on single replacements. If the oldString appears more than once in a TypeScript file, edit throws Found multiple matches for oldString and you must add surrounding context or opt into replaceAll. An ambiguous match is an error, not a silent corruption.
does Atlas understand tsconfig path aliases
Yes. Run atlas in a project with a tsconfig.json and Atlas reads your type definitions, path aliases, and strictness settings. The lsp tool's findReferences resolves an import from @app/lib/auth and one from ../../lib/auth to the same symbol.
how do I make sure a rename did not miss any string literals
Grep for the old name after the rename, including .md, .json, and __snapshots__ files. Atlas runs grep for the old name specifically because string literals, Zod schema keys, and vitest snapshots are invisible to tsc and will compile clean while behaving wrong.
can Atlas run vitest and tsc for me during a rename
Yes. Atlas compiles and tests with the bash tool, so tsc and vitest run as part of the rename workflow rather than after it. Every bash call is permission-gated against allow, ask, and deny rules before it runs.
how do I review a 40-file TypeScript rename before it lands
Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so a 40-file rename arrives as 40 reviewable diffs. Atlas also snapshots file changes as git patches so the whole rename can be rolled back.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Rename a Symbol Across the Repo with Atlas in 2026

How to rename a symbol across a repo with Atlas in 2026: findReferences gets the true reference set, grep catches strings and docs, and edit refuses ambiguous matches.

Atlas for TypeScript in 2026

In 2026, TypeScript developers leverage Atlas, the terminal-native AI coding agent, to enhance productivity. Atlas understands your types, ensures code quality, and offers robust safety features.

Diagnose a hanging or long-running command in TypeScript with Atlas (2026)

Is your pnpm build slow or blocked on stdin? Atlas's bash timeout message tells you which, in 2026, and how to unstick vitest, tsc, and prettier runs that never finish.

Automate GitHub Issue and Pull Request Triage in TypeScript with Atlas (2026)

Wire the atlas github command into a TypeScript repo's Actions workflow in 2026: set MODEL in provider/model form, gate on write permission, verify with vitest.

Review a TypeScript Pull Request with Atlas (2026)

Review a TypeScript pull request with Atlas in 2026. Get the raw diff with bash, read changed files in full, and check callers with lsp findReferences before running vitest.

Document a TypeScript Module With a README Using Atlas (2026 Guide)

Write a README that matches your TypeScript code in 2026. Atlas enumerates exports with lsp documentSymbol, quotes real signatures, and verifies every sample with vitest.

Write Unit Tests for Untested Code in TypeScript with Atlas (2026)

How Atlas writes vitest unit tests for untested TypeScript in 2026: lsp documentSymbol enumerates exports, grep copies your conventions, and pnpm vitest actually runs them.

Run the Test Suite and Triage the Failures in TypeScript with Atlas (2026)

Turn a wall of red vitest output into a ranked list of root causes in 2026: Atlas truncates at 2000 lines, saves the full log, and greps it into a todowrite triage list.

Browse this resource hub