Functional Weave
Code in TypeScript

payroll.tax-code-parse@1.0.2

README.md

3,804 bytes · view raw

# payroll.tax-code-parse

Takes a UK PAYE tax code apart. It does not calculate tax; `payroll.income-tax`
does that, using this.

What a code is made of:

- An optional country prefix: `S` for a Scottish taxpayer, `C` for a Welsh one,
  nothing for England and Northern Ireland (`rest-of-uk`).
- The code proper, one of:
  - a number and a suffix letter, `1257L`, `1100M`, `1385N`, `0T`: a tax-free
    allowance. The number is the allowance divided by ten, so the annual
    allowance HMRC's routines use is **number x £10 + £9**: 1257L is £12,579,
    not £12,570, because the code covers a £10 range and the routines give the
    employee the top of it. `0T` means no allowance at all.
  - `K` and a number, `K475`: a negative allowance, pay to be *added* to
    taxable pay (£4,759 a year for K475). There is no K0.
  - `BR`: all pay at the basic rate. `D0`, `D1` (and `SD0` to `SD3` in
    Scotland): all pay at the rate one, two, three or four bands above basic.
  - `NT`: no tax. There is no Scottish or Welsh NT, so `SNT` is refused.
- An optional basis marker, `W1`, `M1` or `X`, meaning the code is operated on
  a week 1 / month 1 (non-cumulative) basis. It may follow the code with or
  without a space: `1257L W1`, `1257LM1`, `1257L X`.

Suffix letters L, M, N and T do not change the calculation (M and N are the
marriage allowance, T means HMRC wants to review the code); they are returned
so a payroll can apply HMRC's bulk code uplifts, which are made by suffix.
Withdrawn suffixes (P, V, Y, retired in 2016) and anything else unrecognised
are errors rather than guesses. Leading zeros (`01257L`) are refused, since
HMRC never issues them and they usually mean a keying error.

Sources: HMRC, "Tax codes" (https://www.gov.uk/tax-codes, and its "What your
tax code means" page, https://www.gov.uk/tax-codes/what-your-tax-code-means);
HMRC, "Specification for PAYE tax table routines" v24.0 (February 2026),
paragraphs 4.3.1 (the £10 x number + £9 annual value, K codes, 0T), 7 and 11
(NT has no S or C version), 8 (week 1 / month 1 basis),
https://www.gov.uk/government/publications/payroll-technical-specifications-income-tax.

1.0.1 fixes Python accepting a trailing newline in code (its patterns now use
fullmatch), and trims the same whitespace in every language: spaces, tabs,
line breaks and Unicode space separators. Before, Python also trimmed U+001C to
U+001F and U+0085, Rust U+0085 and TypeScript U+FEFF; each is now refused as
part of the code. Adds tests.

## Before you rely on this

**Not professional advice.** This capability calculates payroll figures from published rules. It is a software component for developers, not tax or legal advice. Rules change and every rate here has an effective date. Check that the dates cover your case. Verify results against the official sources listed above, and have a payroll specialist review how you use it, before anyone relies on the output. Provided "as is" under its licence, without warranty.

**Unreviewed.** This capability's implementations agree in every language and pass its published test vectors, which were worked out from the official sources cited. But no qualified payroll specialist has yet checked those vectors, or confirmed that the capability covers the cases it claims. Treat it as a draft. Do not use it for real people, money or decisions without your own expert review. Once a qualified reviewer signs off, this notice is replaced with their name, qualification and the date. Each new version needs fresh sign-off.

## Notices

Contains public sector information licensed under the Open Government
Licence v3.0 (https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).

1.0.2 marks it unreviewed and adds its attribution notices (NOTICE). The code and the tests are unchanged.