estraverse vs esprima vs acorn-walk vs estree-walker vs recast
JavaScript AST (Abstract Syntax Tree) Manipulation Comparison
1 Year
estraverseesprimaacorn-walkestree-walkerrecastSimilar Packages:
What's JavaScript AST (Abstract Syntax Tree) Manipulation?

JavaScript AST (Abstract Syntax Tree) Manipulation libraries provide tools for analyzing, transforming, and generating JavaScript code by working with its syntactic structure. These libraries parse JavaScript code into a tree-like representation (the AST), allowing developers to traverse, modify, or generate code programmatically. They are useful for tasks like code analysis, linting, transpiling, and building tools like formatters and minifiers. Each library has its own strengths, such as performance, ease of use, and support for specific AST specifications, making them suitable for different use cases in the JavaScript ecosystem.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
estraverse126,869,365960-394 years agoBSD-2-Clause
esprima74,535,7607,105-1487 years agoBSD-2-Clause
acorn-walk57,183,30611,02052.3 kB1710 months agoMIT
estree-walker52,358,99641417.6 kB112 years agoMIT
recast15,720,3225,146246 kB2075 months agoMIT
Feature Comparison: estraverse vs esprima vs acorn-walk vs estree-walker vs recast

AST Traversal

  • estraverse:

    estraverse is designed specifically for traversing ESTree-compliant ASTs. It offers a comprehensive API for both simple and complex traversals, including the ability to skip nodes, replace them, or perform actions at specific points in the traversal. Its flexibility makes it suitable for a wide range of traversal tasks.

  • esprima:

    esprima focuses on parsing JavaScript code and generating a detailed AST. While it does not provide built-in traversal methods, its AST structure is well-defined and can be easily traversed using external libraries like estraverse or acorn-walk. This separation of concerns allows for more specialized traversal implementations.

  • acorn-walk:

    acorn-walk provides a simple and efficient way to traverse ASTs generated by Acorn. It supports both pre-order and post-order traversal, allowing you to visit nodes in a flexible manner. The API is straightforward, making it easy to integrate into projects that require basic tree walking.

  • estree-walker:

    estree-walker provides a lightweight and efficient way to traverse ESTree-compliant ASTs. It uses a simple walker pattern that allows for easy customization of traversal behavior. The library is minimalistic, which makes it fast and easy to use for projects that require quick and straightforward tree walking.

  • recast:

    recast integrates AST traversal with code transformation and pretty-printing. It allows you to traverse the AST while also modifying it and generating new code from the transformed tree. This dual functionality makes it a powerful tool for refactoring and transforming JavaScript code while maintaining its original structure.

Code Transformation

  • estraverse:

    estraverse is a traversal library that facilitates code transformation by allowing you to visit and modify nodes in the AST. While it does not perform transformations itself, it provides the necessary hooks and structure to implement custom transformations, making it a valuable tool for developers working on AST manipulation and code refactoring projects.

  • esprima:

    esprima focuses on parsing and generating ASTs rather than transforming them. It provides a detailed representation of the code structure, which can be used by other libraries for transformation tasks. Esprima’s role is to provide accurate and compliant ASTs that can be manipulated by external tools and frameworks.

  • acorn-walk:

    acorn-walk is primarily a traversal library and does not provide built-in support for code transformation. However, it allows you to visit and manipulate nodes during traversal, enabling custom transformations to be implemented as needed. For more complex transformations, you may need to combine it with other libraries that handle AST manipulation.

  • estree-walker:

    estree-walker is designed for traversal and does not include built-in transformation capabilities. However, it allows for easy manipulation of nodes during traversal, enabling developers to implement custom transformations as they walk the tree. Its simplicity and efficiency make it a good choice for projects that require lightweight transformation logic.

  • recast:

    recast excels at code transformation while preserving the original formatting. It allows you to modify the AST and generate new code from it, making it ideal for refactoring tasks. Recast handles the complexities of maintaining code style and structure during transformations, which is a significant advantage for projects that require high-quality output.

Performance

  • estraverse:

    estraverse is designed to be efficient for traversing ESTree-compliant ASTs, but its performance can vary based on the complexity of the traversal and the number of nodes being processed. It is generally fast for most use cases, but developers should be mindful of potential performance bottlenecks when implementing complex traversal logic.

  • esprima:

    esprima is known for its fast parsing capabilities, but the performance of AST traversal and manipulation depends on how the generated AST is used. Esprima is optimized for quick parsing, making it a good choice for applications that need to analyze code quickly. However, for large-scale AST manipulation, performance will also depend on the algorithms and techniques used by external libraries.

  • acorn-walk:

    acorn-walk is lightweight and optimized for performance, especially when traversing ASTs generated by the Acorn parser. Its minimalistic design ensures that traversal operations are fast and efficient, making it suitable for applications where performance is critical.

  • estree-walker:

    estree-walker is designed for performance, with a focus on minimal overhead during traversal. Its lightweight nature makes it one of the fastest options for walking ESTree-compliant ASTs, making it ideal for applications that require quick and efficient tree traversal without unnecessary complexity.

  • recast:

    recast is more resource-intensive than simple traversal libraries due to its capabilities for parsing, transforming, and pretty-printing code. While it provides powerful transformation features, developers should be aware of the potential performance implications when working with large codebases or performing complex transformations.

Ease of Use: Code Examples

  • estraverse:

    estraverse Example

    import { parse } from 'acorn';
    import estraverse from 'estraverse';
    
    const code = `const x = 1;`;
    const ast = parse(code);
    
    estraverse.traverse(ast, {
      enter(node) {
        console.log('Visiting node:', node.type);
      },
    });
    
  • esprima:

    esprima Example

    import esprima from 'esprima';
    
    const code = `const x = 1;`;
    const ast = esprima.parseScript(code);
    console.log(JSON.stringify(ast, null, 2));
    
  • acorn-walk:

    acorn-walk Example

    import { parse } from 'acorn';
    import { simple } from 'acorn-walk';
    
    const code = `const x = 1;`;
    const ast = parse(code);
    
    simple(ast, {
      VariableDeclaration(node) {
        console.log('Found a variable declaration:', node);
      },
    });
    
  • estree-walker:

    estree-walker Example

    import { parse } from 'acorn';
    import { walk } from 'estree-walker';
    
    const code = `const x = 1;`;
    const ast = parse(code);
    
    walk(ast, {
      enter(node) {
        console.log('Entering node:', node.type);
      },
    });
    
  • recast:

    recast Example

    import recast from 'recast';
    
    const code = `const x = 1;`;
    const ast = recast.parse(code);
    
    recast.types.visit(ast, {
      visitVariableDeclaration(path) {
        console.log('Found a variable declaration:', path.node);
        this.traverse(path);
      },
    });
    
    const transformedCode = recast.print(ast).code;
    console.log(transformedCode);
    
How to Choose: estraverse vs esprima vs acorn-walk vs estree-walker vs recast
  • estraverse:

    Choose estraverse if you need a flexible and extensible library for traversing and manipulating ESTree-compliant ASTs. It provides a simple API for walking the tree and allows for easy customization of traversal behavior.

  • esprima:

    Choose esprima if you need a standards-compliant, fast JavaScript parser that generates a detailed AST. It is suitable for projects that require accurate parsing and analysis of JavaScript code, including support for ES6 and beyond.

  • acorn-walk:

    Choose acorn-walk if you need a lightweight and fast library for traversing ASTs generated by Acorn. It is ideal for simple traversal and manipulation tasks without the overhead of a full-featured framework.

  • estree-walker:

    Choose estree-walker if you want a minimalistic and efficient walker for ESTree-compliant ASTs. It is designed for performance and simplicity, making it a great choice for projects that require fast and lightweight tree traversal.

  • recast:

    Choose recast if you need a powerful tool for parsing, transforming, and pretty-printing JavaScript code while preserving the original formatting. It is ideal for complex code transformations and refactoring tasks, as it integrates well with existing code and supports custom transformations.

README for estraverse

Estraverse Build Status

Estraverse (estraverse) is ECMAScript traversal functions from esmangle project.

Documentation

You can find usage docs at wiki page.

Example Usage

The following code will output all variables declared at the root of a file.

estraverse.traverse(ast, {
    enter: function (node, parent) {
        if (node.type == 'FunctionExpression' || node.type == 'FunctionDeclaration')
            return estraverse.VisitorOption.Skip;
    },
    leave: function (node, parent) {
        if (node.type == 'VariableDeclarator')
          console.log(node.id.name);
    }
});

We can use this.skip, this.remove and this.break functions instead of using Skip, Remove and Break.

estraverse.traverse(ast, {
    enter: function (node) {
        this.break();
    }
});

And estraverse provides estraverse.replace function. When returning node from enter/leave, current node is replaced with it.

result = estraverse.replace(tree, {
    enter: function (node) {
        // Replace it with replaced.
        if (node.type === 'Literal')
            return replaced;
    }
});

By passing visitor.keys mapping, we can extend estraverse traversing functionality.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'Literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
estraverse.traverse(tree, {
    enter: function (node) { },

    // Extending the existing traversing rules.
    keys: {
        // TargetNodeName: [ 'keys', 'containing', 'the', 'other', '**node**' ]
        TestExpression: ['argument']
    }
});

By passing visitor.fallback option, we can control the behavior when encountering unknown nodes.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'Literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
estraverse.traverse(tree, {
    enter: function (node) { },

    // Iterating the child **nodes** of unknown nodes.
    fallback: 'iteration'
});

When visitor.fallback is a function, we can determine which keys to visit on each node.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'Literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
estraverse.traverse(tree, {
    enter: function (node) { },

    // Skip the `argument` property of each node
    fallback: function(node) {
        return Object.keys(node).filter(function(key) {
            return key !== 'argument';
        });
    }
});

License

Copyright (C) 2012-2016 Yusuke Suzuki (twitter: @Constellation) and other contributors.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.