react-bigint-input
v1.0.0
Published
A React input component for BigInt values with decimal formatting. Built for crypto/DeFi apps.
Maintainers
Readme
✨ Features
- 🧮 True BigInt — no floating point, no precision loss
- 🌍 Locale-aware formatting —
1,000.50or1.000,50or1,00,000— auto-detects or configure per-locale - 🔢 Configurable decimals — set 18 for ETH, 6 for USDC, or any token precision
- 📋 Paste handling — sanitizes pasted values
- 🎯 Min/max clamping — enforced on every keystroke
- 📦 Zero dependencies — no ethers or viem required
- 🏗️ Works everywhere — React 17, 18, and 19
📦 Install
npm install react-bigint-input🚀 Quick Start
import { useState } from 'react'
import { BigIntInput } from 'react-bigint-input'
function SwapForm() {
const [amount, setAmount] = useState(0n)
return (
<BigIntInput
value={amount}
decimals={18}
onChange={setAmount}
/>
)
}🌍 Formatting
By default, numbers are formatted US-style (1,000.50). Most crypto users are familiar with this format regardless of locale.
⚠️ Changing the format can confuse users who expect US formatting. Use at your own risk.
// Default (US): 1,000.50 — recommended for most crypto apps
<BigIntInput value={amount} decimals={18} onChange={setAmount} />
// Auto (browser locale)
<BigIntInput value={amount} decimals={18} onChange={setAmount} format="auto" />
// Specific locale (Indian: 1,00,000 / German: 1.000,50)
<BigIntInput value={amount} decimals={18} onChange={setAmount} format={{ locale: 'en-IN' }} />
<BigIntInput value={amount} decimals={18} onChange={setAmount} format={{ locale: 'de-DE' }} />
// Custom separators
<BigIntInput value={amount} decimals={18} onChange={setAmount} format={{ thousand: '.', decimal: ',' }} />
// No formatting (raw digits): 1000.50
<BigIntInput value={amount} decimals={18} onChange={setAmount} format="none" />🎯 Min / Max
<BigIntInput
value={amount}
decimals={6}
onChange={setAmount}
max={100000000n} // 100 USDC
min={1000000n} // 1 USDC
/>Values are clamped on every keystroke — no invalid states.
📐 Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | bigint | — | Current value in smallest unit (e.g. wei) |
| decimals | number | — | Token decimals (18 for ETH, 6 for USDC) |
| onChange | (v: bigint) => void | — | Fires when value changes |
| max | bigint | — | Clamp to maximum |
| min | bigint | — | Clamp to minimum |
| format | FormatConfig \| "auto" \| "none" | { thousand: ",", decimal: "." } | Number formatting |
| allowNegative | boolean | false | Allow negative values |
| showZero | boolean | false | Show "0" instead of empty |
| placeholder | string | "0" | Placeholder text |
| disabled | boolean | false | Disable input |
| readOnly | boolean | false | Read-only mode |
| className | string | — | CSS class |
| style | CSSProperties | — | Inline styles |
Plus: name, id, autoFocus, onFocus, onBlur.
FormatConfig
interface FormatConfig {
locale?: string // Use Intl.NumberFormat with this locale (e.g. 'de-DE', 'en-IN')
thousand?: string // Thousands separator (default: ',')
decimal?: string // Decimal separator (default: '.')
}When locale is set, grouping uses Intl.NumberFormat (handles Indian lakh/crore, etc.). thousand and decimal can override the detected separators.
🧰 Utilities
Format and parse BigInt values outside the input:
import { formatValue, parseValue } from 'react-bigint-input'
// Format for display
formatValue(1234567890n, 6) // "1,234.56789"
formatValue(1234567890n, 6, { locale: 'de-DE' }) // "1.234,56789"
formatValue(1234567890n, 6, 'none') // "1234.56789"
// Parse back to BigInt
parseValue('1,234.56789', 6) // 1234567890n
parseValue('1.234,56789', 6, { locale: 'de-DE' }) // 1234567890nSame format config as the component prop.
🤔 Why?
Every crypto project builds a BigInt input from scratch. Most have bugs:
- 💥 Crash when switching token decimals mid-input
- 🔢 Floating point precision errors (
0.1 + 0.2 ≠ 0.3) - 📋 Can't handle paste or edge cases
- 📚 Depend on ethers/viem just for
formatUnits - 🔤 No separator support or cursor jumps around
This package does one thing well.
📄 License
MIT
