Java vs JavaScript: The Real Differences, Explained

Aug 4, 2026·15 min read

Java and JavaScript are two unrelated languages that share four letters because of a marketing deal announced in December 1995. Java is statically typed, compiles ahead of time to bytecode, and runs on the JVM. JavaScript is dynamically typed and runs inside an engine that compiles it as it loads, in a browser or in Node.js, Deno and Bun. Neither is a version, subset or dialect of the other, and the differences that actually break code are types, numbers, objects, equality and threading.

The short answer

Java and JavaScript were written by different people, at different companies, for different reasons. They share a prefix and a family resemblance in their braces. The borrowing stops at the surface: the type system, object model, number model and concurrency model share no ancestry.

Java is a statically typed language. You compile source files with javac, which produces .class files full of JVM bytecode, and a JVM runs that bytecode. Types are checked before the program starts.

JavaScript is a dynamically typed language. You hand source text to an engine, and the engine compiles and runs it on the spot. Values carry types; variables do not.

Neither is a version, subset or dialect of the other. JavaScript is not “Java for the browser,” and Java is not “JavaScript with types.” TypeScript is JavaScript with types, and it has nothing to do with Java either.

This article walks through where the shared name came from, who steers each language now, the five differences that change the code you write, and which one to start with.

Why they share a name

Sun Microsystems formally announced Java at SunWorld on 23 May 1995. JDK 1.0 followed on 23 January 1996.

In the same month Sun made its announcement, Brendan Eich was writing something else entirely at Netscape. The first working prototype took about ten days in May 1995. It was code-named Mocha, and it shipped in a Netscape Navigator 2.0 beta under the name LiveScript. The language kept changing for months after that sprint.

Then, on 4 December 1995, Netscape and Sun issued a joint press release. It announced JavaScript as “an open, cross-platform object scripting language,” and said that 28 industry-leading companies would endorse it as a complement to Java for online application development.

That is the whole mechanism. A language that already existed under two other names got a third one, chosen to associate it with the language Sun was promoting. The resemblance is contractual, not technical.

The syntax similarity is real, but it points somewhere else. Both languages take braces, semicolons, if, for, while and C-style function calls from the same ancestry, the way C++, C#, Go and PHP all do. Sharing a grammar family tells you nothing about how a language handles types, memory, objects or concurrency, which is exactly where these two diverge.

Who owns and steers each language today

Two different bodies, two different rhythms, and two trademarks held by the same company.

JavaScript is standardised as ECMA-262 by TC39, a technical committee of Ecma International. Editions ship annually. The 131st Ecma General Assembly, held in Geneva on 30 June 2026, approved the 17th edition, ECMAScript 2026; the 16th edition, ECMAScript 2025, was approved a year earlier. The standard carries the name ECMAScript because Sun held the JavaScript trademark and Ecma could not use it, which is why specification text says one thing and everyone else says another. What browsers and runtimes actually implement is the standard; “JavaScript” is the name the implementations go by.

Java SE is specified through the Java Community Process as a numbered JSR. Java SE 25 is JSR 400. Implementation happens in OpenJDK on a six-month release train: JDK 25 reached General Availability on 16 September 2025 as a Long-Term Support release, and JDK 26 followed on 17 March 2026 as a regular non-LTS release.

Now the trademarks. Oracle completed its acquisition of Sun Microsystems on 27 January 2010, in a deal valued at $7.4 billion, and inherited Sun’s registrations along with it. Oracle holds the U.S. trademark registration for JavaScript, Reg. No. 2,416,017.

That registration is currently being challenged. Deno filed a petition to cancel it with the USPTO’s Trademark Trial and Appeal Board on 22 November 2024 (Cancellation No. 92086835), on grounds of genericness, abandonment and fraud. On 18 June 2025 the board dismissed the fraud claim, leaving genericness and abandonment to proceed. Oracle’s answer was due on 7 August 2025 and the discovery phase opened on 6 September 2025 and runs into mid-2026, with the trial period after it. As of August 2026 the proceeding has not been decided.

Five differences that change the code you write

Here is the same tiny program in both languages. A class that holds a number and bumps it.

