GST Calculator

pub package

A lightweight, dependency-free Dart package for Indian GST (Goods and Services Tax) calculations. Works in Flutter apps and pure Dart (server, CLI) on every platform, including the web.

  • Add GST to a GST-exclusive price
  • Remove GST from a GST-inclusive price
  • Split tax into CGST + SGST (intra-state) or IGST (inter-state)
  • Optional rounding to paise that keeps invoice lines consistent
  • Clear ArgumentErrors for invalid input

Installation

dart pub add gst_calculator

or add it to pubspec.yaml:

dependencies:
  gst_calculator: ^0.0.2

Usage

import 'package:gst_calculator/gst_calculator.dart';

Add GST (price excludes GST)

final result = GstCalculator.addGST(amount: 1000, gstRate: 18);

print(result.cgst);      // 90.0
print(result.sgst);      // 90.0
print(result.gstAmount); // 180.0
print(result.total);     // 1180.0

Remove GST (price includes GST)

final result = GstCalculator.removeGST(amount: 1180, gstRate: 18);

print(result.baseAmount); // 1000.0
print(result.cgst);       // 90.0
print(result.total);      // 1180.0 (always the amount you passed in)

Inter-state supply (IGST)

final result = GstCalculator.addGST(
  amount: 1000,
  gstRate: 18,
  isInterState: true,
);

print(result.igst); // 180.0
print(result.cgst); // 0.0

Rounding for invoices

By default results are unrounded doubles, so they can contain floating point noise (0.1 at 18% gives a total of 0.11800000000000001) or fractions of a paisa. Pass fractionDigits to get values ready for an invoice:

final result = GstCalculator.addGST(
  amount: 99.99,
  gstRate: 5,
  fractionDigits: 2,
);

print(result.cgst);  // 2.5   (exact value 2.49975)
print(result.sgst);  // 2.5
print(result.total); // 104.99

With fractionDigits:

  • The input amount is rounded first.
  • CGST and SGST are each rounded separately, so they are always equal. IGST is rounded once.
  • addGST keeps the base amount and adds the rounded tax to get the total. removeGST keeps the total and subtracts the rounded tax to get the base.
  • baseAmount + gstAmount == total holds exactly at the chosen precision.
  • Rounding is half away from zero, and is not thrown off by binary representation (1.005 rounds to 1.01).

fractionDigits must be between 0 and GstCalculator.maxFractionDigits (6). Use 0 to round to whole rupees. To display a value, format it yourself, for example result.total.toStringAsFixed(2).

Result

GstResult has:

Property Meaning
baseAmount Taxable value, before GST
gstRate Rate used, as a percentage
cgst Central GST (intra-state only, else 0)
sgst State / UT GST (intra-state only, else 0)
igst Integrated GST (inter-state only, else 0)
gstAmount Total tax: cgst + sgst + igst
total Amount including GST

It also supports value equality (==) and a readable toString().

Error handling

Invalid input throws an ArgumentError rather than returning NaN or Infinity:

try {
  GstCalculator.addGST(amount: 100, gstRate: -5);
} on ArgumentError catch (e) {
  print(e.message); // Must be a finite, non-negative percentage
}
Input Result
amount is NaN or infinite ArgumentError
gstRate is negative, NaN or infinite ArgumentError
fractionDigits outside 0..6 RangeError
Amount too large to round exactly (fractionDigits set; above ~₹6 × 10¹³ at 2 digits) ArgumentError
Negative amount (credit notes, refunds) Allowed; tax values are negative
gstRate of 0 Allowed; no tax

Notes and limitations

  • The rate is not validated against official GST slabs, because slabs change. Pass whatever rate applies to your supply.
  • In Union Territories without a legislature, the state component is UTGST. It is calculated the same way; read it from sgst.
  • Compensation cess and TDS/TCS are not calculated.
  • Calculations use double. For totals across very many line items, sum the rounded values in integer paise (for example (result.total * 100).round()) to avoid accumulating error.
  • This package does arithmetic only and is not tax advice.

Compatibility

  • Dart SDK 2.17 or later (Flutter 3.0 or later).
  • No dependencies.
  • All calculations are pure, synchronous functions with no shared state, so they are safe to call from any isolate or widget build method.

Upgrading from 0.0.1

Existing code keeps working and returns the same values for valid input. Two things changed:

  • Invalid input (NaN or infinite amounts, negative or non-finite rates) now throws an ArgumentError. Before, it silently returned NaN/Infinity.
  • The version constraint ^0.0.1 does not allow 0.0.2, so update it to ^0.0.2.

Libraries

gst_calculator
Indian GST (Goods and Services Tax) calculations.