Perform Matrix Multiplication in JavaScript

Beginner
⏱️ 12 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Linear algebra

What You’ll Learn

Standard matrix multiplication builds each result cell as a row × column dot product: C[i][j] = sum(A[i][k] * B[k][j]), only when inner dimensions match. This tutorial covers the rule, triple nested loops, a live preview, worked JavaScript examples, edge cases, and complexity.

Definition

Row · column

Each C[i][j] is a dot product of row i of A with column j of B.

Shape Rule

(m×n)(n×p)

AB exists only when columns of A equal rows of B; result is m×p.

Triple Loop

i, j, k

Outer i/j pick a cell; inner k accumulates products.

Zero Init

Start at 0

Every result cell is a running sum — initialize before adding.

Live Preview

Show 3×3

Run the classic 3×3 sample product in the browser.

Not Hadamard

Not cell×cell

This is true matrix product — not element-wise multiply.

Introduction

Matrix multiplication combines a row from A with a column from B. If A is m × n and B is n × p, then AB is defined and has size m × p, with C[i][j] = sum over k of A[i][k] * B[k][j].

This is not cell-by-cell multiplication (Hadamard product). Order matters: AB is generally not equal to BA.

Why it matters?

It is a classic interview problem that tests 2D indexing, accumulation, and understanding of linear-algebra shape rules.

Key Highlights

Dot Product Cells

Each output entry is one row dotted with one column.

Inner Dimensions

cols(A) must equal rows(B).

Three Loops

i and j pick the cell; k walks the shared dimension.

O(n³) Classic

Square case uses cubic work with the basic algorithm.

In short: if shapes are compatible, zero-init C, then for each i, j accumulate A[i][k] * B[k][j] over k.

📝 Problem & Approach

Given compatible matrices A and B, build product C = AB using row–column dot products.

JavaScript
// (m x n) * (n x p) -> (m x p)
// C[i][j] = A[i][0]*B[0][j] + A[i][1]*B[1][j] + ...
// Not the same as A[i][j] * B[i][j]

Inputs & Outputs

ItemTypeDescription
A, B2D arraysCompatible matrices: cols(A) == rows(B).
Return / printmatrix / textProduct matrix of size rows(A) × cols(B).

Minimal workflow

Pseudocode
function multiply(A, B):
    n <- size
    C <- n x n matrix of zeros
    for i from 0 to n - 1:
        for j from 0 to n - 1:
            for k from 0 to n - 1:
                C[i][j] <- C[i][j] + A[i][k] * B[k][j]
    return C

Method comparison

MethodIdeaNotes
Triple nested loopsAccumulate A[i][k]*B[k][j]Interview default — clear and correct
Element-wise (Hadamard)A[i][j] * B[i][j]Different operation — same shape required
Library matMul helpersLibrary productProduction path; show loops in interviews

⚡ Quick Reference

GoalPattern
Accumulate cellresult[i][j] += a[i][k] * b[k][j]
Triple loopfor i / for j / for k
Zero-initArray.from({ length: n }, () => Array(n).fill(0))
Shape checka[0].length === b.length (cols A == rows B)
Result sizem x p when A is m x n, B is n x p
Trace one cellTop-left 3×3 sample: 1*9 + 2*6 + 3*3 = 30

📋 Matrix Product vs Hadamard vs Library Helpers

Same word “multiply” — very different meanings.

Matrix product
sum A[i][k]*B[k][j]

This page — classic interview style

Hadamard
A[i][j] * B[i][j]

Element-wise — needs same shape

Library
matMul(A, B)

Fast in apps; show loops in interviews

Interview tip
state shape first

Say (m×n)(n×p)→m×p before coding

Context

When This Problem Shows Up

Reach for true matrix products when rows must combine with columns.

  1. Interview classics

    Triple loops plus shape rules are a common warm-up.

  2. After entrywise ops

    Natural step up from addition/division in this chain.

  3. Linear transforms

    Compose maps, graphics, and simple ML layers.

  4. Teaching accumulation

    Practice running sums over a shared index k.

  5. Not for Hadamard

    Clarify when the interviewer wants cell-by-cell multiply.

Key benefit: one short problem that locks in indexing, accumulation, and the (m×n)(n×p)→m×p rule.

