Which Languages Run on AWS Graviton Without Code Changes?

Migrating applications to Amazon EC2 Graviton instances is often straightforward because interpreted languages and bytecode-based runtimes abstract the underlying processor architecture from your source code. Languages such as Python, Node.js, Ruby, PHP, Java, and .NET generally require zero code modifications when transitioning from x86 to Arm64 processors, provided their third-party dependencies do not rely on architecture-specific native extensions or pre-compiled x86 binaries. Even compiled languages like Go and Rust typically only require updating the build target configuration rather than rewriting application logic.

Interpreted Languages

Interpreted and dynamically typed languages execute inside a language runtime that handles platform-specific machine instructions on behalf of your application. Because your codebase stays in plain text until the runtime interprets or just-in-time compiles it on the host machine, migrating to an Arm64 environment requires only installing the Arm64 version of the interpreter.

  • Python: Pure Python applications run identically on x86 and Arm64. Modern versions of Python (3.8 and newer) offer full optimizations for 64-bit Arm architectures. Most popular packages containing C or Rust extensions, such as NumPy, Pandas, and Cryptography, publish pre-built manylinux aarch64 wheels to PyPI, allowing pip to install them without local compilation or code changes.
  • JavaScript and TypeScript (Node.js, Deno, Bun): The V8 and JavaScriptCore engines have first-class Arm64 support. Pure JavaScript and TypeScript applications require zero source modifications. When using packages that rely on native addons via node-gyp or pre-built binaries, ensuring you are on current package versions guarantees that Arm64 binaries are downloaded automatically during installation.
  • Ruby: Standard Ruby (MRI) runs natively on Linux Arm64 distributions. Pure Ruby scripts and frameworks like Ruby on Rails run unmodified on Graviton. Gems with native C extensions compile automatically during bundle install as long as standard build tools and development headers are present on the instance.
  • PHP: PHP applications, including those built on Laravel, Symfony, or WordPress, execute through the Zend Engine without architecture awareness in the userland code. Installing the standard Arm64 PHP packages and extensions via your Linux distribution package manager allows existing PHP codebases to run immediately.
  • Perl and Lua: Scripts written in Perl or Lua without custom inline assembly or x86-specific C bindings run directly on Arm64 interpreters without modification.

Managed Bytecode and Virtual Machine Runtimes

Languages that compile to intermediate bytecode rather than machine-specific assembly are inherently portable. The virtual machine translates the platform-neutral bytecode into native Arm64 instructions at runtime.

  • Java and JVM Languages (Kotlin, Scala, Groovy, Clojure): Java bytecode (.class and .jar files) follows the write-once, run-anywhere model. You can often take the exact same .jar or .war artifact built on an x86 build server and run it directly on an Amazon Corretto or OpenJDK Arm64 runtime on Graviton. Code changes are only necessary if the application uses Java Native Interface (JNI) libraries compiled exclusively for x86 without an aarch64 counterpart bundled in the archive.
  • .NET (C#, F#, PowerShell): Starting with .NET Core 3.1 and thoroughly matured in .NET 5, 6, 7, and 8, the .NET runtime natively supports Arm64. Framework-dependent deployments built as intermediate language (IL) assemblies require zero source code changes and run directly on the Arm64 .NET runtime, provided the application does not invoke x86-only unmanaged DLLs via P/Invoke.
  • Erlang and Elixir (BEAM): Applications targeting the BEAM virtual machine compile to portable .beam bytecode files. Standard Elixir and Erlang applications, unless utilizing custom C or Rust Native Implemented Functions (NIFs) with x86-specific instructions, transition to Graviton without code edits.
  • WebAssembly (Wasm): Wasm modules compiled to the WebAssembly System Interface (WASI) or executed inside runtimes like Wasmtime or WasmEdge are portable binary targets by design and run unmodified on Arm64 hosts.

Compiled Languages Requiring Only Build Flag Changes

While ahead-of-time (AOT) compiled languages produce architecture-specific binaries, modern systems languages usually require zero changes to your actual source code—only a change to your compilation environment or cross-compilation flags.

  • Go: Go provides built-in cross-compilation. Unless your codebase uses cgo with x86-specific C libraries or platform-specific assembly files, your Go source code remains untouched. You simply compile your binary with the environment variables GOOS=linux and GOARCH=arm64.
  • Rust: Standard Rust code that avoids architecture-specific intrinsics (such as core::arch::x86_64) compiles directly for Graviton by targeting aarch64-unknown-linux-gnu or aarch64-unknown-linux-musl via Cargo.

When Are Changes Actually Required?

Even when using an interpreted or bytecode language, your deployment pipeline or dependency tree might require minor adjustments in the following scenarios:

  1. Container Base Images: While your application code stays the same, your Dockerfile must use multi-architecture base images (such as python:3.12-slim, node:20-alpine, or amazoncorretto:21) rather than images hardcoded to amd64.
  2. Outdated Native Dependencies: Older versions of libraries that wrap C/C++ code might predate widespread Arm64 adoption. Upgrading your dependency lockfiles (package-lock.json, requirements.txt, Gemfile.lock, pom.xml) is typically sufficient to pull in pre-compiled Arm64 binaries (such as updated Netty, gRPC, or RocksDB versions in Java).
  3. Architecture-Specific Intrinsics: Applications written in C, C++, or Rust that explicitly call x86 SIMD instructions (such as SSE or AVX) require refactoring to use portable SIMD abstractions, compiler auto-vectorization, or Arm NEON and SVE equivalents.