String.prototype.padStart()
Pads a string from the start until it reaches a target length.
padStart(targetLength)
padStart(targetLength, padString)- Added in JavaScript ES2017
Parameters
| Parameter | Type | Description |
|---|---|---|
$targetLength | number | The length of the resulting string once the current str has been padded. If the value is less than or equal to str.length, str is returned as-is. |
$padStringoptional | string= " " (the space character, U+0020) | The string to pad the current str with. If padString is too long to stay within targetLength, it is truncated from the end. |
Return value
stringA String of the specified targetLength with padString applied at the start.
padStart() prepends padString, repeating and truncating it as needed, until the result reaches targetLength. It is the standard way to zero-pad a number for display.
Points that catch people out
- It never truncates your string. If
targetLengthis less than or equal to the current length, the string comes back unchanged —"abc".padStart(2, "0")is"abc". Combine withslice()if you need a hard fixed width. - The pad repeats and is cut from its end.
"1".padStart(6, "abc")is"abcab1", not"abcabc1". - An empty padString does nothing — no infinite loop, just the original string.
- Length is measured in UTF-16 code units. An emoji counts as 2, so
"😀".padStart(3, "-")adds only one dash. Aligning columns of text containing emoji or CJK characters withpadStartwill not line up visually.
Only strings have this method: call it on the result of String(n) or n.toString(), not on a number. For alignment in the other direction use padEnd().
Example
When to use it
- Zero-pad hours and minutes when formatting a clock time
- Render an invoice number as a fixed-width id like 000042
- Right-align a column of numbers in console output
- Build a binary or hex string of a fixed bit width
Frequently asked questions
How do I add leading zeros to a number in JavaScript?
Convert it to a string first and call padStart: String(n).padStart(2, "0") turns 5 into "05". padStart only exists on strings, so calling it directly on a number throws a TypeError.
Why is padStart not padding my string?
Because targetLength is less than or equal to the string's current length, in which case the string is returned unchanged. padStart never truncates — chain .slice(-n) after it if you need an exact fixed width.
How does padStart handle a multi-character pad string?
It repeats padString as many times as needed and truncates the last repetition from its end, so "1".padStart(6, "abc") gives "abcab1". An empty padString leaves the string unchanged rather than looping forever.
More examples
Right-aligning a column of numbers
Computing the width from the longest value first means every number lands in the same column: 5 and 7 get two leading spaces, 120 gets none. padEnd fills the label side with dots so the two halves meet cleanly.
const rows = [["apples", 5], ["bananas", 120], ["kiwi", 7]];
const w = Math.max(...rows.map(([, n]) => String(n).length));
for (const [name, n] of rows) {
console.log(name.padEnd(10, ".") + String(n).padStart(w));
}Fixed-width ids and hex
The outputs are 000042, 11111111, 00000101 and 000b. Because toString(radix) drops leading zeros, padStart is what gives a binary or hex value its fixed bit width.
const id = 42;
console.log(String(id).padStart(6, "0"));
console.log((255).toString(2).padStart(8, "0"));
console.log((5).toString(2).padStart(8, "0"));
console.log((11).toString(16).padStart(4, "0"));Padding does not guarantee a width
"7" pads to length 4, but "1234567" is returned untouched at length 7 and the emoji reaches length 4 while occupying only two visible cells. Chaining .slice(-4) is what actually enforces an exact column width.
const values = ["7", "1234567", "\u{1F600}"];
for (const v of values) {
const p = v.padStart(4, "-");
console.log(JSON.stringify(p), p.length);
}
// Force an exact width
console.log("1234567".padStart(4, "-").slice(-4));
Discussion