XGitHub

Numora - Numeric Input Library

numora is a zero-dependency TypeScript library that turns any <input> element into a precision numeric input. Unlike <input type="number">, numora uses type="text" under the hood so you control exactly what the user can type, paste, and see.

Why numora?

If you audit the codebases of the top 10 DeFi protocols - Uniswap, Aave, Curve, Balancer - you'll notice a pattern. For the most critical UI component in finance, the numeric input, every single one has built a custom implementation from scratch.

  • Uniswap maintains ~200 lines of custom regex and locale logic.
  • Aave wraps a formatting library with heavy custom validation.
  • Curve relies on a complex chain of hooks to handle state.

There is no standard. Every team wastes days reinventing the wheel: comma/dot separator logic, parseFloat precision loss, mobile keyboard ghost characters.

numora is the new standard for numeric inputs - a precision-first library you drop in once, configure with options, and forget about.

What you get

  • Zero dependencies - no moment, no lodash, no formatting library
  • 6.4 kb gzipped - negligible bundle cost
  • String-only values - never converts to Number, so no IEEE 754 rounding errors on amounts like 0.1 + 0.2
  • Full cursor preservation - editing in the middle of a formatted number keeps the caret in place after reformatting
  • Thousand separator formatting - Standard, Indian Lakh, and East Asian Wan grouping styles
  • Paste sanitization - strips non-numeric characters, expands compact notation (1k → 1000) and scientific notation (1.5e-7 → 0.00000015)
  • Framework-agnostic - works with React, Vue, Svelte, Angular, or plain HTML

Vanilla JS API

The core package exports a NumoraInput class. Instantiate it with a container element and an optional FormattingOptions object. The class attaches all event listeners and manages internal state - no build step, no JSX, no reactivity system required.

import { NumoraInput } from 'numora'

const container = document.querySelector('#amount-input')

const input = new NumoraInput(container, {
  maxDecimals: 2,
  thousandSeparator: ',',
  decimalSeparator: '.',
  enableNegative: false,
})

container.addEventListener('change', (e) => {
  console.log(e.target.value) // raw string, e.g. "1234.56"
})

The NumoraInput class is the same engine used by the numora-react component. Both share the formatting pipeline, sanitization logic, and options interface.


Use Numora in your framework

Numora is a precision-first numeric input library that works in every modern JavaScript framework. The core NumoraInput class is vanilla TypeScript and ships with thin, idiomatic adapters for each ecosystem – no separate wrapper packages needed.

  • Svelte numeric input – a 10-line use:numora action for Svelte 5 and SvelteKit (SSR-safe).
  • Vue numeric input – a Vue 3 composable bound to a template ref, or a v-numora directive (works with Nuxt 3, VeeValidate, FormKit, Pinia).
  • Angular numeric input – a standalone directive that composes with ControlValueAccessor and FormControl<string> for Reactive Forms.
  • SolidJS numeric input – a tiny onMount wrapper that writes the raw value into a createSignal (works with SolidStart).
  • React numeric input – the numora-react package gives you a drop-in <NumoraInput /> component with full TypeScript support and React Hook Form integration.

Next Steps

Follow the Installation guide to add numora to your project, or read Anatomy to understand the beforeinput-based architecture.