jsguides

String.prototype.padStart()

str.padStart(targetLength[, padString])

String.prototype.padStart() pads the current string with a given character (or characters) from the beginning (left side) until it reaches the specified length. This method is perfect for left-padding strings to achieve fixed-width alignment, such as formatting numeric IDs, zero-padding numbers, or ensuring consistent column widths in formatted output.

Syntax

str.padStart(targetLength)
str.padStart(targetLength, padString)

Parameters

ParameterTypeDefaultDescription
targetLengthnumberThe length the resulting string should have
padStringstring" " (space)The string to pad with

Return Value

A new string of the specified length, with the padding prepended to the start.

Examples

Basic padding

By default, padStart() uses spaces. Omitting the second argument is equivalent to passing a single space — the method fills the gap with invisible padding. This is the simplest form of padStart() and works well for visual alignment in plain-text output:

"hello".padStart(10);
// "     hello"

"test".padStart(6);
// "  test"

Numeric month formatting

Space padding is fine for labels, but zero-padding is the go-to pattern for dates and numeric IDs. A common use case is formatting dates — left-padding month and day numbers with zeros so single-digit values align perfectly with double-digit ones:

const month = 3;
const day = 5;

`${month}`.padStart(2, "0") + "/" + `${day}`.padStart(2, "0");
// "03/05"

// Or with a date object
const now = new Date();
const formattedMonth = String(now.getMonth() + 1).padStart(2, "0");
const formattedDay = String(now.getDate()).padStart(2, "0");
// Example output: "03/05"

Custom multi-character padding strings

Single-character padding covers most practical cases, but padStart() accepts any string as the pad material, and the behavior with longer pad strings is worth understanding. The padString argument can be any text, not just single characters like "0". If the pad string is longer than the space available, it gets truncated from the right. If it is shorter, the method repeats it until the target length is reached — the final repetition may be cut off mid-string:

// Pad with zeros (common for IDs)
"42".padStart(5, "0");
// "00042"

// Pad with dashes
"end".padStart(7, "-");
// "----end"

// Multi-character padding gets truncated to fit
"ab".padStart(6, "XYZ");
// "XYZab" (truncates to 4 chars to reach length 6)

// Repeats and truncates the padding string
"x".padStart(8, "AB");
// "ABABABax"

Fixed-width table alignment

Beyond simple padding, padStart() is a compact way to format tabular data with consistent column widths. By setting the same target length for each value in a column, you produce aligned output without string concatenation or manual spacing arithmetic. Use padStart() for left-aligned columns in log output or terminal displays:

const items = [
  { id: "1", name: "Widget", price: "$9.99" },
  { id: "42", name: "Gadget", price: "$19.99" },
  { id: "256", name: "Gizmo", price: "$299.99" }
];

console.log("ID    | NAME    | PRICE");
console.log("------|---------|-------");

items.forEach(({ id, name, price }) => {
  console.log(`${id.padStart(4)}| ${name.padStart(8)}| ${price}`);
});

// Output:
// ID    | NAME    | PRICE
// ------|---------| -------
//    1 | Widget  | $9.99
//   42 | Gadget  | $19.99
//  256 | Gizmo   | $299.99

The examples so far cover the common cases, but padStart() has a few edge behaviors worth knowing. When the target length is less than or equal to the string’s current length, it returns the original without modification. An empty pad string also produces the original. And since padStart() counts UTF-16 code units rather than visible characters, padding around emoji can produce unexpected results:

Edge Cases

// If targetLength <= string length, returns original string
"hello".padStart(3);
// "hello"

// Empty padString returns original
"test".padStart(8, "");
// "test"

// Unicode characters count as single units
"👍".padStart(4, "x");
// "x👍xx"

Browser Compatibility

padStart() was introduced in ES2017 (ECMAScript 8) and is supported in:

  • Chrome/Edge 57+
  • Firefox 48+
  • Safari 11+
  • Node.js 8.0+

Now that you have seen how padStart() behaves with edge inputs, here is what to know about environment support. padStart() was added in ES2017, so it is available in all modern browsers and Node.js 8+. If you need to support older runtimes, a small polyfill covers the gap:

if (!String.prototype.padStart) {
  String.prototype.padStart = function(targetLength, padString) {
    targetLength = targetLength >> 0;
    padString = String(padString || ' ');
    if (this.length > targetLength) return String(this);
    return padString.repeat(targetLength - this.length) + String(this);
  };
}

padStart() vs manual left-padding

Before ES2017, developers wrote manual zero-padding helpers that checked string length and built a filler string with new Array() and join(). These helpers were verbose and easy to get wrong — off-by-one errors in the width calculation were common. With padStart(), the same logic collapses to a single readable call:

// Before padStart()
function zeroPad(n, width) {
  const s = String(n);
  return s.length >= width ? s : new Array(width - s.length + 1).join('0') + s;
}

// With padStart()
String(n).padStart(width, '0');

The built-in version handles edge cases correctly: if the number is already wider than the target, it returns the original string unchanged rather than truncating.

Unicode and string length

padStart() measures length in JavaScript string units (UTF-16 code units), not visible characters. Most Latin characters are 1 unit. Emoji and many non-BMP Unicode characters are 2 units (a surrogate pair):

"😀".length;              // 2 — one emoji, two code units
"😀".padStart(4, "x");   // "xx😀" — adds 2 x's to reach length 4

// For visual alignment in terminals, display width differs from length

For padding numbers and ASCII strings — by far the most common use case — this distinction does not matter. It only becomes relevant when padding strings that contain emoji or extended Unicode characters.

padStart() does not truncate

If the string’s current length already meets or exceeds targetLength, padStart() returns the original string unchanged. It never shortens strings:

"hello".padStart(3);      // "hello" — already longer than 3
"1234".padStart(4, '0');  // "1234" — already exactly 4, no change

This makes padStart() safe to apply without length checks — you can call it defensively on any string.

When padStart() is the better fit

padStart() is useful when the beginning of the string needs a fixed width but the original content should stay intact. That makes it ideal for IDs, serial numbers, tabular labels, and visual alignment in logs or previews.

It is also a good alternative to manual string concatenation because it handles repeated filler characters for you. The call reads like a formatting rule instead of a small loop, which makes the code easier to maintain.

See Also