Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 1,000,000+ packages pre-installed, including postcode with all npm packages installed. Try it out:

const { parse, isValid, toOutcode } = require("postcode"); // Quickly sanity check postcode console.log(isValid("SW1A 2AA")); // Extract outward code console.log(toOutcode("SW1A 2AA")); // Parse postcode to access different parts const postcode = parse("Sw1a 2AA");

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

postcode v5.0.0

UK Postcode helper methods


Validate & parse UK postcodes

CI codecov Dependencies Size Downloads Release Try postcode on RunKit

Utility methods for UK Postcodes, including validating the shape of a postcode, extracting postcode elements (like incodes, outcodes, areas and more).

Tested against ~1.7 million postcodes on ONSPD.




Getting Started


npm install postcode


import { isValid } from "postcode";

isValid("AA1 1AB"); // => true


Pass a string to parse. This will return a valid or invalid postcode instance which can be easily destructured.

Valid Postcode

ValidPostcode type definition

import { parse } from "postcode";

const {
  postcode,    // => "SW1A 2AA"
  outcode,     // => "SW1A"
  incode,      // => "2AA"
  area,        // => "SW"
  district,    // => "SW1"
  unit,        // => "AA"
  sector,      // => "SW1A 2"
  subDistrict, // => "SW1A"
  valid,       // => true
} = parse("Sw1A     2aa");

Invalid Postcode

InvalidPostcode type definition

const {
  postcode,    // => null
  outcode,     // => null
  incode,      // => null
  area,        // => null
  district,    // => null
  unit,        // => null
  sector,      // => null
  subDistrict, // => null
  valid,       // => false
} = parse("    Oh no, ):   ");

Type Guard

The TypeScript compiler can infer if you have a valid postcode type from parse by checking the valid attribute

import { parse } from "postcode";

const postcode = parse("SW1A 2AA");

if (postcode.valid) {
  // `postcode` adheres to the `ValidPostcode` interface
  processString(postcode.outcode.toLowerCase()); // TypeScript compiler knows `outcode` to be a string
  processString(postcode.subDistrict.toLowerCase()); // And it will throw errors on common gotchas (e.g. subdistrict can be `null` on a valid postcode)
} else {
  // `postcode` adheres to the `InvalidPostcode` interface

Valid Postcode Object

A9 9AAA99AAAA9nullA9 9AA
A99 9AAA999AAAA99nullA99 9AA
AA99 9AAAA999AAAAAA99nullAA99 9AA

Exported Methods

If you're just after a single value, you can import a single method.


isValid("Sw1A 2aa"); // => true


import {
} from "postcode";

toNormalised("Sw1A 2aa");  // => "SW1A 2AA"
toOutcode("Sw1A 2aa");     // => "SW1A"
toIncode("Sw1A 2aa");      // => "2AA"
toArea("Sw1A 2aa");        // => "AA"
toDistrict("Sw1A 2aa");    // => "SW1"
toSubDistrict("Sw1A 2aa"); // => "SW1A"
toSector("Sw1A 2aa");      // => "SW1A 2"
toUnit("Sw1A 2aa");        // => "AA"

Extract & Replace

match. Retrieve valid postcodes in a body of text

const matches = match("The PM and her no.2 live at SW1A2aa and SW1A 2AB"); // => ["SW1A2aa", "SW1A 2AB"]

// Perform transformations like normalisation using `.map` and `toNormalised`; // => ["SW1A 2AA", "SW1A 2AB"]; // => ["SW1A", "SW1A"]

// No matches yields empty array
match("Some London outward codes are SW1A, NW1 and E1"); // => []

replace. Replace postcodes in a body of text, returning the updated corpus and any matching postcodes

const { match, result } = replace("The PM and her no.2 live at SW1A2AA and SW1A 2AB");
// => match: ["SW1A2AA", "SW1A 2AB"]
// => result: "The PM and her no.2 live at  and "

// Add custom replacement
replace("The PM lives at SW1A 2AA", "Downing Street");
// => { match: ["SW1A 2AA"], result: "The PM lives at Downing Street" };

// No match
replace("Some London outward codes are SW1A, NW1 and E1");
// => { match: [], result: "Some London outward codes are SW1A, NW1 and E1" }

Version 5.0.0

5.0.0 brings changes which allows for better treeshaking and interopability with ES Modules. It also deprecates legacy class based APIs in favour of single purpose methods.

Breaking Changes

  • postcode no longer exports a class. Legacy new Postcode() functionality has been removed. Methods attached to Postcode are all available as named exports.
  • postcode no longer uses default exports. All exports are named. E.g.
// In <= 4.0.0
import Postcode from "postcode";
Postcode.parse("SW1A 2AA");

// In >= 5.0.0
import { parse } from "postcode";
parse("SW1A 2AA");

In many cases, migration can be achieved by changing import Postcode from "postcode" to import * as Postcode from "postcode", however this gives up treeshaking advantages.

New Features

  • postcode now exports a ES Module build
  • Exports regular expressions
  • match accepts a string and returns all valid postcodes
  • replace accepts a string and replaces valid postcodes with an optional second argument. Default replacement text is empty string ""


See the postcode format guide for a glossary of postcode component terms.


Postcodes cannot be validated just with a regular expression (however complex). True postcode validation requires having a full list of postcodes to check against. Relying on a regex will produce false postives/negatives.

See the postcode validation guide for an overview of the approaches and tradeoffs associated with postcode validation.


npm test



Contains Ordnance Survey Data © Crown Copyright & Database Right


RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free