Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More

postcode

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcode

UK Postcode helper methods


Version published
Maintainers
1
Created

Postcode.js

Validate & parse UK postcodes

CI codecov Dependencies Release

Size Downloads 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.

Features

Guides

Getting Started

Installation

npm install postcode

Validate

import { isValid } from "postcode";

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

Parse

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
  processInvalidPostcode(postcode);
}
Valid Postcode Object
Postcode.outcode.incode.area.district.subDistrict.sector.unit
AA9A 9AAAA9A9AAAAAA9AA9AAA9A 9AA
A9A 9AAA9A9AAAA9A9AA9A 9AA
A9 9AAA99AAAA9nullA9 9AA
A99 9AAA999AAAA99nullA99 9AA
AA9 9AAAA99AAAAAA9nullAA9 9AA
AA99 9AAAA999AAAAAA99nullAA99 9AA

Exported Methods

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

Validation
isValid("Sw1A 2aa"); // => true
Formatting
import {
  toNormalised,
  toOutcode,
  toIncode,
  toArea,
  toDistrict,
  toSubDistrict,
  toSector,
  toUnit,
} 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"
Fix

fix Attempts to correct and clean up a postcode without validating by replacing commonly misplaced characters (e.g. mixing up 0 and "O", 1 and "I"). This method will also uppercase and fix spacing. The original input is returned if it cannot be reliably fixed.

fix("SWIA 2AA") => "SW1A 2AA" // Corrects I to 1
fix("SW1A 21A") => "SW1A 2IA" // Corrects 1 to I
fix("SW1A OAA") => "SW1A 0AA" // Corrects O to 0
fix("SW1A 20A") => "SW1A 2OA" // Corrects 0 to O

// Other effects
fix(" SW1A  2AO") => "SW1A 2AO" // Properly spaces
fix("SW1A 2A0") => "SW1A 2AO" // 0 is coerced into "0"

Aims to be used in conjunction with parse to make postcode entry more forgiving:

const { inward } = parse(fix("SW1A 2A0")); // inward = "2AO"

If the input is not deemed fixable, the original string will be returned

fix("12a") => "12a"
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`
matches.map(toNormalised); // => ["SW1A 2AA", "SW1A 2AB"]
matches.map(toOutcode); // => ["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 ""

Definitions

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

Notes

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.

Testing

npm test

License

MIT

Contains Ordnance Survey Data © Crown Copyright & Database Right

FAQs

Package last updated on 24 Feb 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts