Skip to main content
Build a working JavaScript ast-grep (JSSG) codemod in minutes.

What is JSSG?

JavaScript ast-grep (JSSG) is a secure JavaScript runtime for codemods. This runtime is compatible with Node.js and comes with ast-grep as a built-in module.
JSSG is built on top of QuickJS, a lightweight JavaScript engine, and uses LLRT for Node.js module compatibility.
JSSG follows a deny-by-default security model. Unsafe operations like file system access (fs), network requests (fetch), and process spawning (child_process) are disabled by default. See Security & Capabilities to learn how to enable them.
How it works:
  • A JSSG codemod is a module that export defaults a function receiving an SgRoot<L> (the parsed file) and returning a string (modified code) or null/undefined (no change). Any other return type is a runtime error.
  • The codemod:ast-grep built‑in provides parsing and pattern matching. At runtime it exports parse and parseAsync; SgRoot and SgNode are TypeScript types from @codemod.com/jssg-types that describe the AST API you interact with in the transform.
  • You express search conditions as ast-grep rule objects (plain JS), traverse nodes, create edits with node.replace(...), and finalize with rootNode.commitEdits(edits).
For engine details and built-ins, see Runtime and built-ins in the API reference.
Key concepts:
  • Patterns: Describe code shapes using ast-grep’s pattern syntax with captures (for example, $NAME, $$$ARGS).
  • Rules: Compose patterns with any, all, kind, relational constraints (inside, has, precedes, follows), and utilities like matches and constraints.
  • Edits: Build replacements with node.replace(text) and apply them with commitEdits(edits).
  • Lifecycle: Select → Traverse → Capture → Edit → Commit & Return.
You can author rules as plain JavaScript objects. See the ast‑grep rule configuration docs and the JSSG API reference.

Build your first codemod

1

Scaffold a JSSG package

npx codemod init
Pick JavaScript ast-grep (JSSG) codemod when prompted.This will scaffold a new folder with the required files and structure.
your-codemod
codemod.yaml
workflow.yaml
scripts
codemod.ts
2

Write a minimal transform (scripts/codemod.ts)

Key concepts:
  • Transform signature: export default function transform(root, options)
  • Edit flow: find nodes → build edits → commitEdits(edits) → return resulting string
  • Return contract: string → modified (unless equal to input), null/undefined → unmodified; anything else → error
  • Type safety: Always check node types before accessing fields
codemod.ts
import type { Transform } from "codemod:ast-grep";
import type TSX from "codemod:ast-grep/langs/tsx";

const transform: Transform<TSX> = (root) => {
  const rootNode = root.root();

  // Find all console.* calls with type safety
  const consoleCalls = rootNode.findAll({
    rule: {
      any: [
        { pattern: "console.log($$$ARGS)" },
        { pattern: "console.debug($$$ARGS)" },
        { pattern: "console.warn($$$ARGS)" },
      ],
    },
  });

  if (consoleCalls.length === 0) {
    return null; // No changes needed
  }

  // Create edits with proper validation
  const edits = consoleCalls.map((node) => {
    const callee = node.field("function");
    const method = callee?.field("property")?.text() || "log";
    const args = node.getMultipleMatches("ARGS")
      .map(arg => arg.text())
      .join(", ");
    
    return node.replace(`logger.${method}(${args})`);
  });

  return rootNode.commitEdits(edits);
}

export default transform;
The transform follows this pattern:
  1. If no matches are found, the step is skipped or files are unchanged
  2. When matches exist, files with changes are updated in-memory and reported in the diff
  3. Returning the same string results in “unmodified”; returning null/undefined is also treated as “unmodified”
3

Validate & run

npx codemod workflow validate -w workflow.yaml
npx codemod workflow run -w workflow.yaml --dry-run
The transform will make the following changes:
Before
function example() {
  console.log("Hello");
  console.debug("Debug");
}
After
function example() {
  logger.log("Hello");
  logger.log("Debug");
}

Next steps

Security & Capabilities

Learn about JSSG’s security model and how to enable file system, network, and process capabilities.

Test your codemod

Validate your codemod with before/after fixtures and the test runner.

JSSG reference

Explore the full API reference for node navigation, editing, and pattern matching.

Semantic Analysis

Find symbol definitions and references across your codebase.

Advanced patterns

Learn advanced transformation techniques and best practices.