public class Counter {
    private int value;

    Counter(int start) {
        this.value = start;
    }

    int next() {
        this.value += 1;
        return this.value;
    }
}
class Counter {
  constructor(start) {
    this.value = start;
  }
  next() {
    this.value += 1;
    return this.value;
  }
}

Same shape, same braces, same word class. Every difference below is invisible here and shows up the moment you use these.

Static types vs dynamic types

In Java the type belongs to the variable, and javac checks it:

int total = 3;
total = "three";  // javac: incompatible types: String cannot be converted to int

That is not a runtime failure. The compiler refuses to produce a .class file, so the program never starts.

In JavaScript the type belongs to the value:

let total = 3;
total = "three";
console.log(total + 1);
three1

Nothing objects. total holds a number, then a string, and + sees a string operand so it concatenates. JavaScript is not untyped: values carry types, and typeof total reports "string". Some wrong operations throw when they run, like calling a method a string does not have, and others go quietly and hand you NaN or a concatenation. The check happens when the line runs, not before. If you want the checking without the JVM, that is what TypeScript is for.

One number type vs eight primitives

Java has eight primitive types: byte, short, int, long, float, double, boolean and char. int is a 32-bit signed integer running from −2,147,483,648 to 2,147,483,647, and integer division truncates:

System.out.println(7 / 2);    // 3
System.out.println(7.0 / 2);  // 3.5

Every JavaScript Number is an IEEE-754 double-precision float. There is no separate integer type:

console.log(7 / 2);
console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2);
3.5
9007199254740991
true

That last line is the consequence. Past 9,007,199,254,740,991 (2⁵³ − 1), integers stop being distinct, so two different arithmetic results compare equal. BigInt exists for integers beyond that range. The numbers chapter covers the rest of the model.

Prototypes underneath the classes

JavaScript got the class keyword in ES2015, and it looks like Java’s. MDN states the relationship plainly: classes in JavaScript are built on prototypes but also have some syntax and semantics that are unique to classes, and instance methods are installed on the class’s prototype property.

You can see it:

class Counter {
  constructor(start) { this.value = start; }
  next() { this.value += 1; return this.value; }
}

const c = new Counter(41);
console.log(c.next());
console.log(Object.hasOwn(c, "next"));
console.log(Object.getPrototypeOf(c) === Counter.prototype);
42
false
true

next is not on the instance. It sits on Counter.prototype, and c reaches it by delegation, following a chain of objects at lookup time. Add a method to Counter.prototype later — Counter.prototype.reset = function () { this.value = 0; }; — and c.reset() works, because the lookup happens when you call, not when you construct. In ordinary Java code, the methods a class has are fixed by the class file the JVM loaded, and lookup goes through the type hierarchy the compiler already checked. The native prototypes chapter shows how far the chain goes.

== means two different things

In Java, == on two objects asks whether they are the same object. Contents are .equals()’s job:

String a = new String("a");
String b = new String("a");
System.out.println(a == b);       // false
System.out.println(a.equals(b));  // true

In JavaScript, == converts its operands before comparing, and === refuses to:

console.log("1" == 1);
console.log("1" === 1);
console.log([] == false);
true
false
true

The third line takes three conversions to compare an empty array with a boolean: false becomes 0, [] becomes "", "" becomes 0, and 0 == 0 is true. So the house rule in JavaScript is to write === unless you have a reason not to, and comparisons explains the exceptions. A Java developer reaching for .equals() will not find it on a JavaScript string, and a JavaScript developer writing == on two Java objects will be asking a question about identity without meaning to.

Threads vs one thread and a loop

This is the deepest architectural difference of the five.

Java runs multiple threads inside one JVM. They share memory, which is why the language has synchronized, locks and a memory model, and why data races are a category of bug you plan around. Virtual threads were finalised in Java 21 (JEP 444), which reached General Availability on 19 September 2023; they let server applications written in a thread-per-request style scale without dedicating an OS thread to every request.

JavaScript runs your code on one thread. The runtime keeps a queue and an event loop, and callbacks run one at a time, to completion:

