Java

There is no AI here. All content is human-authored and tested for accuracy.

Install Java 21 on Mac

How to install Java 21 on Mac step by step. Get the free Java 21 JDK for macOS, install with Homebrew or a PKG, verify the version, and set JAVA_HOME.

Java 21 is NOT the latest version of Java. However, many projects rely on Java 21 and haven't yet migrated to the latest Java version. If you're on a software team or in a university course that uses Java 21, this guide will show you how to install the Java version you need.

While Java 25 is now the current Java version, Java 21 remains an excellent choice for projects that haven't migrated yet. Java releases new versions every six months, but only some get long-term support (LTS). LTS versions receive security updates for years. Released in September 2023, Java 21 was the most recent long-term support (LTS) release before Java 25 and will receive security updates and bug fixes until at least December 2029.

If you're starting a new project, Install Java 25 instead. It's the current LTS release with support until September 2033 and includes additional performance improvements. However, if your team or dependencies haven't caught up yet, Java 21 remains fully supported and production-ready.

If you plan to use both Java 21 and Java 25, or any older versions, consider a version manager like SDKMAN or jEnv. Read Java Version Managers for tools that automate switching.

Read the article Compare Java 21 to Java 25 for a detailed comparison between the two versions. Or get an overview of Java on Mac for an understanding of Java versions, vendor distributions, and installation approaches.

Before you get started

You'll need a terminal application to develop with Java 21. Apple includes the Mac terminal but I prefer Warp Terminal. Warp is an easy-to-use terminal application, with AI assistance to help you learn and remember terminal commands. Download Warp Terminal now; it's FREE and makes coding easier when working with Java.

Check for Java

Check whether you already have Java installed. Learn How to Open Terminal in Mac and run:

$ java -version

If Java is installed, you'll see output showing the version and distribution. Output showing "command not found" means you need to install Java. See Fix "java: command not found" on Mac if you think you already installed Java but can't find it. For detailed guidance on checking and interpreting your Java version, see Check Java Version on Mac.

Choose a Java distribution

Several organizations provide Java 21 builds. All are based on the OpenJDK specification and functionally identical. The only differences are licensing and support. Sun Microsystems developed the Java programming language and the Java Virtual Machine (JVM) in the early 1990s. In 2010, Oracle acquired Sun Microsystems and the Java trademark. Oracle makes a Java JDK available to its enterprise customers but several vendors provide a Java JDK that is freely available for anyone to use without Oracle's strict enterprise licensing. Eclipse Temurin is the most popular choice among developers. It's completely free, backed by the Eclipse Foundation, and receives quarterly security updates.

Read Install JDK on Mac for a comparison of Java distributions.

Install Java 21 with Homebrew

Homebrew is the easiest way to install Java 21. It handles architecture detection, installs to the correct location, and registers Java with macOS automatically. We've got a guide How to Install Homebrew.

My guide Brew Install Java - Easy Cask Method covers Java 25 installation instructions with Homebrew. You can follow the guide, substituting 21 for 25. Here are the basics:

$ brew update
$ brew install --cask temurin@21

The brew update command refreshes Homebrew's package list so you get the latest version. The --cask flag tells Homebrew to install the macOS package rather than using a Homebrew build formula. This installs Java to /Library/Java/JavaVirtualMachines/temurin-21.jdk/, the standard location macOS expects. No additional configuration is needed.

If you don't want Eclipse Temurin, use brew install --cask corretto@21 for Amazon Corretto or brew install --cask zulu@21 for Azul Zulu.

Why not brew install openjdk@21?

You might see recommendations to use brew install openjdk@21 (without --cask). This formula works, but it's "keg-only." That means Homebrew installs it without linking to standard locations. Most developer tools won't detect it until you manually create a symlink. Read Brew Install Java - Formula Method if you'd prefer to install Java 21 with a Homebrew formula. Some develpers will prefer this approach if they are accustomed to installing and configuring other programming languages with Homebrew.

Install Java 21 manually

