nepali-tax-pro-max
v1.1.0
Published
नेपाली कर — Nepal IRD income tax, TDS, VAT, capital gains, SSF, CIT, PF, payroll, and corporate tax calculations. Fiscal-year-aware (FY 2081/82+), TypeScript-first, zero deps, ESM+CJS. For accountants, payroll software, fintech, and ERPs.
Maintainers
Readme
nepali-tax-pro-max
नेपाली कर — pro-max edition
The complete Nepal tax calculator. IRD income tax slabs (single/couple, SSF/disabled/pensioner/women), TDS by category, VAT 13%, capital gains, SSF (31%), PF, CIT, corporate tax, and full payroll pipelines — fiscal-year-versioned, TypeScript-first, zero dependencies.
📑 Table of Contents
- Highlights
- Install
- Quick Start
- Mental Model
- Income Tax
- TDS
- VAT
- Capital Gains
- SSF / PF / CIT
- Corporate Tax
- Full Payroll
- Vendor Bills
- Full API Reference
- Recipes
- Maintenance
✨ Highlights
- 🇳🇵 Built for Nepal — IRD slabs, NPR rupees, fiscal-year-aware (Shrawan–Ashad)
- 📅 Fiscal-year-versioned — pin to
"2081/82", never mutate historical rates - 👥 Full profile coverage — single/couple, SSF members, disabled, pensioner, women rebate, non-resident, remote-area
- 💼 15+ TDS categories — rent, royalty, dividend, interest, commission, lottery, …
- 💰 VAT calculator — 13%, exclusive/inclusive, threshold checker
- 📈 Capital gains — listed/unlisted shares, land/building, individual/entity, short/long-term
- 🏛️ SSF (31%) — full sub-allocation (medical, accident, dependent, retirement)
- 🧾 Vendor bill calculator — service + VAT + TDS pipeline in one call
- 💵 Full payroll — gross → SSF/PF → deductions → slabs → monthly net + monthly TDS
- 📦 Tree-shakeable — pure ESM exports,
sideEffects: false - 🎯 TypeScript-first — strict mode, exhaustive type exports, JSDoc on every function
- 🪶 Zero dependencies — works in Node, Deno, Bun, the browser, Workers
📦 Install
# npm
npm install nepali-tax-pro-max
# pnpm
pnpm add nepali-tax-pro-max
# yarn
yarn add nepali-tax-pro-max
# bun
bun add nepali-tax-pro-maxWorks with Node ≥ 14, modern browsers, Deno, Bun, Cloudflare Workers, Vercel Edge.
⚡ Quick Start
import {
calculateIncomeTax,
calculateTDS,
calculateVAT,
calculateBill,
calculatePayroll,
calculateCapitalGains,
calculateSSF,
calculatePF,
calculateCorporateTax,
} from "nepali-tax-pro-max";
// Income tax
calculateIncomeTax({ income: 1_000_000, status: "single" });
// { tax: 85000, taxableIncome: 1000000, effectiveRate: 0.085, ... }
// TDS — rent 10%
calculateTDS({ amount: 100_000, type: "rent" }).tds; // 10000
// VAT 13%
calculateVAT(1000).total; // 1130
calculateVAT(1130, { inclusive: true }).vat; // 130
// Vendor bill (service + VAT + TDS)
calculateBill({
serviceAmount: 100_000,
applyVAT: true,
tdsType: "service-vat-registered",
});
// { vat: 13000, tds: 1500, payableToVendor: 111500, ... }
// Capital gains — listed shares, individual, > 365 days = 5%
calculateCapitalGains({
gain: 100_000,
asset: "shares-listed",
ownerType: "individual",
holdingDays: 400,
}).tax; // 5000
// SSF 31% on basic
calculateSSF(50_000);
// { employee: 5500, employer: 10000, total: 15500, breakdown: {...} }
// Corporate tax — bank 30%
calculateCorporateTax({ profit: 10_000_000, category: "bank-financial" }).tax;
// 3000000
// Full payroll
calculatePayroll({
monthlyBasic: 50_000,
monthlyAllowances: 20_000,
festivalBonus: true,
profile: { status: "single", isSSFMember: true },
deductions: { lifeInsurance: 30_000 },
});
// { annualGross: 910000, annualTax: ..., monthlyNet: ..., ssfEmployee: ..., ... }🧠 Mental Model
| Rule | Why |
|---|---|
| Default fiscal year is 2081/82 (Shrawan 1, 2081 → Ashad 31, 2082). | Most current. Override via { fiscalYear: "2081/82" }. |
| All rate data is keyed by fiscal year in RATES_BY_FY. | Never mutate historical rates — add new files for new FYs. |
| Single vs couple slabs differ. | Couple gets a wider basic exemption (Rs 6 lakh vs 5 lakh). |
| SSF members skip the 1% SST. | Pass profile: { isSSFMember: true }. |
| Non-resident is flat 25% — no slabs. | Pass profile: { residency: "non-resident" }. |
| Salary TDS uses slabs; everything else is flat-rate per category. | calculateTDS rejects "salary" — use calculateSalaryTDS or calculatePayroll. |
| VAT is computed on service amount, TDS is computed on service amount. | TDS is not on the VAT (per IRD). |
| All amounts are NPR rupees (number); paisa precision via half-up rounding. | If you need BigInt-precise paisa, use nepali-numbers-pro-max for the math. |
💼 Income Tax
import { calculateIncomeTax, getSlabs, getEffectiveRate, getMarginalRate } from "nepali-tax-pro-max";
calculateIncomeTax({ income: 1_000_000, status: "single" });
// {
// fiscalYear: "2081/82",
// grossIncome: 1000000,
// taxableIncome: 1000000,
// tax: 85000,
// effectiveRate: 0.085,
// perBracket: [
// { bracket: { from: 0, to: 500000, rate: 0.01 }, amountInBracket: 500000, tax: 5000 },
// { bracket: { from: 500000, to: 700000, rate: 0.10 }, amountInBracket: 200000, tax: 20000 },
// { bracket: { from: 700000, to: 1000000, rate: 0.20 }, amountInBracket: 300000, tax: 60000 },
// ],
// notes: [],
// }
// Profile flags
calculateIncomeTax({
income: 1_000_000,
profile: { isSSFMember: true, isWomanRebate: true, remoteArea: "A" },
});
// Helpers
getSlabs("single"); // FY 2081/82 single slabs
getEffectiveRate(1_000_000); // 0.085
getMarginalRate(800_000); // 0.20FY 2081/82 slabs
| Bracket | Single (Rs) | Couple (Rs) | Rate | |---|---|---|---| | 1 (SST) | 0 – 5,00,000 | 0 – 6,00,000 | 1% (0% if SSF) | | 2 | 5,00,001 – 7,00,000 | 6,00,001 – 8,00,000 | 10% | | 3 | 7,00,001 – 10,00,000 | 8,00,001 – 11,00,000 | 20% | | 4 | 10,00,001 – 20,00,000 | 11,00,001 – 20,00,000 | 30% | | 5 | 20,00,001 – 50,00,000 | 20,00,001 – 50,00,000 | 36% | | 6 | Above 50,00,000 | Above 50,00,000 | 39% |
Profile modifiers
| Flag | Effect |
|---|---|
| isSSFMember: true | First slab is 0% (no 1% SST), retirement deduction cap rises to Rs 5 lakh |
| isDisabled: true | Basic exemption widens by 50% (e.g. Rs 5L → Rs 7.5L for single) |
| isPensioner: true | Basic exemption widens by 25% |
| isWomanRebate: true | 10% rebate on tax (employment income, single only) |
| residency: "non-resident" | Flat 25% on Nepal-source income, no slabs |
| remoteArea: "A" to "E" | Additional Rs 50k → Rs 10k deduction |
🧾 TDS
import { calculateTDS, calculateSalaryTDS, getTDSRate } from "nepali-tax-pro-max";
calculateTDS({ amount: 100_000, type: "rent" });
// { tds: 10000, rate: 0.10, netToVendor: 90000, ... }
calculateTDS({ amount: 50_000, type: "service-vat-registered" }).tds; // 750 (1.5%)
calculateTDS({ amount: 50_000, type: "service-non-vat" }).tds; // 7500 (15%)
calculateTDS({ amount: 100_000, type: "lottery" }).tds; // 25000
calculateSalaryTDS({ annualIncome: 1_000_000 });
// { annualTax: 85000, monthlyTds: 7083.33, fiscalYear: "2081/82" }
getTDSRate("commission"); // 0.15TDS categories (FY 2081/82)
| Category | Rate |
|---|---|
| rent | 10% |
| rent-vehicle | 1.5% |
| service-vat-registered | 1.5% |
| service-non-vat | 15% |
| service-non-resident | 15% |
| royalty | 15% |
| dividend-resident / dividend-non-resident | 5% |
| interest-bank-individual | 5% |
| interest-other | 15% |
| commission | 15% |
| lottery | 25% |
| meeting-allowance | 15% |
| aircraft-lease | 10% |
| reinsurance-non-resident | 1.5% |
| consumer-committee | 1.5% |
| exam-fee | 15% |
💰 VAT
import { calculateVAT, extractVAT, addVAT, isAboveVATThreshold } from "nepali-tax-pro-max";
calculateVAT(1000); // { base: 1000, vat: 130, total: 1130, inclusive: false }
calculateVAT(1130, { inclusive: true }); // { base: 1000, vat: 130, total: 1130, inclusive: true }
extractVAT(1130); // 130
addVAT(1000); // 130
isAboveVATThreshold(60_00_000, "goods"); // true (above Rs 50 lakh)
isAboveVATThreshold(40_00_000, "service"); // true (above Rs 30 lakh)VAT rate: 13%. Thresholds: Rs 50 lakh goods / Rs 30 lakh services (FY 2081/82).
📈 Capital Gains
import { calculateCapitalGains } from "nepali-tax-pro-max";
// Listed shares, individual, > 365 days = 5%
calculateCapitalGains({
gain: 100_000,
asset: "shares-listed",
ownerType: "individual",
holdingDays: 400,
});
// { rate: 0.05, tax: 5000, netProceeds: 95000, ... }
// Land, individual, ≥ 5 years = 5%
calculateCapitalGains({
gain: 1_000_000,
asset: "land",
ownerType: "individual",
holdingDays: 10 * 365,
}).tax; // 50000| Asset | Rate | |---|---| | Listed shares — individual, < 365 days | 7.5% | | Listed shares — individual, ≥ 365 days | 5% | | Listed shares — entity | 10% | | Unlisted shares — individual | 10% | | Unlisted shares — entity | 15% | | Land/building — individual, < 5 years | 7.5% | | Land/building — individual, ≥ 5 years | 5% | | Land/building — entity | 1.5% (advance) |
🏛️ SSF / PF / CIT
import { calculateSSF, calculatePF, calculateCIT } from "nepali-tax-pro-max";
calculateSSF(50_000);
// {
// basicSalary: 50000,
// employee: 5500,
// employer: 10000,
// total: 15500,
// breakdown: { medical: 1610, accident: 700, dependent: 135, retirement: 13055 },
// }
calculatePF(50_000);
// { employee: 5000, employer: 5000, total: 10000 }
calculatePF(50_000, { employeeRate: 0.15 }); // custom
calculateCIT(500_000);
// { contribution: 500000, cappedContribution: 300000, cap: 300000, excess: 200000, ... }
calculateCIT(600_000, { isSSFMember: true });
// SSF cap is 500k
// { cappedContribution: 500000, cap: 500000, ... }| Scheme | Employee | Employer | Notes | |---|---|---|---| | SSF | 11% | 20% | Total 31% on basic. SSF members skip 1% SST. | | PF | 10% | 10% | Standard provident fund. | | CIT | voluntary | — | Capped at Rs 3 lakh (or Rs 5 lakh for SSF members). |
🏢 Corporate Tax
import { calculateCorporateTax, getCorporateRate } from "nepali-tax-pro-max";
calculateCorporateTax({ profit: 10_000_000, category: "standard" }).tax; // 2,500,000
calculateCorporateTax({ profit: 10_000_000, category: "bank-financial" }).tax; // 3,000,000
calculateCorporateTax({ profit: 10_000_000, category: "special-industry" }).tax; // 2,000,000
getCorporateRate("export"); // 0.20| Category | Rate |
|---|---|
| standard | 25% |
| bank-financial / insurance / telecom / petroleum / capital-market / tobacco-alcohol | 30% |
| special-industry (manufacturing) / export | 20% |
💵 Full Payroll
import { calculatePayroll } from "nepali-tax-pro-max";
calculatePayroll({
monthlyBasic: 50_000,
monthlyAllowances: 20_000,
festivalBonus: true, // adds 1 month gross as Dashain bonus
profile: { status: "single", isSSFMember: true },
deductions: { lifeInsurance: 30_000 },
retirementScheme: "ssf", // "ssf" | "pf" | "none"
});
// {
// fiscalYear: "2081/82",
// annualGross: 910000, // 13 × 70000
// ssfEmployee: 71500, // 11% × 650000 (basic only)
// ssfEmployer: 130000, // 20% × 650000
// annualDeductions: ...,
// taxableIncome: ...,
// annualTax: ...,
// monthlyTds: ...,
// annualNet: ...,
// monthlyNet: ...,
// notes: [...],
// }Pipeline:
- Annualize — 12 × monthly + festival bonus
- SSF or PF on basic
- Cap deductions (life insurance ≤ 40k, health ≤ 20k, donation ≤ 5% of income or 100k, retirement ≤ 300k or 500k for SSF)
- Apply slabs to taxable income
- Apply rebates (women, etc.)
- Annual net = gross − employee retirement − tax
- Monthly TDS = annualTax / 12
🧾 Vendor Bills (VAT + TDS)
import { calculateBill } from "nepali-tax-pro-max";
calculateBill({
serviceAmount: 100_000,
applyVAT: true,
tdsType: "service-vat-registered",
});
// {
// serviceAmount: 100000,
// vat: 13000,
// tds: 1500, // 1.5% of service amount (NOT VAT)
// grossInvoice: 113000, // service + VAT
// payableToVendor: 111500, // gross − TDS
// payableToGovtVAT: 13000,
// payableToGovtTDS: 1500,
// }
// Rent — no VAT, just TDS
calculateBill({ serviceAmount: 100_000, tdsType: "rent" });
// { tds: 10000, payableToVendor: 90000, ... }🧰 Full API Reference
| Function | Description |
|---|---|
| calculateIncomeTax(opts) | Full slab calculation with profile + deductions. |
| applySlabs(taxable, slabs) | Pure: apply a slab table to a value. |
| getSlabs(status?, fy?) | Slab table for a status & FY. |
| getEffectiveRate(income, status?, fy?) | Effective tax rate (tax / income). |
| getMarginalRate(income, status?, fy?) | Marginal rate at a given income. |
| Function | Description |
|---|---|
| calculateTDS({ amount, type, fy? }) | TDS by category (returns { tds, rate, netToVendor }). |
| calculateSalaryTDS({ annualIncome, status?, profile?, deductions?, fy? }) | Slab-based annual + monthly TDS. |
| getTDSRate(type, fy?) | Lookup rate. |
| totalDeductions(d, fy?, isSSFMember?, taxableForDonation?) | Sum capped deductions. |
| Function | Description |
|---|---|
| calculateVAT(amount, opts?) | Base/vat/total breakdown. |
| extractVAT(totalInclusive, fy?) | VAT amount from inclusive total. |
| addVAT(base, fy?) | VAT amount on top of exclusive base. |
| getVATRate(fy?) | Standard rate (default 13%). |
| getVATThreshold("goods" \| "service", fy?) | Registration threshold. |
| isAboveVATThreshold(turnover, type, fy?) | True if turnover triggers registration. |
| Function | Description |
|---|---|
| calculateCapitalGains({ gain, asset, ownerType, holdingDays?, fy? }) | High-level — picks the right canonical key. |
| getCapitalGainsRate(canonicalKey, fy?) | Direct lookup. |
asset: "shares-listed" \| "shares-unlisted" \| "land". ownerType: "individual" \| "entity".
| Function | Description |
|---|---|
| calculateSSF(basic, opts?) | 11%/20% with 4-way breakdown. |
| calculatePF(basic, opts?) | 10%/10% (rates configurable). |
| calculateCIT(contribution, opts?) | Capped + excess. |
| Function | Description |
|---|---|
| calculateCorporateTax({ profit, category, fy? }) | Single-rate per category. |
| getCorporateRate(category, fy?) | Lookup. |
| Function | Description |
|---|---|
| calculatePayroll(opts) | Full pipeline (gross → net). |
| calculateBill({ serviceAmount, applyVAT?, tdsType?, fy? }) | Service + VAT + TDS breakdown. |
| Function / Constant | Description |
|---|---|
| getRates(fy?) | Full RatesSnapshot for a FY. |
| getSupportedFiscalYears() | List of FYs in the registry. |
| RATES_BY_FY | Map of FY → snapshot. |
| RATES_FY_2081_82 | Snapshot for current FY. |
| DEFAULT_FISCAL_YEAR | "2081/82". |
🎯 Recipes
Salary slip (employee view)
import { calculatePayroll, formatNPR } from "nepali-tax-pro-max";
// (formatNPR from nepali-numbers-pro-max if you also use that — totally optional)
const slip = calculatePayroll({
monthlyBasic: 80_000,
monthlyAllowances: 30_000,
festivalBonus: true,
profile: { status: "single", isSSFMember: true },
deductions: { lifeInsurance: 25_000, healthInsurance: 15_000 },
});
console.log(`Annual gross: Rs ${slip.annualGross.toLocaleString()}`);
console.log(`Monthly TDS: Rs ${slip.monthlyTds.toLocaleString()}`);
console.log(`Monthly net: Rs ${slip.monthlyNet.toLocaleString()}`);Quarterly tax estimate
import { calculateIncomeTax } from "nepali-tax-pro-max";
const annual = calculateIncomeTax({ income: 1_500_000, status: "couple" });
const quarterly = annual.tax / 4;
console.log(`Quarterly advance: Rs ${quarterly}`);Vendor bill workflow
import { calculateBill } from "nepali-tax-pro-max";
const bill = calculateBill({
serviceAmount: 250_000,
applyVAT: true,
tdsType: "service-vat-registered",
});
// Pay the vendor:
console.log(`Cheque to vendor: Rs ${bill.payableToVendor}`);
// Deposit to IRD:
console.log(`VAT to IRD: Rs ${bill.payableToGovtVAT}`);
console.log(`TDS to IRD: Rs ${bill.payableToGovtTDS}`);Compare SSF vs PF for an employee
import { calculatePayroll } from "nepali-tax-pro-max";
const opts = { monthlyBasic: 50_000, monthlyAllowances: 0 };
const ssfRun = calculatePayroll({
...opts,
profile: { status: "single", isSSFMember: true },
});
const pfRun = calculatePayroll({
...opts,
profile: { status: "single" },
});
console.log(`SSF take-home: Rs ${ssfRun.monthlyNet}`);
console.log(`PF take-home: Rs ${pfRun.monthlyNet}`);Capital gains on a stock sale
import { calculateCapitalGains } from "nepali-tax-pro-max";
const result = calculateCapitalGains({
gain: 250_000,
asset: "shares-listed",
ownerType: "individual",
holdingDays: 300, // short-term
});
console.log(`Tax on gain: Rs ${result.tax}`); // 18,750 (7.5%)🔧 Maintenance / Annual Updates
Every Nepali fiscal year (Jestha 15 budget speech) brings new rates. Updating:
- Copy
src/data/fy-2081-82.tstosrc/data/fy-NEW.ts. - Update rates per the new Finance Act.
- Add the new entry to
RATES_BY_FYinsrc/data/index.ts. - Bump
DEFAULT_FISCAL_YEARto the new FY. - Add a regression test:
calculateIncomeTax({ income, fiscalYear: "OLD" })should still return the old result. - Bump minor version, ship.
Never mutate a published FY file — historical accuracy matters for past tax filings.
Verification sources
- 🏛️ IRD (ird.gov.np) — Finance Act PDFs, TDS booklet
- 💰 Ministry of Finance (mof.gov.np) — Budget Speech
- 🏛️ SSF (ssf.gov.np) — Contribution schedule
- 📊 ICAN (ican.org.np) — Tax bulletin
- 📕 Nepal Law Commission — Income Tax Act 2058 consolidated
Cross-check via PwC Nepal Tax Facts, KPMG Nepal Tax Card, and Deloitte Nepal Highlights annual PDFs.
⚠️ Disclaimer
This package implements tax math per published rate tables. It is not legal or financial advice. For binding tax filings, consult a licensed Nepali Chartered Accountant (CA). Authors and contributors disclaim liability for any reliance on these calculations.
🤝 Contributing
PRs welcome. Specifically wanted:
- Verified rate tables for older fiscal years (2079/80, 2080/81, …)
- Edge-case test coverage
- Special-industry tax rates / rebates / incentives
npm install
npm test
npm run typecheck
npm run build📜 License
MIT © 2026 l3lackcurtains
Made with ❤️ for the Nepali developer community.
बनाइएको नेपाली डेभलपर समुदायको लागि।
