🔄 Renaming Variables and Functions in JavaScript Using ASTs
When working with JavaScript, there are times you might want to automatically rename variables or functions across your code — perhaps for obfuscation, code transformation, or refactoring. Doing this safely, without accidentally breaking your program, requires understanding how your code is structured — and that’s where the Abstract Syntax Tree (AST) comes in.
In this post, we’ll look at how to rename variable and function declarations using ASTs, with a simple utility renamedecl.
🌳 What Is an AST?
An Abstract Syntax Tree (AST) is a structured, tree-like representation of your source code.
Instead of dealing with raw text, you work with objects that represent program constructs like variables, functions, loops, and expressions.
For example, the code:
const x = 5;
console.log(x);
can be represented (simplified) as:
{
type: "Program",
body: [
{
type: "VariableDeclaration",
declarations: [
{
type: "VariableDeclarator",
id: { type: "Identifier", name: "x" },
init: { type: "Literal", value: 5 }
}
]
},
{
type: "ExpressionStatement",
expression: {
type: "CallExpression",
callee: {
object: { name: "console" },
property: { name: "log" }
},
arguments: [{ type: "Identifier", name: "x" }]
}
}
]
}
By working with this structure, you can programmatically modify parts of your code (e.g. change x
to width
) and then regenerate valid JavaScript source code.
🧩 Tools: Acorn, Escodegen
- Acorn — a fast, lightweight JavaScript parser. It converts JS source code into an AST.
- Escodegen — generates readable JavaScript code from an AST.
Scopes
Scopes — just like in real code, variables and functions in an AST exist within scopes (e.g., global, function, block). When renaming identifiers, you need to make sure you don’t accidentally rename a variable from an outer scope that has the same name.
🚀 Introducing renamedecl
renamedecl is the lightweight tool for renaming variables and functions in JS code based on an AST.
The function renameDeclarations(ast, rename, initscope?)
walks through your AST, finds all declarations (variables, function names, parameters, etc.), and lets you rename them safely according to the rules you define.
It can be used in two main ways:
1. Automatic Renaming
You can rename every variable and function in a consistent way — for example, to obfuscate or anonymize code.
const acorn = require('acorn');
const escodegen = require('escodegen');
const { renameDeclarations } = require('renamedecl');
const originalCode = `
function add(x, y) {
const result = x + y;
return result;
}
`;
const ast = acorn.parse(originalCode, {
ecmaVersion: 2020,
sourceType: 'script'
});
// Rename all identifiers sequentially
renameDeclarations(
ast,
(id, scope) => `v${++scope.varNum}`,
scope => { scope.varNum = 0; }
);
const newCode = escodegen.generate(ast);
console.log(newCode);
Output:
function v1(v2, v3) {
const v1 = v2 + v3;
return v1;
}
Here, every declared identifier got renamed with a consistent numbering scheme, respecting the correct scope hierarchy.
2. Custom Rename Mapping
You can also define your own rename map to transform specific variable or function names.
const renameMap = {
x: 'width',
y: 'height',
result: 'sum'
};
renameDeclarations(ast, id => renameMap[id.name]);
This is great for refactoring, such as renaming variables to more meaningful names.
🧠 How Scoping Works
renamedecl
automatically tracks scopes as it traverses the AST.
When it enters a new function or block, it creates a new scope object.
This ensures that two variables named x
in different functions don’t get mixed up:
function outer() {
const x = 10;
function inner() {
const x = 20;
console.log(x);
}
inner();
}
Both x
variables live in different scopes. The renaming logic keeps that distinction intact — so each gets its own renamed version.
🔧 Why Use This?
- ✅ Safe — Respects JavaScript scoping rules
- 🔍 Customizable — You control the renaming logic
- 🧰 Tool-friendly — Works directly with standard AST tools
- ⚙️ Flexible — Use it for obfuscation, refactoring, or static analysis
🧩 Try It Out
You can install it via npm:
npm install git+https://github.com/optinsoft/renamedecl.git
Then import and use it as shown above.
💡 Conclusion
Working with ASTs may sound intimidating at first, but with tools like Acorn, Escodegen, and utilities such as renamedecl
, transforming JavaScript code becomes powerful and approachable.
By controlling variable and function names at the AST level, you can safely build tools for code analysis, transpilation, refactoring, or obfuscation — all while preserving the correctness of your original code.