skills/web3-format-number/SKILL.md
Use when displaying token balances or token values in UI, converting user input to bigint for contract writes, or doing math with wei/token amounts in viem or wagmi apps. Web3 number formatting with formatUnits, parseUnits, BigNumber, bigint naming (`Raw`, `Formatted`, `Bn`), decimals handling, and reusable display helpers. Triggers on token balance, formatUnits, parseUnits, wei, decimals, bigint, BigNumber, number formatting, or web3 display math.
npx skillsauth add tianyili/skills web3-format-numberInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Format web3 values for UI and contract writes without losing precision.
viem or wagmi / wagmi/actionsbignumber.js{variableName}formatUnits: {variableName}RawformatUnits: {variableName}Formatted{variableName}BnKeep the representation obvious in the variable name. This prevents mixing display values, math values, and contract-write values.
bigint, become a formatted string, or become BigNumber for math?| Situation | Use | Why |
|-----------|-----|-----|
| Read from contract | bigint + formatUnits | Keep onchain precision, format only for UI/math |
| User input before write | parseUnits to bigint | Convert display input back to raw contract value |
| Math on token values | BigNumber | Avoid JS float precision loss |
| General UI display | formatted string or display helper | Keep formatting decisions out of components |
Use bigint as the source of truth. Keep the raw value as *Raw, then derive a formatted value.
function useTokenBalance() {
const { data } = useReadContract(/** read user token balance */)
const userTokenBalanceRaw = data
return {
userTokenBalanceRaw,
userTokenBalanceFormatted: formatUnits(data ?? 0n, /** token decimals */ 18),
}
}
Parse user-entered display values to raw bigint right before the write.
import type BigNumber from 'bignumber.js'
import { parseUnits } from 'viem'
function useSendToken(inputAmount: BigNumber.Value) {
const { mutateAsync } = useWriteContract()
function sendToken() {
const inputAmountRaw = parseUnits(String(inputAmount), /** token decimals */ 18)
return mutateAsync({
/** erc20 send token */
})
}
}
Align decimals first, then do math in BigNumber, then convert back to raw for contract writes.
const inputTokenRaw = 20000000000000000000n
const rewardRate = 1.5
const inputTokenFormatted = formatUnits(inputTokenRaw, 18)
const rewardTokenBn = BigNumber(inputTokenFormatted).mul(rewardRate)
const shouldMintTokenRaw = parseUnits(rewardTokenBn.toString(), 18)
Use one display helper so components do not re-implement decimal or tiny-value rules.
import { formatValueToStandardDisplay } from 'xxx/formatValueToStandardDisplay'
function DisplayTokenBalance({ tokenAmount }: { tokenAmount: BigNumber.Value }) {
return <div>{formatValueToStandardDisplay(tokenAmount)}</div>
}
templates/formatValueToStandardDisplay.ts.templates/formatCommonNumbers.ts.BigNumber parsing, shared formatting, suffixes (K, M, B, T), or conversion helpers, read templates/bignumber.ts.templates/unicodeSubscriptionFormat.ts.Do NOT read templates when you only need the core viem flow (formatUnits, parseUnits, bigint) and are not implementing reusable display helpers.
number or float math for token or wei values. Precision loss will corrupt display values and contract-write amounts.Raw, formatted strings, and BigNumber under the same variable meaning. Convert deliberately and rename by representation.formatUnits or parseUnits. Wrong decimals make both UI and writes wrong.bigint with parseUnits.BigNumber for math and bigint for onchain raw values.Raw as bigint only.development
Use and structure Zustand stores for React and vanilla JS state management. Use when the user mentions Zustand, needs a store pattern, global state, persist state, or migrating from Redux/Context.
development
React performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React code to ensure optimal performance patterns. Triggers on tasks involving React components, data fetching, bundle optimization, or performance improvements.
development
Use when designing or refactoring functions with many optional params, configurable components, or when the user mentions optional params, function signatures, or API simplification. Reduces optional parameters in functions and components for cleaner APIs.
development
Implements data tables using @tanstack/react-table v8 with project UI primitives. Use when adding or modifying tables, column configs, sorting, filtering, row selection, or virtualized table bodies.