/^\d+$/ matches a string made only of the digits 0 to 9, at least one of them. \d is a digit, + means one or more, and the anchors do the real work: ^ and $ pin the match to the whole string. Without them, /\d+/ finds the 12 in 12a45 and calls it a match.
What it accepts
The tester below checks one value per line with g and m; for a single value, drop both flags.
12345 matches
007 matches: leading zeros are digits too
0 matches
12a45 no: a letter
-12 no: a sign
3.14 no: a decimal point
١٢٣ no: Arabic-Indic digits
12 345 no: a space
The empty string doesn’t match, because + needs at least one digit. Use ^\d*$ if empty is allowed.
\d in JavaScript is 0 to 9
In JavaScript, \d means exactly [0-9], with or without the u flag. Python’s \d also matches digits from other scripts, such as ١٢٣, unless you pass re.ASCII. To accept any script’s decimal digits in JavaScript, say so: /^\p{Nd}+$/u. Remember that Number('١٢٣') is NaN, so convert those digits yourself before doing arithmetic.
Numbers, not just digits
Digits-only is right for PINs, ZIP codes and account numbers, where 007 must stay 007. Keep such values as strings. For actual numbers:
/^-?\d+$/ // an integer, optionally negative
/^-?\d+(?:\.\d+)?$/ // a decimal such as -3.14
/^\d{1,3}(?:,\d{3})*$/ // with thousands separators: 1,234,567
If you’re about to do math, Number.isInteger(Number(text)) or Number.isFinite(Number(text)) may be all you need, but note that Number('') is 0 and Number(' 12 ') is 12, so test the string with the regex first.
In a form
<input inputmode="numeric" pattern="[0-9]*"> brings up the number pad on phones and lets the browser check the field. The pattern attribute is anchored for you, so it has no ^ or $. Avoid type="number" for codes like PINs: it drops leading zeros and shows a spinner.