If you prefer not to use Homebrew to install Java 21 from Eclipse Temurin, you can download the Java installer directly from adoptium.net/temurin/releases. Select macOS and choose aarch64 for Apple Silicon or x64 for Intel Macs. Download the .pkg installer, double-click it, and follow the prompts. The installer places Java at /Library/Java/JavaVirtualMachines/temurin-21.jdk/. Apple's macOS automatically detects JDKs in this location. Read Download Java for Mac for all download options and follow the instructions to Install Java on Mac.

Verify the installation

After installing, confirm Java 21 is working correctly. Run java -version to check. You should see output showing "21" in the version number. Also verify the compiler with javac -version to confirm you have the full JDK.

Running a test program

For extra confidence, compile and run a test program:

$ echo 'public class Hello { public static void main(String[] args) { System.out.println("Java 21 works!"); } }' > Hello.java
$ javac Hello.java
$ java Hello

If you see "Java 21 works!" printed, everything is configured correctly.

Read Check Java Version on Mac for detailed version verification steps.

Set JAVA_HOME

Java tools, such as Maven, Gradle, IntelliJ, and others, use the JAVA_HOME environment variable to find your JDK. Apple's macOS provides a helper utility to locate installed JDKs.

Run /usr/libexec/java_home -v 21 to find your Java 21 path. After finding the Java location, add these lines to your ~/.zprofile file to set JAVA_HOME and update PATH on every new shell:

export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH=$JAVA_HOME/bin:$PATH

See the articles Mac Shell Configuration and Set Mac Path for complete instructions.

After saving, run source ~/.zprofile to apply the changes (or close and reopen your terminal). Verify with echo $JAVA_HOME.

Read Set JAVA_HOME on Mac for complete JAVA_HOME configuration instructions.

JAVA_HOME sets the default version

If you have multiple Java versions installed, the JAVA_HOME configuration will set the version to use. List all installed versions with /usr/libexec/java_home -V to see what's on your system. If you are maintaining projects on different Java versions and need to switch versions frequently, consider a version manager like SDKMAN or jEnv. Read Java Version Managers for tools that automate switching.

Why Java 21?

Though Java is a language first developed in the early 1990s, Java continually improves, both for performance, language features, and developer convenience. Java 21 was a noteworthy advance over the earlier Java 17.

Virtual threads (Project Loom)

Virtual threads are Java 21's headline feature. Traditional Java threads map one-to-one to operating system threads, limiting concurrency to thousands of simultaneous connections. Virtual threads are managed by the JVM and require only ~1KB of memory each, enabling millions of concurrent tasks.

For server applications, this means simpler code that scales better. Instead of reactive frameworks with callbacks, you can write straightforward thread-per-request code that performs like async code. This is the biggest change to Java concurrency since the language was created.

Pattern matching

Java 21 finalizes pattern matching for switch statements and adds record patterns. These features reduce boilerplate when working with complex data:

// Before: verbose type checking
if (obj instanceof String) {
    String s = (String) obj;
    // use s
}

// Java 21: concise pattern matching  
if (obj instanceof String s) {
    // s is already available
}

Pattern matching for switch enables type-based switching with guards, making complex conditional logic cleaner and more readable.

Sequenced collections

New interfaces (SequencedCollection, SequencedSet, SequencedMap) provide uniform methods for ordered collections. Instead of awkward list.get(list.size() - 1), you can write list.getLast(). These interfaces add methods like getFirst(), addFirst(), addLast(), and reversed() across all ordered collection types.

Performance improvements

Generational ZGC delivers roughly 10% better throughput with sub-millisecond pause times. Enable it with -XX:+UseZGC -XX:+ZGenerational. Additional improvements include JIT compiler optimizations and faster startup times.

Upgrading from older Java versions

If you're upgrading an existing project, here's what to expect.

From Java 17