🔮 Live Preview

Uses the same 3×3 matrices as Example 1. Click to display both inputs and the product matrix.

Matches the JavaScript sample values below.

Live result
Press “Show 3x3 product”.

Examples Gallery

Three complete JavaScript programs — classic 3×3 product, easy-to-verify 2×2, and a shape-safe general multiplier. Click View Output to reveal sample console results.

📚 Getting Started

Triple nested loops with a zero-initialized result matrix.

Example 1 — Multiply Two 3×3 Matrices

Classic interview-style implementation with helpers for multiply and display.

JavaScript
const N = 3;

function multiplyMatrices(a, b) {
  const result = [];
  for (let i = 0; i < N; i++) {
    result[i] = [];
    for (let j = 0; j < N; j++) {
      result[i][j] = 0;
    }
  }
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < N; j++) {
      for (let k = 0; k < N; k++) {
        result[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return result;
}

function displayMatrix(matrix) {
  for (let i = 0; i < N; i++) {
    console.log(matrix[i].join("\t"));
  }
}

const firstMatrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];
const secondMatrix = [
  [9, 8, 7],
  [6, 5, 4],
  [3, 2, 1],
];

const result = multiplyMatrices(firstMatrix, secondMatrix);

console.log("First Matrix:");
displayMatrix(firstMatrix);
console.log("\nSecond Matrix:");
displayMatrix(secondMatrix);
console.log("\nResult Matrix:");
displayMatrix(result);

How It Works

The innermost loop computes one dot product for each result cell: result[i][j] += a[i][k] * b[k][j]. Top-left output is 1*9 + 2*6 + 3*3 = 30.

⚡ Easy Manual Check

Same logic on a smaller matrix so you can verify by hand.

Example 2 — Smaller 2×2 Product

Same triple-loop pattern with values that are easy to dry-run.

JavaScript
const N = 2;

function multiplyMatrices(a, b) {
  const result = [];
  for (let i = 0; i < N; i++) {
    result[i] = [];
    for (let j = 0; j < N; j++) {
      result[i][j] = 0;
      for (let k = 0; k < N; k++) {
        result[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return result;
}

function printMatrix(title, m) {
  console.log(title);
  for (let i = 0; i < N; i++) {
    console.log(m[i].join(" "));
  }
}

const a = [[1, 2], [3, 4]];
const b = [[5, 6], [7, 8]];
const r = multiplyMatrices(a, b);

printMatrix("A", a);
console.log();
printMatrix("B", b);
console.log();
printMatrix("AB", r);

How It Works

Top-left value is 1*5 + 2*7 = 19; top-right is 1*6 + 2*8 = 22. Matching the printed AB confirms the accumulation logic.

⚙️ General Shape Validation

Drop fixed N and enforce cols(A) == rows(B).

Example 3 — Shape-Safe General Product

Checks inner dimensions, then multiplies any compatible m×n by n×p.

JavaScript
function canMultiply(a, b) {
  if (!a.length || !b.length || !a[0].length || !b[0].length) {
    return false;
  }
  const colsA = a[0].length;
  const rowsB = b.length;
  if (colsA !== rowsB) {
    return false;
  }
  const colsB = b[0].length;
  for (let i = 0; i < a.length; i++) {
    if (a[i].length !== colsA) {
      return false;
    }
  }
  for (let i = 0; i < b.length; i++) {
    if (b[i].length !== colsB) {
      return false;
    }
  }
  return true;
}

function multiplySafe(a, b) {
  if (!canMultiply(a, b)) {
    return null;
  }
  const m = a.length;
  const n = a[0].length;
  const p = b[0].length;
  const result = Array.from({ length: m }, () => Array(p).fill(0));
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < p; j++) {
      for (let k = 0; k < n; k++) {
        result[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return result;
}

const ok = multiplySafe([[1, 2, 3], [4, 5, 6]], [[7, 8], [9, 10], [11, 12]]);
const bad = multiplySafe([[1, 2], [3, 4]], [[5, 6, 7]]);
console.log(JSON.stringify(ok));
console.log(bad);

How It Works

First sample is 2×3 times 3×22×2. Second fails because columns of A (2) do not match rows of B (1).

🧠 How the Algorithm Builds C

1

Check shapes

Require cols(A) == rows(B); result will be rows(A) × cols(B).

Shape
2

Zero-init C

Create an m×p matrix of zeros before accumulation.

Init
3

Triple loop

For each i, j accumulate A[i][k] * B[k][j] over k.

Loops
=

Product matrix ready

C holds every row–column dot product.

🔎 Worked Walkthrough — Top Row of 3×3

Trace the first row of C for the Example 1 matrices.

CellDot productValue
C[0][0]1*9 + 2*6 + 3*330
C[0][1]1*8 + 2*5 + 3*224
C[0][2]1*7 + 2*4 + 3*118

First row of the result is [30, 24, 18] — matching Example 1 output.

Use Cases

Where true matrix multiplication shows up beyond the interview prompt.

1. Interview Warm-Ups

2D indexing plus accumulation over k.

Example: write multiplyMatrices(A, B).

2. After Entrywise Ops

Step up from addition/division to products.

Example: compare with Hadamard multiply.

3. Linear Transforms

Compose maps in graphics and simple ML.

Example: apply a 2×2 transform to points.

4. Shape Reasoning

Practice (m×n)(n×p)→m×p checks.

Example: reject incompatible pairs.

5. Complexity Talk

State O(n³) for the classic square case.

Example: mention a library helper for large n.

6. Precursor to Subtract

Next page returns to entrywise ops.

Example: continue the matrix chain.

Pro Tip: open with “(m×n)(n×p)→m×p, C[i][j] is a row–column dot product” before writing loops.

Advantages

Why the classic triple-loop approach works well in interviews.

  1. 1. Clear Formula

    One rule: C[i][j] = sum of A[i][k] * B[k][j].

  2. 2. Easy to Trace

    2×2 dry-runs verify understanding in seconds.

  3. 3. Forces Shape Thinking

    Inner-dimension checks are a natural follow-up question.

  4. 4. Maps to Libraries

    Same idea as library matrix helpers — you just write the loops by hand.

Pro Tip: lead with loops and zero-init; mention library helpers only as a production aside.

Usage Tips

Small habits that keep matrix-multiplication solutions interview-ready.

  1. 1. State Shapes First

    Say (m×n)(n×p)→m×p before writing code.

  2. 2. Zero-Init Every Cell

    Accumulation requires starting at zero.

  3. 3. Keep k as the Shared Index

    Always pair A[i][k] with B[k][j].

  4. 4. Build Fresh Row Lists

    Avoid [[0]*n]*n shared references.

  5. 5. State O(n³) / O(mnp)

    Square vs rectangular complexity in one sentence.

Pro Tip: dry-run 1*5 + 2*7 = 19 aloud on the 2×2 sample — if that matches, your indexing is correct.

Common Pitfalls

Mistakes that commonly break matrix-multiplication solutions.

  1. 1. Inner Dimensions Mismatch

    Multiplying when cols(A) ≠ rows(B).

    → Validate shapes before looping.

  2. 2. Doing Element-Wise Multiply

    Writing A[i][j] * B[i][j] instead of a dot product.

    → Use three loops and the k index.

  3. 3. Forgetting Zero Init

    Accumulating into uninitialized cells.

    → Start every C[i][j] at 0.

  4. 4. Assuming AB = BA

    Order usually changes the result (or validity).

    → Multiply in the requested order only.

  5. 5. Shared Row Initialization

    [[0]*n]*n shares row lists.

    → Build each row separately.

Edge Cases

Common beginner mistakes — plus a few more.

Shape

Inner dimensions mismatch

Cannot multiply unless columns of A equal rows of B.

Order

AB is not always BA

Changing order usually changes result, and sometimes makes multiplication invalid.

Logic

Forgetting zero init

If result cells do not start at zero, accumulation gives incorrect values.

Ragged

Uneven rows

Validate every row length before multiplying.

1×1

Single cell

Still a product: C[0][0] = A[0][0] * B[0][0].

Rect

Non-square pairs

Use m, n, p — not a single N — when shapes differ.

⚖️ Facts Worth Knowing

Handy follow-ups interviewers sometimes ask.

  • Associative. (AB)C = A(BC) when shapes allow — but not commutative.
  • Not commutative. AB is generally not equal to BA.
  • Identity. AI = IA = A for the compatible identity matrix I.
  • Cost. Classic algorithm is O(n³) for n×n; faster algorithms exist but are advanced.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Dry-run 2×2

  • Reproduce Example 2 by hand
  • Expect [[19, 22], [43, 50]]

2. Trace C[0][0] on 3×3

  • Compute 1*9 + 2*6 + 3*3
  • Confirm 30 matches Example 1

3. Reject bad shapes

  • 2×2 times 3×2 → null or throw
  • Assert cols(A) == rows(B)

4. Rectangular product

  • Multiply 2×3 by 3×2
  • Drop fixed N; use m, n, p

Notes

  • Rule: C[i][j] = sum(A[i][k] * B[k][j]), with compatible dimensions.
  • Code pattern: initialize result to zeros, then use three loops.
  • Complexity: cubic for square matrices with the basic algorithm.
  • Non-square matrices use rowsA, colsA, and colsB with the check colsA == rowsB.

Quick Takeaway: compatible shapes first, zero-init C, then accumulate A[i][k]*B[k][j] with three nested loops.

⏱️ Time and Space Complexity

SettingTimeExtra space
Two n × n matrices, classic triple loopO(n^3)O(1) beyond output
m × n by n × pO(m*n*p)O(1) beyond output
Shape validationO(m + n) row checksO(1)

For large matrices, production code usually switches to optimized libraries; interviews still expect the triple-loop explanation.

Wrap Up

🎉 Conclusion

Matrix multiplication builds each result cell as a row–column dot product when inner dimensions match. Zero-init the result, use three nested loops, and distinguish this from element-wise multiplication.

Practice the three examples above, then continue to matrix subtraction for the next entrywise operation.

Compatible shapes first, zero-init C, then C[i][j] += A[i][k] * B[k][j].

💡 Best Practices

✅ Do

  • State (m×n)(n×p)→m×p first
  • Zero-init the result matrix
  • Use three nested loops with index k
  • Dry-run one cell by hand
  • State O(n³) or O(mnp) complexity

❌ Don’t

  • Multiply incompatible shapes
  • Confuse this with Hadamard multiply
  • Skip zero initialization
  • Assume AB equals BA
  • Use shared-row list init

Key Takeaways

Knowledge Unlocked

Five things to remember about matrix multiplication

Multiply matrices the interview-friendly way.

5
Core concepts
= 02

Shape

(m×n)(n×p)

Constraint
3 03

Loops

i, j, then k

Pattern
0 04

Init

Start at zero

Safety
O 05

Cost

O(n³) / O(mnp)

Analysis

❓ Frequently Asked Questions

The number of columns of A must equal the number of rows of B. If A is m×n and B is n×p, the product AB exists and is m×p. If those inner sizes differ, multiplication is not defined this way.
No. Element-wise multiplication (Hadamard product) only works for same-shaped matrices and multiplies matching entries. Standard matrix multiplication uses the row-column dot-product rule shown on this page.
Typical order: i loops rows of the result, j loops columns of the result, k walks along the shared dimension to accumulate sum_k A[i][k]*B[k][j]. Some codes reorder loops for cache performance, but the math is the same.
Because each result entry is built as a running sum: result[i][j] += ... You must start from zero before adding products.
Products and sums can exceed Number.MAX_SAFE_INTEGER for large entries or sizes. Use BigInt matrices or floating-point paths when the problem demands it.
The classic triple loop does Θ(n³) arithmetic operations for square n×n matrices. Space aside from inputs/output is O(1) extra if you only store a few loop variables.
Not in general. Matrix multiplication is not commutative: AB and BA can differ, and one order may even be undefined.
Libraries can multiply matrices in bulk. Interviews usually want the triple-loop version first so you show indexing clearly.
Use the Try it Yourself links under each code sample — they open an in-browser editor with the same logic so you can edit the input and Run.

Did you Know? 🔊

Matrix multiplication links rows of A with columns of B. You need A to be m × n and B to be n × p—the two n’s must match—then AB is m × p.

Continue to Matrix Subtraction

Learn entrywise subtraction with matching dimensions — a simpler return to cell-by-cell ops.

Matrix subtraction tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful