wtax-engine
v1.0.0
Published
Lithuanian Individual Activity tax estimation engine for WTax SaaS platform
Maintainers
Readme
wtax-engine
Lithuanian Individual Activity (Individuali veikla) tax estimation engine for WTax.
Answers the one question every self-employed Lithuanian needs:
"How much money can I safely spend right now after taxes?"
⚠️ DISCLAIMER: All calculations are estimates only and do not constitute legal, financial, or professional tax advice. Lithuanian tax law changes frequently. Always consult a certified accountant or VMI (State Tax Inspectorate) before filing your tax return.
Features
- ✅ GPM calculation with progressive brackets (15% / 20%)
- ✅ VSD calculation with minimum floor and ceiling cap
- ✅ PSD (health insurance) with student exemption
- ✅ NPD (non-taxable personal allowance) phase-out
- ✅ Three deduction methods:
flat30,actual,auto - ✅ Pension accumulation (II pillar) support
- ✅ 2025 and 2026 tax year support (2026 rates are projections)
- ✅ Structured warnings and assumptions in every result
- ✅ Fully typed TypeScript with strict mode
- ✅ Zero runtime dependencies
- ✅ 81 tests, 100% pure functions
Installation
npm install wtax-engineQuick Start
import { calculate2025 } from "wtax-engine";
const result = calculate2025({
taxYear: 2025,
grossIncome: 30_000, // EUR earned this year
actualExpenses: 4_500, // Documented business expenses
deductionMethod: "auto", // Engine picks the better option
isStudent: false,
pensionAccumulation: false,
});
console.log(`Safe to spend: €${result.summary.safeToSpend}`);
console.log(`Total tax: €${result.summary.totalTax}`);
console.log(`Effective rate: ${(result.summary.effectiveTaxRate * 100).toFixed(1)}%`);
console.log(`Deduction used: ${result.selectedDeductionMethod}`);API
Entry Points
| Function | Description |
|---|---|
| calculate2025(input) | Calculate taxes for 2025 |
| calculate2026(input) | Calculate taxes for 2026 (projected rates) |
| calculateForYear(year, input) | Generic entry — any supported year |
| getSupportedYears() | Returns [2025, 2026] |
TaxInput
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| taxYear | 2025 \| 2026 | ✅ | — | Tax year |
| grossIncome | number | ✅ | — | Total gross income (EUR) |
| deductionMethod | "flat30" \| "actual" \| "auto" | ✅ | — | Deduction strategy |
| actualExpenses | number | ⚠️ | — | Required for actual/auto |
| isStudent | boolean | ❌ | false | Full-time student (PSD exemption) |
| pensionAccumulation | boolean | ❌ | false | II pillar pension (adds 3% to VSD) |
| monthlyPsdAlreadyPaid | number | ❌ | 0 | PSD already paid this year (EUR, total) |
| monthsActive | number | ❌ | 12 | Months with active income (1–12) |
TaxResult
{
taxYear: 2025,
engineVersion: "1.0.0",
input: { /* echoed input */ },
selectedDeductionMethod: "flat30" | "actual",
// Both scenarios available when deductionMethod is "auto"
scenarios: {
flat30: { method, deductionAmount, taxableIncome, totalTax },
actual?: { method, deductionAmount, taxableIncome, totalTax },
},
gpm: {
taxableIncome, // Net income after deduction
npdApplied, // NPD allowance applied
gpmBase, // Income subject to GPM (after NPD)
rate, // Effective/blended rate
amount, // GPM owed (EUR)
},
vsd: {
base, // VSD calculation base
rate, // VSD rate applied
amount, // VSD owed (EUR)
minimumFloorApplied, // true if income below MMA floor
ceilingCapApplied, // true if income above 43 × MMA ceiling
},
psd: {
studentExemptionApplied,
studentNote?, // Advisory if student
monthlyRate,
monthsActive,
annualDue, // Total PSD for the year (EUR)
alreadyPaid, // PSD already paid (EUR)
remaining, // Still owed (EUR)
},
summary: {
grossIncome,
deductionApplied,
taxableIncome,
gpm, // GPM amount
vsd, // VSD amount
psd, // PSD due
totalTax,
takeHome,
safeToSpend, // = takeHome (key product metric)
effectiveTaxRate, // Decimal fraction, e.g. 0.28
},
warnings: TaxWarning[], // { code, message, severity }
assumptions: string[],
recommendation: string,
disclaimer: string,
}Deduction Methods
| Method | Description |
|---|---|
| flat30 | Deduct 30% of gross income (capped at €30k/yr). No receipts needed. |
| actual | Deduct documented business expenses. Requires actualExpenses. |
| auto | Engine calculates both and picks whichever yields the lower tax bill. |
Warning Codes
| Code | Severity | Meaning |
|---|---|---|
| ZERO_INCOME | info | Gross income is zero |
| ACTUAL_EXPENSES_IGNORED | info | actualExpenses provided with flat30 method |
| EXPENSES_EXCEED_INCOME | warn | Expenses > income; deduction capped |
| VSD_MINIMUM_FLOOR | info | Income below MMA; VSD on minimum base |
| VSD_CEILING_APPLIED | info | Income above 43×MMA ceiling; VSD capped |
| UPPER_GPM_RATE_APPLIES | warn | Gross income above €114,162 bracket |
| HIGH_INCOME | warn | Income > €300k; consult professional |
| PROJECTED_YEAR_RATES | warn | 2026 rates not officially confirmed |
2025 Tax Constants
| Parameter | Value | Notes | |---|---|---| | GPM lower rate | 15% | Up to €114,162 taxable income | | GPM upper rate | 20% | Above €114,162 | | VSD rate | 12.52% | +3% if pension accumulation | | VSD min base | €924/month | MMA 2025 | | VSD ceiling | 43 × MMA × months | | | PSD (non-student) | €21.58/month | | | PSD (student) | €0/month | Full exemption | | flat30 max deduction | €30,000 | | | NPD base | €7,140/year | |
Repository Structure
wtax-engine/
├── src/
│ ├── index.ts # Public API entry point
│ ├── engine.ts # Core calculation logic
│ ├── types/
│ │ └── index.ts # All TypeScript types
│ ├── utils/
│ │ ├── math.ts # Pure math helpers
│ │ └── validation.ts # Input validation
│ └── years/
│ ├── registry.ts # Year config registry
│ ├── config2025.ts # 2025 tax constants
│ └── config2026.ts # 2026 projected constants
├── tests/
│ ├── engine.test.ts # 53 integration tests
│ ├── validation.test.ts # 12 validation tests
│ └── math.test.ts # 16 unit tests
├── dist/ # Built output (CJS + ESM + types)
├── package.json
├── tsconfig.json
└── vitest.config.tsAdding a New Tax Year
- Create
src/years/config20XX.tsfollowing theYearConfiginterface - Import and register it in
src/years/registry.ts - Export a
calculate20XX()convenience function insrc/index.ts - Add tests to
tests/engine.test.ts
Development
# Install dependencies
npm install
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverage
# Build
npm run build
# Type-check only
npm run typecheckLicense
MIT — see LICENSE
This package is part of the WTax platform — the simplest way for self-employed people in Lithuania to know exactly how much tax they owe.