console.log("1: sync");
setTimeout(() => console.log("4: timer"), 0);
Promise.resolve().then(() => console.log("3: microtask"));
console.log("2: sync");
1: sync
2: sync
3: microtask
4: timer

The timer callback waits for the synchronous code, and the promise callback jumps the timer, even though the timeout is 0. There are two queues: after each turn the runtime drains the microtask queue, where promise callbacks land, all the way to empty before it takes the next task, where timers and I/O land. So a promise callback always beats a setTimeout(…, 0) queued alongside it. Nothing here overlaps. A slow loop in the middle of that script blocks every line after it. For actual parallelism you reach for workers, which get their own global scope and communicate by passing messages rather than by sharing your variables.

”Compiled vs interpreted” is the wrong line

The line you will see repeated is that Java is compiled and JavaScript is interpreted. That stopped describing reality once engines started compiling JavaScript to machine code, and it misdescribes Java too, because the JVM starts out interpreting.

Here are both pipelines.

Java. Source goes through javac, which produces .class files containing JVM bytecode. The JVM loads that bytecode and begins by interpreting it. Tiered compilation, introduced in Java 7 and on by default in HotSpot since Java 8, then promotes methods that run often: C1 compiles them quickly with modest optimisation and adds profiling instrumentation, and C2 takes the hottest ones and spends far more time producing heavily optimised machine code.

JavaScript. Source text arrives at an engine. In V8, which runs in Chrome, Node.js and Deno, the engine parses it — pre-parsing inner functions and compiling each one to Ignition bytecode lazily, on first call — then tiers up through Sparkplug (a baseline JIT shipped in 2021), Maglev (introduced in Chrome M117) and TurboFan, which produces optimised machine code. Firefox’s SpiderMonkey and Safari’s JavaScriptCore name their tiers differently.

Read those side by side and the supposed distinction disappears. Both compile to bytecode. Both interpret that bytecode at first. Both JIT-compile hot code to machine instructions while the program runs.

What actually differs is what artifact ships and when compilation happens. Java ships .class bytecode that you compiled before anyone ran it, so type errors and syntax errors are found on your machine. JavaScript ships source text, and the engine compiles it on load, every load, on the user’s machine. That is the honest line, and it explains the things you can observe: why a Java build step exists at all, why a JavaScript syntax error surfaces in a browser rather than in CI, and why engines work so hard on startup time.

From Source Text to Running Code traces the JavaScript half in detail, and Part 9, Under the Hood covers the engine, the object layout and what the optimising tiers are actually doing.

Where each one actually runs in 2026

The old split, Java on the backend and JavaScript in the browser, has been wrong for years in one direction and is now wrong in the other too.

Java runs server applications, Android apps, large data platforms, build tooling and desktop software, all on a JVM. What it no longer runs is applets. JEP 504 removed the entire java.applet package in JDK 26, which reached General Availability on 17 March 2026. The path there was long: the Applet API was deprecated in JDK 9 (JEP 289, 2017), the appletviewer tool was removed in JDK 11, the API was deprecated for removal in JDK 17 in 2021, and JDK 25 was the last Java SE release to contain it. Any comparison table listing applets as Java’s browser story is describing a package that is gone.

JavaScript is the only programming language that browsers execute natively from source. WebAssembly runs in browsers as well, but it is a compilation target you produce from another language rather than something you type into a <script> tag. On the server, Node.js, Deno and Bun all run JavaScript, and desktop and mobile shells embed engines to run application code.

So the asymmetry is one-directional and worth stating exactly. Both languages write backends now, and choosing between them there is a question about teams, libraries and operations. Only JavaScript runs in the browser.

Which should you learn first?

There is a rule here, not a shrug.

Start with JavaScript if your goal involves anything visible in a browser, or if you want the shortest path from zero to a running program. The engine is already in front of you. Open the console in the tab you are reading this in, type 1 + 1, and you have run a program. There is no toolchain to install and no build step to configure before your first line does something. An Introduction to JavaScript starts from there.

