{
  "id": 3283243,
  "title": "Building a TypeScript Code Radar: What an AST Reveals That Text Search Misses",
  "url": "https://urgent.news/2026/08/25/building-a-typescript-code-radar-what-an-ast-reveals-that-text-search",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-25T14:17:50.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/akamabe/building-a-typescript-code-radar-what-an-ast-reveals-that-text-search-misses-231d"
  },
  "original_language": "en",
  "account": "On a recent exploration, I delved into Tree-sitter, a tool I had heard about but never utilized. My objective was straightforward: parse a TypeScript file and discern what Tree-sitter discerns that conventional text searches overlook. I selected a compact NestJS controller for experimentation.\n\nInitially, I displayed Tree-sitter's syntax tree directly. While accurate, the output was convoluted, consisting of nodes like import_statement, class_declaration, decorator, call_expression, and identifier. To make sense of it, I crafted a compact recursive tree printer. This was when Tree-sitter's true potential became evident.\n\nTree-sitter doesn't perceive source code as a sequence of characters; it discerns structural relationships. For instance, @Controller(orders) is transformed into a structure resembling decorator call_expression identifier = Controller arguments string = orders. Likewise, export class OrdersController becomes a structure containing class_declaration type_identifier = OrdersController class_body.\n\nThis distinction is far more significant than it initially appears. While text searches answer the question, \"Does this string exist?\" ASTs provide essential context. Rather than searching for the characters OrdersController, I could search for a node with the type class_declaration and subsequently request Tree-sitter for its name field. My initial structural extraction yielded: { type: class_declaration, name: OrdersController }.\n\nI then scrutinized the surrounding decorator nodes and extracted: { name: Controller, arguments: [ orders ] } and { name: UseGuards, arguments: [ AuthGuard ] }. At this point, we were no longer dealing with source code as text, but rather transforming code into factual representations. The pipeline evolved into: TypeScript source ↓ Tree-sitter ↓ Syntax tree ↓ Structural extraction ↓ Facts about the code.\n\nHowever, a crucial limitation emerged: Tree-sitter comprehends syntax, not application semantics. Even if I wrote @ SomethingThatDoesNotExist(), Tree-sitter could still accurately identify it as a decorator and function call. It lacks knowledge about the existence of that decorator in NestJS or whether it would compile in my application. This distinction proved enlightening: parsing reveals the structural nature of the code, while subsequent layers — the TypeScript compiler, framework knowledge, and static analysis rules — determine the actual meaning of that structure.\n\nThough this was a modest experiment, I now grasped why Tree-sitter serves as the foundation for editors, code navigation tools, and static analyzers. Tomorrow, I planned to transition from manually inspecting the AST to extracting imports, classes, and decorators into normalized facts. This initial step aimed to transform this experiment into a small TypeScript code radar.",
  "summary": "Today I started experimenting with Tree-sitter . I had heard the name before, but I had never actually used it. My goal was simple: take a TypeScript file, parse it, and understand what Tree-sitter sees that a normal text search does not. The file I used was a tiny NestJS controller: import { Controller , Get , UseGuards } from ' @nestjs/common ' ; import { AuthGuard } from ' ./auth.guard ' ;…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}