String.prototype.padStart()

The zero-padding method. Its two rules worth remembering: it never truncates, and a multi-character pad is cut off mid-way rather than overshooting.

String methodES2017Live demo
Common call
String(n).padStart(2, '0')
Returns
a new string of at least the target length
Replaces
('00' + n).slice(-2) and while loops
Watch out
it never shortens a string that is already too long
string.padStart(targetLength[, padString])
→ string

Demo

Live evaluation
Try:
Inputs
sstringthe string to pad
lengthnumbertarget length
padstringpad text
Output
'5'.padStart(3, '0')
'005'

Zero-padding a number is what this method is for, and the first case is the whole idiom. The second case is the rule that surprises people: a string already longer than the target is returned UNCHANGED — padStart never truncates, so it cannot be used to enforce a maximum width. The multi-character pad repeats and is then cut to fit exactly, which is why 'ab' padding to length 5 gives 'ababx' rather than overshooting. An empty pad string is a silent no-op.

Parameters

NameTypeRequiredDescription
targetLengthnumberyesDesired final length. A value at or below the current length means no padding at all — the string comes back untouched.
padStringstringno (' ')Text to pad with, repeated as needed and TRUNCATED to fit exactly. An empty pad string does nothing at all.

Return value

string — A new string of at least targetLength, padded on the LEFT. If the string is already that long it is returned unchanged — never truncated.

Common patterns

Format a clock
The canonical use.
const hhmm = `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
Fixed-width identifiers
Keeps ids sortable as text.
const id = String(n).padStart(6, '0');   // '000042'
Enforce a maximum too
padStart alone cannot shorten — slice does.
const fixed = s.slice(0, 8).padStart(8);

Examples

1. Zero padding
'5'.padStart(3, '0')
Returns
'005'
2. Already longer
'abc'.padStart(2, '0')
Returns
'abc'
3. Default is a space
'abc'.padStart(6)
Returns
' abc'
4. Multi-char, cut
'x'.padStart(5, 'ab')
Returns
'ababx'
5. padEnd mirrors it
'x'.padEnd(5, 'ab')
Returns
'xabab'
6. Empty pad
'x'.padStart(5, '')
Returns
'x'

Pitfalls

1. It never truncates
The name says pad, and that is all it does. Code that formats a column assuming padStart guarantees a width breaks the moment a value is longer than expected — the row just gets wider. Combine with slice to bound both ends.
Overflows
'abcdef'.padStart(3, '0')
'abcdef' // length 6
Slice too
'abcdef'.slice(0, 3).padStart(3, '0')
'abc'
2. It only works on strings
Numbers have no padStart, so a numeric value must be converted first. Forgetting is a TypeError, and the fix — String(n) or a template literal — is easy to leave out when refactoring.
Not a function
(5).padStart(3, "0")
TypeError: 5.padStart is not a function
Convert first
String(5).padStart(3, '0')
'005'
3. A multi-character pad is cut mid-character
Truncation happens by code unit, so padding with an emoji or other astral character can leave half a surrogate pair at the join. Stick to single-code-unit pad characters unless you have checked the arithmetic.
Broken half
'x'.padStart(4, '\u{1F600}')
'\u{1F600}\ud83dx'
Plain pad
'x'.padStart(4, '-')
'---x'
4. Padding is not alignment in a proportional font
Spaces line things up only in a monospaced context. In HTML, runs of spaces also collapse unless white-space is preserved, so padded output usually needs CSS rather than string manipulation.
Collapses in HTML
el.textContent = '  x'
leading spaces collapse
Use CSS
text-align: right
actually aligned

When to use

Use it
  • Zero-padding numbers for times, dates and identifiers
  • Fixed-width output in a monospaced context — logs, terminals
  • Making numeric strings sort correctly as text
  • Right-aligning short values in plain text
Reach for something else
  • You need a maximum width too → slice first, then pad
  • Padding on the right → padEnd
  • Aligning in HTML → CSS, not spaces
  • Formatting numbers for humans → toLocaleString or Intl.NumberFormat

Notes

Complexity
O(targetLength)
Return
A new string, or the original when no padding is needed
CPython impl
V8: Builtins-string-pad
Memory
Allocates the padded result
Thread-safe
Single-threaded; the string is only read

FAQ

Because padding and truncating are different operations, and conflating them would make the method lossy. If you need an exact width, slice first and then pad — the two together are explicit about discarding data.

s.slice(0, n).padStart(n, '0');

History

ES2017
padStart and padEnd added together, replacing an assortment of slice and loop idioms.