Comparisons

Pairs that get conflated in real conversations, and in real pull requests. Neither column wins — what decides is the requirement. Each record leads with the confusion, because the confusion is the reason the record exists.

Polyfills vs Transpilation

What people get wrong about this pair

Both are filed under "browser support" and configured in the same build step, so people assume one setting covers both. It does not, and the failure modes are different in a way that matters. A syntax the parser does not understand is a parse error: the whole script fails before a single line runs, and it fails at load, which is loud. A missing runtime API is a TypeError at the moment that line executes, which may be deep inside a rarely-used branch and may only happen for the small slice of users on that engine — quiet, late, and hard to reproduce. The other half of the confusion is the cost: transpiled output is usually a little larger and occasionally slower, while a polyfill is real code shipped to every user including the ones who did not need it, which is why conditional or feature-detected loading exists. And a polyfill cannot always be faithful — some behaviour is not implementable from userland at all.

Transpilation (down-levelling syntax)
Use it when

When the target browser's parser does not understand the syntax you wrote — optional chaining, class fields, async generators, JSX, TypeScript type annotations. The compiler rewrites it into syntax the parser accepts.

Polyfilling (supplying a missing runtime API)
Use it when

When the syntax parses fine but the object, method or global does not exist at runtime — a newer Array or String method, a constructor, an observer API. Code is added that defines it.

DimensionTranspilation (down-levelling syntax)Polyfilling (supplying a missing runtime API)
FixesSyntax the parser rejectsObjects and methods that do not exist
Failure without itParse error — the whole file never runsTypeError at the call site, possibly much later
Applied byA compiler rewriting your sourceExtra code that runs before yours
Ships to usersRewritten equivalent of your own codeAdditional library code, often for everyone
Detectable at runtimeNo — it already happened at build timeYes — feature detection is how conditional loading works
Can it always be doneUsually, though output may be larger or slowerNo — some platform behaviour cannot be reproduced in userland
Typical configCompiler target and browser listA polyfill library, ideally loaded conditionally