Skip to content

Getting Started ​

Welcome to ReluxScript! This guide will help you write your first AST transformation plugin.

What is ReluxScript? ​

ReluxScript is a domain-specific language for writing AST transformation plugins that compile to both Babel (JavaScript) and SWC (Rust). Write your transformation logic once, and ReluxScript generates plugins for both platforms.

Installation ​

Install ReluxScript from crates.io:

bash
cargo install reluxscript

This installs the relux CLI tool globally.

Your First Plugin ​

Let's create a simple plugin that removes console.log statements:

1. Create a New Plugin ​

bash
relux new remove-console

This creates remove-console.lux with a basic template.

2. Implement the Transformation ​

Edit remove-console.lux:

reluxscript
// Remove all console.log calls from your code
plugin RemoveConsole {
    fn visit_call_expression(node: &mut CallExpression, ctx: &Context) {
        // Check if this is a console.log call
        if matches!(node.callee, "console.log") {
            // Replace with an empty statement
            *node = Statement::empty();
        }
    }
}

3. Compile to Babel ​

bash
relux build remove-console.lux --target babel

This generates dist/index.js - a Babel plugin you can use with webpack, rollup, or babel-cli.

4. Compile to SWC ​

bash
relux build remove-console.lux --target swc

This generates dist/lib.rs - a SWC plugin you can compile to WASM.

5. Use Your Plugin ​

With Babel:

javascript
// babel.config.js
module.exports = {
  plugins: [
    './dist/index.js'
  ]
}

With SWC:

json
// .swcrc
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["./dist/lib.wasm", {}]
      ]
    }
  }
}

What's Next? ​

Key Concepts ​

The Visitor Pattern ​

ReluxScript uses the visitor pattern to traverse and transform the AST. You implement visitor methods like:

  • visit_call_expression - Called for every function call
  • visit_function_declaration - Called for every function declaration
  • visit_identifier - Called for every identifier

Mutations are Explicit ​

All changes to the AST must be explicit:

reluxscript
*node = Statement::empty();  // Replace node
node.name = "newName";         // Modify property

The matches! Macro ​

Use matches! to pattern match on AST nodes:

reluxscript
if matches!(node.callee, "console.log") {
    // This is console.log
}

if matches!(node.operator, "+") {
    // This is addition
}

Common Patterns ​

Removing Nodes ​

reluxscript
*node = Statement::empty();

Modifying Properties ​

reluxscript
node.name = "newName";
node.async = true;

Creating New Nodes ​

reluxscript
let new_call = CallExpression {
    callee: Identifier::new("console.log"),
    arguments: vec![StringLiteral::new("Hello")]
};

Conditional Transformations ​

reluxscript
if matches!(node.operator, "+") && node.left.is_number() {
    // Transform only numeric additions
}

Getting Help ​

Ready to dive deeper? Continue to Core Concepts.

Released under the MIT License.