When a compiler intermediate representation (IR) makes the news, you know it matters. Google has published JSIR, a next-generation JavaScript analysis tool built on MLIR, and it's already used internally for tasks that reveal just how ambitious the project is: decompiling Hermes bytecode back to JavaScript, and powering AI-assisted deobfuscation pipelines that combine JSIR with Gemini.
Why This Matters for Tooling
An intermediate representation is the data structure that a compiler or analysis tool uses to represent code between parsing and code generation. If an AST tells you what the code looks like structurally, an IR tells you what it does. The quality of your IR determines what kind of analysis and transformation you can perform.
JavaScript tooling has long suffered from fragmented IR approaches. Babel plugins work on ASTs. ESLint rules work on ASTs. Bundlers often work on their own internal representations with limited interoperability. A common, well-designed IR could let these tools share analysis work — and that's exactly what Google is proposing with JSIR.
High-Level and Low-Level Simultaneously
The core technical challenge JSIR solves is a familiar one in compiler design: you typically have to choose between a high-level IR (preserves AST structure, can be lifted back to source) and a low-level IR (enables deep dataflow analysis like taint tracking and constant propagation). Most systems pick one.
JSIR uses MLIR regions to accurately model JavaScript's control flow structures — things like closures, try-catch-finally, async functions, and generator frames — in a way that supports both directions simultaneously. You can transform code and lift it back to source, or run taint analysis across the same representation.
This unlocks use cases that were previously impractical:
Decompilation: JSIR is used at Google to decompile Hermes bytecode all the way back to JavaScript. Hermes compiles React Native apps to a compact bytecode for faster startup; JSIR's source-liftability is what makes this decompilation possible when other tools would hit a dead end.
Deobfuscation: Google published research (CASCADE) on combining Gemini LLM with JSIR for JavaScript deobfuscation. The AI operates on JSIR's structured representation rather than raw obfuscated source, producing transformations that JSIR applies back to reconstruct clean code.
The MLIR Foundation
JSIR isn't a standalone project — it's built on MLIR, the LLVM project's flexible IR framework. This is significant for ecosystem compatibility: MLIR already has a broad set of existing dialects, transformations, and tooling. By expressing JavaScript analysis in MLIR terms, JSIR can plug into that ecosystem rather than reinventing infrastructure.
Getting Started
JSIR is available on GitHub at github.com/google/jsir. The project recommends using Docker for local experimentation:
docker build -t jsir:latest .
docker run --rm -v $(pwd):/workspace jsir:latest jsir_gen --input_file=/workspace/yourfile.js
Building from source requires clang, Bazel, and significant build time — the project notes that LLVM fetch and build takes a while. The Docker path is the practical entry point for most developers.
What This Means for the Ecosystem
Most developers won't interact with JSIR directly in the near term — it's a foundation for tooling developers to build on. But the long-term implications are significant. A shared, well-designed IR could enable:
- Linters with deeper semantic understanding (not just pattern matching on AST nodes)
- Bundlers with better dead code elimination using dataflow analysis
- Refactoring tools that can safely transform code across complex control flow
- Cross-framework analysis that works consistently regardless of which framework or build tool is used
Google has open sourced it, which means the community can build on this foundation. Whether it gains traction depends on whether tooling maintainers see enough benefit to integrate JSIR-based analysis into their pipelines — but the technical foundation is solid.