A Raycast-style natural language calculator. One function, one string input, structured JSON output.
Supports math expressions, unit conversions, time zones, date calculations, currency, and crypto — all from natural language.
npm install @supercmd/calculator
import { calculate } from '@supercmd/calculator'; // Math await calculate('3 + 43 + 23'); // { type: "math", result: 69, formatted: "69" } await calculate('sqrt(144)'); // { type: "math", result: 12, formatted: "12" } await calculate('2^10'); // { type: "math", result: 1024, formatted: "1,024" } await calculate('0xFF'); // { type: "math", result: 255, formatted: "255" } await calculate('5!'); // { type: "math", result: 120, formatted: "120" } // Unit Conversions await calculate('3 km to m'); // { type: "unit", result: 3000, formatted: "3,000 meter" } await calculate('100 fahrenheit to celsius'); // { type: "unit", result: 37.78, formatted: "37.78 celsius" } await calculate('5 kg to lb'); // { type: "unit", result: 11.02, formatted: "11.02 pound" } await calculate('1 gb to mb'); // { type: "unit", result: 1000, formatted: "1,000 megabyte" } // Time Zones await calculate('time in tokyo'); // { type: "time", formatted: "Mon, Mar 2, 2026, 05:46 AM JST" } await calculate('time in madison'); // { type: "time", formatted: "Sun, Mar 1, 2026, 02:46 PM CST" } await calculate('india to us time'); // { type: "time", formatted: "... IST → ... EST" } // Dates await calculate('tomorrow'); // { type: "date", formatted: "Tuesday, March 3, 2026 at 02:16 AM" } await calculate('next friday'); // { type: "date", formatted: "Friday, March 6, 2026 ..." } await calculate('3 days from now'); // { type: "date", formatted: "..." } await calculate('1741000000'); // { type: "date", formatted: "Monday, March 3, 2025 ..." } (unix timestamp) // Currency (works out of the box — free APIs with fallbacks) await calculate('usd to inr'); // { type: "currency", formatted: "₹91.08" } await calculate('100 usd to inr'); // { type: "currency", formatted: "₹9,108" } await calculate('500 jpy to usd'); // { type: "currency", formatted: "3ドル.21" } // Crypto (works out of the box — CoinGecko → Binance → CoinCap) await calculate('btc to usd'); // { type: "crypto", formatted: "65,295ドル" } await calculate('1 eth to usd'); // { type: "crypto", formatted: "1,914ドル.12" } await calculate('100 usd to btc'); // { type: "crypto", formatted: "0.00153 Bitcoin" } await calculate('1.5 eth to inr'); // { type: "crypto", formatted: "₹261,743" } await calculate('doge to inr'); // { type: "crypto", formatted: "₹8.28" }
Single entry point. Accepts any natural language string.
interface Config { rateProvider?: RateProvider; // Optional — built-in free providers used by default timezone?: string; // User's IANA timezone (default: system) locale?: string; // Locale for formatting (default: 'en-US') precision?: number; // Max significant digits (default: 10) }
// Success interface CalculateResult { type: 'math' | 'unit' | 'currency' | 'crypto' | 'time' | 'date'; input: string; result: number | string; formatted: string; metadata?: Record<string, unknown>; } // Failure interface ErrorResult { type: 'error'; input: string; error: string; }
Currency and crypto conversions work out of the box using built-in free API providers:
- Fiat: Frankfurter (ECB) → ExchangeRate API → Fawaz Ahmed Currency API
- Crypto: CoinGecko → Binance → CoinCap
Each has automatic fallback — if one API is down, the next is tried. No API keys needed.
You can override with a custom provider:
interface RateProvider { getFiatRate(base: string, target: string): Promise<number>; getCryptoRate(base: string, target: string): Promise<number>; }
const myProvider: RateProvider = { async getFiatRate(base, target) { const res = await fetch(`https://api.example.com/rates?from=${base}&to=${target}`); const data = await res.json(); return data.rate; }, async getCryptoRate(base, target) { const res = await fetch(`https://api.example.com/crypto?from=${base}&to=${target}`); const data = await res.json(); return data.rate; }, }; const result = await calculate('100 usd to eur', { rateProvider: myProvider });
- Arithmetic:
+,-,*,/,%(modulo) - Exponentiation:
^,** - Parentheses:
(3 + 4) * 2 - Functions:
sqrt,cbrt,abs,ceil,floor,round,log,log2,log10,ln,sin,cos,tan,asin,acos,atan,exp,sinh,cosh,tanh,pow,max,min - Constants:
pi,e,tau,phi,infinity - Factorial:
5! - Percentage:
50%→ 0.5 - Bitwise:
&,|,~,<<,>> - Base literals:
0xFF,0b1010,0o77 - Scientific notation:
1e10,2.5e-3
- Length: nm, mm, cm, m, km, in, ft, yd, mi, nmi, au, light year, parsec
- Mass: mg, g, kg, tonne, oz, lb, stone, carat, grain
- Volume: ml, l, tsp, tbsp, fl oz, cup, pint, quart, gallon, barrel
- Area: mm2, cm2, m2, km2, in2, ft2, yd2, mi2, acre, hectare
- Temperature: celsius, fahrenheit, kelvin
- Speed: m/s, km/h, mph, knots, mach
- Time: ns, ms, s, min, hr, day, week, month, year, decade, century
- Data: bit, byte, KB, MB, GB, TB, PB, KiB, MiB, GiB, TiB
- Pressure: Pa, kPa, bar, atm, psi, torr, mmHg
- Energy: J, kJ, cal, kcal, Wh, kWh, BTU, eV
- Power: W, kW, MW, GW, hp
- Angle: rad, deg, grad, arcmin, arcsec, revolution
- Frequency: Hz, kHz, MHz, GHz, THz, RPM
- Electric current: A, mA, kA, μA
- Voltage: V, mV, kV, μV
- Fuel economy: km/l, mpg
Full ISO 4217 coverage including USD, EUR, GBP, JPY, INR, CNY, BRL, and 140+ more.
Common names work: dollar, euro, pound, rupee, yuan, yen.
BTC, ETH, SOL, XRP, USDT, USDC, BNB, DOGE, ADA, MATIC, DOT, LTC, AVAX, LINK, UNI, ATOM, XLM, TON, SHIB, and more.
Names work: bitcoin, ethereum, solana, etc.
- Cities:
time in tokyo,time in new york,time in madison - Countries:
time in india,time in germany - Abbreviations:
time in pst,time in ist,time in jst - Conversions:
india to us time,utc to ist
- Relative:
today,tomorrow,yesterday - Named days:
next monday,last friday,this wednesday - Offsets:
3 days from now,2 weeks ago,in 5 months - Unix timestamps:
1741000000 - ISO parsing:
2025年03月03日 - To unix:
now to unix,today to timestamp - Date diff:
from 2025年01月01日 to 2025年12月31日
When input is ambiguous, the parser resolves in this order:
- Time — if input matches "time in X" or "X to Y time"
- Date — if input matches relative dates, timestamps, or date patterns
- Currency/Crypto — if both sides of "X to Y" resolve to currencies or crypto
- Unit — if both sides resolve to units in the same category
- Math — fallback for any arithmetic expression
| Feature | Offline | Needs Internet | Provider |
|---|---|---|---|
| Math | Yes | ||
| Units | Yes | ||
| Time zones | Yes | ||
| Dates | Yes | ||
| Fiat currency | Yes | Frankfurter → ExchangeRate → Fawaz Ahmed | |
| Crypto | Yes | CoinGecko → Binance → CoinCap |
- Empty input →
{ type: "error", error: "Empty input" } - Invalid math →
{ type: "error", error: "Unexpected character..." } - Unknown currency → falls through to math (likely error)
- All APIs down →
{ type: "error", error: "All providers failed" } - Division by zero →
{ type: "error", error: "Division by zero" } - Large numbers → handled via JavaScript's native number precision
- Ambiguous
m→ resolved as meter (length), not minute — useminfor minutes
MIT