Google's JSIR: An MLIR-Based Intermediate Representation for JavaScript Analysis

Google's JSIR: An MLIR-Based Intermediate Representation for JavaScript Analysis

lschvn5 min read

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.

Frequently Asked Questions

Related articles

More coverage with overlapping topics and tags.

Astro 6.1.8 Patches Critical Netlify Deploy Bug and Image Endpoint Security Flaw
JavaScript

Astro 6.1.8 Patches Critical Netlify Deploy Bug and Image Endpoint Security Flaw

Astro 6.1.8 fixes a regression where build output filenames containing special characters caused deploy failures on Netlify and Vercel, and patches a content-type confusion vulnerability in the built-in image endpoint that could serve non-SVG content as SVG.
Next.js v16.3.0-Canary: Prefetch Controls, Dedup Improvements, and a New Dev Overlay
JavaScript

Next.js v16.3.0-Canary: Prefetch Controls, Dedup Improvements, and a New Dev Overlay

Next.js 16.3.0-canary brings fine-grained prefetch configuration, better deduping for the 'use cache' directive, and a redesigned blocking route dev overlay — with sccache now bootstrapped via cargo-binstall.
Oxc v0.126.0: Turbopack Magic Comments Land in the Parser, Allocator Breaking Changes
JavaScript

Oxc v0.126.0: Turbopack Magic Comments Land in the Parser, Allocator Breaking Changes

Oxc v0.126.0 ships support for Turbopack magic comments in the parser, a breaking rename of Box and Vec allocator methods, new NAPI transform options for enum optimization, and continued performance work on the lexer and allocator.

Comments

Log in Log in to join the conversation.

No comments yet. Be the first to share your thoughts.