Skip to the solution
HardFrontend10 min read

What is the difference between AOT and JIT compilation?

1.2k views

The problem

Question presented to candidate: "Angular templates are not JavaScript, yet the browser runs them. Explain the difference between AOT and JIT compilation, which one a production build uses, and what would concretely get worse if we switched to JIT."

What a strong answer should cover:

  • Both turn templates and decorators into JavaScript instructions; the difference is when: at build time (AOT, Ahead-of-Time) or in the browser at startup (JIT, Just-in-Time).
  • AOT is the default for ng build and ng serve (aot defaults to true); JIT ships @angular/compiler to the browser.
  • AOT gives smaller bundles, faster startup (no compile step in the browser) and build-time errors: template type-checking and syntax errors fail the build instead of a user's session.
  • AOT is required for modern APIs: signal input(), model() and signal queries rely on the compiler; plain JIT cannot see them.
  • JIT still appears in tests and tooling (for example TestBed compiling components, or partially compiled libraries without the linker).
  • AOT is also safer: no runtime template compilation means no eval-style template injection.

Clarifying questions expected:

  • "Production builds only, or also tests and the dev server?"
  • "Should I go into what the compiled output looks like?"

Code / implementation expected: Optional — the same component compiled both ways, or a template error that only AOT catches.

  • compilation
  • aot

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

10 min read · 11 sections

Read the code

AngularDecorator inputs and inject(): identical behaviour under AOT and JIT
import { Component, Injectable, Input, inject } from "@angular/core";

@Injectable({ providedIn: "root" })
export class PriceService {
  format(n: number) { return `$${n.toFixed(2)}`; }
}

// Decorator input + inject(): this file behaves the same under AOT (ng build) and JIT.
@Component({
  selector: "price-tag",
  template: `<span>{{ label }}: {{ prices.format(amount) }}</span>`,
})
export class PriceTagComponent {
  @Input() label = "";
  @Input() amount = 0;
  prices = inject(PriceService); // inject() needs no type metadata, unlike constructor(private p: PriceService)
}

@Component({
  selector: "app-root",
  imports: [PriceTagComponent],
  template: `
    <price-tag label="Basic" [amount]="9" />
    <price-tag label="Pro" [amount]="pro" />
    <button (click)="pro = pro + 10">Raise Pro</button>
  `,
})
export class AppComponent {
  pro = 29;
}
AngularA signal input: works with the Angular compiler (AOT), fails under plain JIT
import { Component, input } from "@angular/core";

// Signal input: input() is recognised by the Angular compiler (AOT), not by plain JIT.
@Component({
  selector: "price-tag",
  template: `<span>{{ label() }}: USD {{ amount() }}</span>`,
})
export class PriceTagComponent {
  label = input("");
  amount = input.required<number>();
}

@Component({
  selector: "app-root",
  imports: [PriceTagComponent],
  template: `<price-tag label="Pro" [amount]="29" />`,
})
export class AppComponent {}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 79 of 121 in Angular

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Angular questions
Up nextHard

What are security vulnerabilities in Angular apps, and how does DomSanitizer prevent XSS?

Continue