india-tax-utils
v1.0.0
Published
Production-ready GST utility library for Indian developers — GSTIN validation, tax calculation, and invoice generation
Downloads
201
Readme
india-tax-utils
Production-ready GST utility library for Indian developers.
A clean, modular, zero-dependency utility library for solving GST-related problems in Node.js applications. Covers GSTIN validation (with real checksum verification), GST tax calculation (CGST/SGST/IGST), and invoice generation.
Table of Contents
Installation
npm install india-tax-utilsRequirements: Node.js ≥ 14.0.0 · No runtime dependencies.
Quick Start
const {
validateGSTIN,
calculateGST,
generateInvoice,
} = require('india-tax-utils');
// 1. Validate a GSTIN
console.log(validateGSTIN('27AAPFU0939F1ZV')); // true
// 2. Calculate GST
const tax = calculateGST({ amount: 1000, fromState: '27', toState: '07', rate: 18 });
console.log(tax);
// { baseAmount: 1000, cgst: 0, sgst: 0, igst: 180, totalTax: 180, totalAmount: 1180, ... }
// 3. Generate an invoice
const invoice = generateInvoice({
seller: { name: 'Acme Pvt Ltd', gstin: '27AAPFU0939F1ZV', state: '27' },
buyer: { name: 'Buyer Co', gstin: '29AAPFU0939F1ZR', state: '29' },
items: [{ name: 'Laptop', price: 50000, quantity: 1, taxRate: 18 }],
});
console.log(invoice.summary);
// { subtotal: 50000, totalCGST: 0, totalSGST: 0, totalIGST: 9000, grandTotal: 59000, ... }API Reference
GSTIN Validation
validateGSTIN(gstin: string): boolean
Validates a GSTIN string against all official rules:
| Position | Rule |
|---|---|
| 1–2 | Valid state code (01–37, 97, 99) |
| 3–7 | 5 uppercase letters (PAN) |
| 8–11 | 4 digits (PAN) |
| 12 | 1 uppercase letter (PAN) |
| 13 | Entity number: 1–9 or A–Z |
| 14 | Must be Z |
| 15 | Checksum (computed via mod-36 algorithm) |
Input is normalised (trimmed, uppercased) before validation — so '27aapfu0939f1zv' is treated the same as '27AAPFU0939F1ZV'.
const { validateGSTIN } = require('india-tax-utils');
validateGSTIN('27AAPFU0939F1ZV'); // true
validateGSTIN('27AAPFU0939F1ZZ'); // false — bad checksum
validateGSTIN('99AAPFU0939F1ZV'); // false — invalid state code
validateGSTIN('27AAPFU0939F1Z'); // false — too short (14 chars)
validateGSTIN(null); // false — non-string inputvalidateGSTINDetailed(gstin: string): GSTINValidationResult
Returns a detailed result object with an error message on failure and extracted metadata on success.
const { validateGSTINDetailed } = require('india-tax-utils');
validateGSTINDetailed('27AAPFU0939F1ZV');
// {
// valid: true,
// stateCode: '27',
// stateName: 'Maharashtra',
// pan: 'AAPFU0939F',
// entityNumber: '1'
// }
validateGSTINDetailed('27AAPFU0939F1ZZ');
// {
// valid: false,
// error: 'Checksum mismatch. Expected "V", got "Z".'
// }
validateGSTINDetailed('00AAPFU0939F1ZV');
// {
// valid: false,
// error: 'Invalid state code "00". Must be a valid Indian state/UT code.'
// }getStateFromGSTIN(gstin: string): string | null
Extracts the state name from a valid GSTIN. Returns null for invalid GSTINs.
const { getStateFromGSTIN } = require('india-tax-utils');
getStateFromGSTIN('27AAPFU0939F1ZV'); // 'Maharashtra'
getStateFromGSTIN('07AAGCM2868D1ZG'); // 'Delhi'
getStateFromGSTIN('INVALIDGSTIN123'); // nullSTATE_CODES: Record<string, string>
Map of all valid Indian state codes to their state names.
const { STATE_CODES } = require('india-tax-utils');
STATE_CODES['27']; // 'Maharashtra'
STATE_CODES['07']; // 'Delhi'
STATE_CODES['33']; // 'Tamil Nadu'GST Calculator
calculateGST({ amount, fromState, toState, rate }): GSTCalculationResult
Calculates GST components for a transaction.
Rules:
- Intra-state (
fromState === toState): tax is split equally into CGST + SGST. - Inter-state (
fromState !== toState): entire tax is applied as IGST.
fromState and toState can be state codes ('27') or state names ('Maharashtra') — comparison is case-insensitive.
const { calculateGST } = require('india-tax-utils');
// Intra-state: Maharashtra → Maharashtra
calculateGST({ amount: 1000, fromState: '27', toState: '27', rate: 18 });
// {
// baseAmount: 1000,
// cgst: 90,
// sgst: 90,
// igst: 0,
// totalTax: 180,
// totalAmount: 1180,
// transactionType: 'intra-state',
// rate: 18
// }
// Inter-state: Maharashtra → Delhi
calculateGST({ amount: 1000, fromState: '27', toState: '07', rate: 18 });
// {
// baseAmount: 1000,
// cgst: 0,
// sgst: 0,
// igst: 180,
// totalTax: 180,
// totalAmount: 1180,
// transactionType: 'inter-state',
// rate: 18
// }
// Zero-rated
calculateGST({ amount: 1000, fromState: '27', toState: '27', rate: 0 });
// { baseAmount: 1000, cgst: 0, sgst: 0, igst: 0, totalTax: 0, totalAmount: 1000, ... }Throws Error on invalid input (negative amount, missing fields, non-numeric values).
calculateGSTReverse({ totalAmount, fromState, toState, rate }): GSTCalculationResult
Reverse-calculates GST from an amount that already includes tax.
const { calculateGSTReverse } = require('india-tax-utils');
// ₹1180 is the GST-inclusive price — extract the base and tax
calculateGSTReverse({ totalAmount: 1180, fromState: '27', toState: '27', rate: 18 });
// {
// baseAmount: 1000,
// cgst: 90,
// sgst: 90,
// igst: 0,
// totalTax: 180,
// totalAmount: 1180,
// ...
// }isValidGSTRate(rate: number): boolean
Checks whether a rate is a standard Indian GST slab.
const { isValidGSTRate } = require('india-tax-utils');
isValidGSTRate(18); // true
isValidGSTRate(28); // true
isValidGSTRate(15); // false — not a standard slab
isValidGSTRate(0); // true — zero-ratedStandard slabs: 0, 0.1, 0.25, 1, 1.5, 3, 5, 7.5, 12, 18, 28.
Invoice Generator
generateInvoice(data): Invoice
Generates a complete, GST-compliant invoice object with per-item tax breakdowns and grand totals.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
| seller | Party | ✅ | Seller details |
| buyer | Party | ✅ | Buyer details |
| items | InvoiceItem[] | ✅ | Line items (at least 1) |
| invoiceNumber | string | — | Auto-generated if omitted |
| invoiceDate | string \| Date | — | Defaults to today |
| currency | string | — | Defaults to 'INR' |
| notes | string | — | Payment terms, notes, etc. |
Party object:
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Business name |
| gstin | string | ✅ | Validated GSTIN |
| state | string | ✅ | State code or name |
| address | string | — | Full address |
InvoiceItem object:
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Product/service name |
| price | number | ✅ | Unit price (ex-tax) |
| quantity | number | ✅ | Quantity |
| taxRate | number | ✅ | GST rate % (e.g. 18) |
| hsn | string | — | HSN/SAC code |
| unit | string | — | Unit of measure (e.g. 'pcs') |
const { generateInvoice } = require('india-tax-utils');
const invoice = generateInvoice({
seller: {
name: 'Acme Technologies Pvt Ltd',
gstin: '27AAPFU0939F1ZV',
state: '27',
address: '404, Tech Park, Pune – 411014',
},
buyer: {
name: 'SouthTech Solutions',
gstin: '29AAPFU0939F1ZR',
state: '29',
},
items: [
{ name: 'Laptop', price: 50000, quantity: 2, taxRate: 18, hsn: '8471', unit: 'pcs' },
{ name: 'Mouse', price: 500, quantity: 5, taxRate: 18, hsn: '8471', unit: 'pcs' },
{ name: 'Desk Chair', price: 8000, quantity: 1, taxRate: 12, hsn: '9401', unit: 'pcs' },
],
notes: 'Payment due within 30 days. Bank transfer preferred.',
});Output (abridged):
{
invoiceNumber: 'INV-20240315-A4F2',
invoiceDate: '2024-03-15',
currency: 'INR',
transactionType: 'inter-state', // Maharashtra → Karnataka
seller: { name: 'Acme Technologies Pvt Ltd', gstin: '27AAPFU0939F1ZV', state: '27', address: '...' },
buyer: { name: 'SouthTech Solutions', gstin: '29AAPFU0939F1ZR', state: '29' },
items: [
{
srNo: 1, name: 'Laptop', hsn: '8471', unit: 'pcs',
price: 50000, quantity: 2, lineTotal: 100000,
taxRate: 18, cgst: 0, sgst: 0, igst: 18000,
taxAmount: 18000, lineGrandTotal: 118000,
},
{
srNo: 2, name: 'Mouse', hsn: '8471', unit: 'pcs',
price: 500, quantity: 5, lineTotal: 2500,
taxRate: 18, cgst: 0, sgst: 0, igst: 450,
taxAmount: 450, lineGrandTotal: 2950,
},
{
srNo: 3, name: 'Desk Chair', hsn: '9401', unit: 'pcs',
price: 8000, quantity: 1, lineTotal: 8000,
taxRate: 12, cgst: 0, sgst: 0, igst: 960,
taxAmount: 960, lineGrandTotal: 8960,
},
],
summary: {
subtotal: 110500,
totalCGST: 0,
totalSGST: 0,
totalIGST: 19410,
totalTax: 19410,
grandTotal: 129910,
roundOff: 0,
grandTotalRounded: 129910,
},
notes: 'Payment due within 30 days. Bank transfer preferred.',
}Throws Error with a clear message if:
- Seller or buyer GSTIN fails validation
- Any required field is missing
- Item price is negative, or quantity is zero/negative
generateInvoiceNumber(): string
Generates a unique invoice number. Format: INV-YYYYMMDD-XXXX.
const { generateInvoiceNumber } = require('india-tax-utils');
generateInvoiceNumber(); // 'INV-20240315-A4F2'
generateInvoiceNumber(); // 'INV-20240315-X9QR'TypeScript
Full TypeScript declarations are bundled at src/index.d.ts. No @types package needed.
import {
validateGSTIN,
validateGSTINDetailed,
calculateGST,
generateInvoice,
GSTINValidationResult,
GSTCalculationResult,
Invoice,
GenerateInvoiceInput,
} from 'india-tax-utils';
const result: GSTINValidationResult = validateGSTINDetailed('27AAPFU0939F1ZV');
const tax: GSTCalculationResult = calculateGST({ amount: 1000, fromState: '27', toState: '07', rate: 18 });Testing
# Run all tests
npm test
# Run with coverage report
npm test -- --coverage
# Watch mode
npm run test:watchThe test suite covers 93 test cases across 3 suites:
| Suite | Tests | Coverage |
|---|---|---|
| gstin.test.js | 28 | GSTIN format, state codes, checksum, edge cases |
| tax.test.js | 37 | Intra/inter-state, rounding, reverse calc, error handling |
| invoice.test.js | 28 | Single/multi-item, metadata, input validation |
GST Rate Reference
Standard Indian GST slabs:
| Rate | Common goods/services | |---|---| | 0% | Essential food, books, newspapers | | 0.1% | Cut & polished diamonds | | 0.25% | Rough diamonds | | 1% | Affordable housing | | 1.5% | Cut & polished semi-precious stones | | 3% | Gold, silver, jewellery | | 5% | Packaged food, transport, small restaurants | | 7.5% | Aircraft parts | | 12% | Business class air travel, processed food | | 18% | Electronics, IT services, most manufactured goods | | 28% | Luxury goods, tobacco, aerated drinks, automobiles |
License
MIT © india-tax-utils contributors
