Babel codemod to transform require statements I'm starting to explore the world of ASTs and codemods. As such my first foray is a simple transform to move statements like let fs = require('fs') to const fs = require('fs'). 

const declaratorKinds = { let: null, var: null }

export default function(babel) {
 const { types: t } = babel

 return {
   visitor: {
     VariableDeclaration(path) {
       if (!(path.node.kind in declaratorKinds)) { return }

       const d = path.node.declarations[0]

       if (!(
         d.init
         &amp;&amp; d.init.callee
         &amp;&amp; d.init.callee.name === 'require')) { return }

       path.replaceWith(
         t.VariableDeclaration('const', path.node.declarations)
       )
     }
   }
 }
}


Here's a live ast explorer version.

I'm a newbie here so i'm interested in any feedback, but I'd particuarly like to know about: 


Is VariableDeclarator the best node type to base this transform on?
Is there a way I could better filter for require declarations?
The only problem with this code that jumps out is declaratorKinds = { let: null, var: null } for use with path.node.kind in declaratorKinds. It would be much better to just use an array or set. 

const declaratorKinds = ['let', 'var']
...
if (declaratorKinds.includes(path.node.kind))


As far as I can tell VariableDeclaration is the best way to handle this, I have no experience with babel transforms, so I may be missing something. 

Bugs:


var fs = require('fs'), temp; will be transformed into const fs = require('fs'), temp; which will throw a syntax error. 
var temp = 1, fs = require('fs') will not be transformed.


A better solution would be to check each VariableDeclarator item in path.node.declarations, this could look something like the following. (Note that this rewrites multiple simultaneous declarations into separate declarations - the style I prefer)

export default function({types}) {  
  return {
    visitor: {
      VariableDeclaration(path) {
        const { kind, declarations } = path.node

        if (!['let', 'var'].includes(kind)) {
          return
        }

        const requireDeclarations = declarations.filter(d =&gt; {
          return d.init &amp;&amp; d.init.callee &amp;&amp; d.init.callee.name == 'require'
        })
        const otherDeclarations = declarations.filter(d =&gt; !requireDeclarations.includes(d))

        if (requireDeclarations.length) {
          path.replaceWithMultiple([
            ...requireDeclarations.map(d =&gt; types.VariableDeclaration('const', [d])),
            ...otherDeclarations.map(d =&gt; types.VariableDeclaration(kind, [d])),
          ])
        }
      }
    }
  }
}


Demo here (forked from your demo)