The smoothest upgrade path. Most Java 17 code runs on 21 without changes. Watch for:

  • Method name conflicts with new getFirst() / getLast() methods
  • Security Manager usage (deprecated, will be removed)
  • HTTP client timeout changes (default changed from 20 minutes to 30 seconds)

From Java 11

If you're upgrading from Java 11:

  • UTF-8 is now the default charset (was system-dependent)
  • Strong encapsulation of JDK internals may require --add-opens flags
  • Nashorn JavaScript engine is removed

Use jdeps to analyze your dependencies and jdeprscan to find deprecated API usage.

From Java 8

With Java 8, significant migration effort is required:

  • Module system (JPMS) encapsulates internal APIs
  • javax.* packages moved to jakarta.* for Jakarta EE
  • Removed: JavaFX (now separate), Nashorn, Java Web Start, Applet API

Consider migrating in stages (8 → 11 → 17 → 21) or use OpenRewrite for automated migration recipes.

Framework compatibility

Spring Boot 3.x requires Java 17 minimum and works great with Java 21. If you're on Spring Boot 2.x with Java 8, you'll need to upgrade both the framework and Java together.

  • Spring Boot 3.x – Minimum Java 17, full support for Java 21
  • Spring Framework 6.x – Minimum Java 17, full support for Java 21
  • Quarkus 3.x – Minimum Java 17, full support for Java 21
  • Micronaut 4.x – Minimum Java 17, full support for Java 21
  • Jakarta EE 10 – Minimum Java 11, full support for Java 21

Build tools need updates too. Use Maven 3.9.0+ and Gradle 8.4+ for full Java 21 support.

Troubleshooting

If you see "java: command not found" after installation, verify Java is installed by checking /Library/Java/JavaVirtualMachines/. If the folder exists but Java isn't found, add JAVA_HOME to your shell configuration. If you see the wrong version, list all versions with /usr/libexec/java_home -V and explicitly set Java 21.

Read Fix "java: command not found" for detailed troubleshooting steps.

Quick reference

Here are the essential commands for reference:

# Install Java 21 with Homebrew (recommended)
$ brew update
$ brew install --cask temurin@21
# Check version
$ java -version
$ javac -version
# List all installed JDKs
$ /usr/libexec/java_home -V
# Find Java 21 path
$ /usr/libexec/java_home -v 21
# Set JAVA_HOME (add to ~/.zprofile)
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH=$JAVA_HOME/bin:$PATH
# Reload shell config
$ source ~/.zprofile

Frequently asked questions

Should I use Java 21 or Java 25? Choose Java 25 for new projects. Both are LTS releases, but Java 25 has longer support (until 2033 versus 2031 for Java 21) and includes compact source files, flexible constructors, scoped values, and better performance. Java 21 free updates continue until September 2026, giving you a year to migrate. Read Compare Java 21 to Java 25 for a detailed comparison.

Is Java 21 stable for production? Yes. As an LTS release, Java 21 underwent extensive testing before release. Oracle, Amazon, Azul, and the Eclipse Foundation all provide production-ready builds. Major frameworks like Spring Boot actively support it.

When should I upgrade to Java 21? Upgrade when your dependencies support it—most modern frameworks already do. For greenfield projects, consider starting with Java 25 instead. For existing projects, test thoroughly in a staging environment first.

Does Java 21 support Apple Silicon natively? Yes. All major distributions provide native ARM64 builds for M-series Macs. These run significantly faster than Intel builds under Rosetta 2 emulation. See Java on Apple Silicon or Intel Macs.

What's Next

With Java 21 installed, you're ready to build. Start a new project with your favorite framework, update Maven or Gradle settings to target Java 21, or explore virtual threads with a sample application. If you work on multiple projects with different Java versions, see Java Version Managers for tools that automate switching. If you ever need to remove Java, see Uninstall Java on Mac.

When you're ready to migrate to the latest features and longest support window, see Install Java 25 on Mac for the current LTS release.

My mac.install.guide is a trusted source of installation guides for professional developers. Take a look at the Mac Install Guide home page for tips and trends and see what to install next.