Start with Java if you are targeting Android, joining an existing enterprise JVM codebase, or taking a course or degree that mandates it. In those cases there is no substitute path, and learning JavaScript first will not shorten the trip.

On reach: in the 2025 Stack Overflow Developer Survey, JavaScript topped the list of programming, scripting and markup languages at 66% of all respondents; Java was at 29.4%, seventh in a list that also counts HTML/CSS, SQL and Bash/Shell. That measures self-reported usage among people who took the survey. It is not a count of jobs and not a statement about pay.

Whichever you pick, some habits transfer and some actively mislead. Control flow, braces, function calls, arguments and return values, try/catch, and the general idea of organising code into classes all carry over. What does not carry over is everything in the five-differences section above: expecting a variable’s type to stay put, expecting 7 / 2 to be 3, reaching for .equals(), writing == and meaning identity, assuming class implies a fixed layout, and assuming a compiler will catch the mistake before a user does.

Java vs JavaScript at a glance

JavaJavaScript
OriginAnnounced by Sun at SunWorld, 23 May 1995; JDK 1.0 on 23 January 1996Prototype at Netscape, May 1995; named JavaScript on 4 December 1995
Standard and stewardJava SE through the Java Community Process (Java SE 25 is JSR 400), implemented by OpenJDKECMA-262, by Ecma International’s TC39 (ECMAScript 2026 is the 17th edition)
Release cadenceSix-month train, with periodic LTS releases (JDK 25 LTS, 16 September 2025)Annual ECMAScript editions
TypingStatic; javac rejects the program before it runsDynamic; values carry types, checked as code runs
Number modelEight primitives; int is 32-bit signedEvery Number is an IEEE-754 double; safe integers to 9,007,199,254,740,991; BigInt beyond
Object modelClass-based; methods fixed by the loaded class filePrototype-based; class is syntax built on prototypes
Equality== compares references, .equals() compares contents== converts then compares, === does not convert
ConcurrencyPlatform threads and virtual threads (final in Java 21)One thread with an event loop; workers for parallelism
What ships.class bytecode you compiled ahead of timeSource text the engine compiles on load
RuntimeA JVMA JavaScript engine, in a browser or in Node.js, Deno or Bun
Primary domainsServers, Android, data platforms, desktopBrowsers, servers, desktop and mobile shells

Frequently asked questions

Is JavaScript based on Java?
No. Brendan Eich wrote the first working prototype at Netscape in about ten days in May 1995, under the code name Mocha, and it shipped in a Netscape Navigator 2.0 beta as LiveScript. Netscape and Sun renamed it JavaScript in a joint press release on 4 December 1995, which positioned it as a complement to Java. The language was designed before it got the name.
Is Java compiled and JavaScript interpreted?
Both compile. Java source goes through javac to .class files of JVM bytecode, a compact instruction format for a virtual machine rather than machine code, which the JVM interprets and then JIT-compiles (just-in-time: compiled while the program is already running) to machine code for hot methods. JavaScript source goes to an engine that compiles it to bytecode and then to machine code through several tiers. The real difference is what ships, bytecode you compiled versus source text the engine compiles on load, and when compilation happens.
Which should I learn first, Java or JavaScript?
Start with JavaScript if your goal involves anything visible in a browser, or if you want the shortest path from zero to a running program, because the engine is already in front of you. Start with Java if you are targeting Android, joining an existing JVM codebase, or taking a course that mandates it. Both are C-family languages, so control flow and syntax carry over either way.
Who owns the name JavaScript?
Oracle holds the U.S. trademark registration for JavaScript, Reg. No. 2,416,017, inherited from Sun Microsystems when the acquisition closed on 27 January 2010. Deno filed a petition to cancel it with the USPTO's Trademark Trial and Appeal Board on 22 November 2024. The board dismissed the fraud claim on 18 June 2025; the genericness and abandonment claims are still pending.
Does JavaScript have classes like Java does?
It has the keyword, not the same machinery. MDN puts it directly: classes in JavaScript are built on prototypes but also have syntax and semantics unique to classes. Instance methods live on the constructor's prototype property and instances reach them by delegation, so a Java developer's mental model of a fixed class layout will mislead them.