Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
push:
branches: [main, 'claude/**']
pull_request:
branches: [main]

jobs:
test:
name: Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18, 20, 22]

steps:
- uses: actions/checkout@v4

- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules/
coverage/
202 changes: 185 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,198 @@
# HSN Code Package
# hsn-code-package

HSN code stands for “Harmonized System of Nomenclature”. This system has been introduced for the systematic classification of goods all over the world. HSN code is a 6-digit uniform code that classifies 5000+ products and is accepted worldwide. It was developed by the World Customs Organization (WCO) and it came into effect from 1988 [(more...)](https://cleartax.in/s/gst-hsn-lookup)
Fast, **zero-runtime-dependency** HSN code lookup for Node.js.

This package contains an HSN code list and has three methods to get results.
Search 12,000+ HSN (Harmonized System of Nomenclature) codes by description or code number, validate codes, browse by chapter, and paginate large result sets — all backed by pre-built JSON data so there is nothing to parse at startup.

## Installation
[![npm version](https://img.shields.io/npm/v/hsn-code-package)](https://www.npmjs.com/package/hsn-code-package)

---

## What are HSN codes?

HSN codes are 6-8 digit uniform codes developed by the World Customs Organization (WCO) in 1988 to systematically classify goods worldwide. In India they are extended to 8 digits for GST purposes and maintained by CBIC.

Use the package manager [npm](https://www.npmjs.com/package/hsn-code-package) to install hsn-code-package.
---

## Installation

```bash
npm i hsn-code-package
npm install hsn-code-package
```

No extra dependencies are installed. The package ships pre-built JSON data.

---

## Quick start

```js
const {
getAllHsn,
getCodeByTxt,
getDesByCode,
getHsnByExactCode,
isValidHsnCode,
getHsnChapter,
searchHsn,
getStats
} = require('hsn-code-package');
```

---

## API

### `getAllHsn()`
Returns every HSN code entry.

```js
const all = getAllHsn();
// [ { code: '1011010', description: 'LIVE HORSES ...' }, ... ]
console.log(all.length); // 12604
```

---

### `getCodeByTxt(txt)`
Case-insensitive partial search on descriptions. Returns all matching entries.

```js
getCodeByTxt('cotton');
// [ { code: '...', description: '... COTTON ...' }, ... ]
```

| Param | Type | Description |
|-------|------|-------------|
| `txt` | `string` | Search text (partial match, case-insensitive) |

---

### `getDesByCode(code)`
Returns all entries whose code **contains** the given value (partial match).
Use `getHsnByExactCode` when you need a strict lookup.

```js
getDesByCode('5201');
// All entries whose code contains '5201'
```

---

### `getHsnByExactCode(code)`
Returns the single entry matching the exact code, or `undefined`.

```js
const entry = getHsnByExactCode('52010011');
// { code: '52010011', description: 'COTTON, NOT CARDED ...' }

isValidHsnCode('00000000'); // undefined — code not found
```

---

### `isValidHsnCode(code)`
Returns `true` if the exact code exists, `false` otherwise. Safe to call with `null` or `undefined`.

```js
isValidHsnCode('52010011'); // true
isValidHsnCode('00000000'); // false
isValidHsnCode(null); // false
```

Useful for **form validation** in GST invoice workflows.

---

### `getHsnChapter(chapter)`
Returns all codes under a chapter (first two digits of the full 8-digit code).

```js
getHsnChapter('52'); // All cotton-related codes (chapter 52)
getHsnChapter(1); // Live animals (chapter 01) — numeric input accepted
```

---

### `searchHsn(query, options?)`
Advanced search with match type and pagination.

```js
// First 10 results containing 'silk'
searchHsn('silk', { limit: 10 });

// Codes whose description starts with 'raw'
searchHsn('raw', { matchType: 'startsWith', limit: 5 });

// Paginate — skip first 20, take next 10
searchHsn('cotton', { offset: 20, limit: 10 });
```

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `matchType` | `'contains' \| 'startsWith' \| 'exact'` | `'contains'` | How to match against description |
| `limit` | `number` | `0` (unlimited) | Max results to return |
| `offset` | `number` | `0` | Results to skip (for pagination) |

---

### `getStats()`
Returns metadata about the bundled dataset.

```js
getStats();
// {
// version: '2.0.0',
// lastUpdated: '2026-06-01',
// totalCodes: 12604,
// chapterCount: 86,
// source: 'CBIC / WCO Harmonized System Nomenclature'
// }
```

---

## TypeScript

Type definitions are bundled. No `@types/` package needed.

```ts
import { getHsnByExactCode, isValidHsnCode, HsnCode } from 'hsn-code-package';

const entry: HsnCode | undefined = getHsnByExactCode('52010011');
```

## Usage
Can be used
---

```javascript
# returns objects array contains all codes with description
getAllHsn()
## Migrating from v1

# returns array of hsn code objects matches the search_txt
getCodeByTxt('search_txt')
| v1 | v2 | Notes |
|----|-----|-------|
| `getDesByCode(code)` | `getDesByCode(code)` | Same, but now validates input and won't crash on `null` |
| `getCodeByTxt(txt)` | `getCodeByTxt(txt)` | Same, but now validates input |
| `getAllHsn()` | `getAllHsn()` | Same, but result is cached after first call |
| _(not available)_ | `getHsnByExactCode(code)` | New — strict single-result lookup |
| _(not available)_ | `isValidHsnCode(code)` | New — boolean validation |
| _(not available)_ | `getHsnChapter(chapter)` | New — chapter-level browse |
| _(not available)_ | `searchHsn(query, options)` | New — paginated / typed search |
| _(not available)_ | `getStats()` | New — dataset metadata |

# returns array of hsn code objects matches the search_code
getDesByCode(search_code)
**Breaking change**: `module.exports` in v1 was broken (bitwise OR evaluated to `0`). If you were using `require('hsn-code-package')` directly as a function it would have failed silently. v2 correctly exports named functions.

---

## Data updates

The HSN dataset is maintained in `data/hsn_codes.json`. To rebuild from the source Excel:

```bash
node scripts/build-data.js
```

### About Contribution
Hasn't made this package public yet, so as soon I made this package a stable one with all future I got I will make it open source, before that, if anyone needs any extra features or any corrections please leave me a mail.
This re-converts `code_list.xlsx` and updates `data/hsn_codes.json` and `data/metadata.json`.

---

## Contributing

Issues and feature requests: [GitHub Issues](https://github.com/karthi-21/HSN-Code-Package/issues)
1 change: 1 addition & 0 deletions data/hsn_codes.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions data/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"version": "2.0.0",
"lastUpdated": "2026-06-01",
"totalCodes": 12604,
"chapterCount": 86,
"source": "CBIC / WCO Harmonized System Nomenclature"
}
45 changes: 45 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export interface HsnCode {
code: string;
description: string;
}

export interface SearchOptions {
/** Default: 'contains' */
matchType?: 'contains' | 'startsWith' | 'exact';
/** Max results to return. 0 = unlimited. Default: 0 */
limit?: number;
/** Number of results to skip (for pagination). Default: 0 */
offset?: number;
}

export interface HsnStats {
version: string;
lastUpdated: string;
totalCodes: number;
chapterCount: number;
source: string;
}

/** Returns all 12,000+ HSN codes. */
export function getAllHsn(): HsnCode[];

/** Case-insensitive partial search on description. */
export function getCodeByTxt(txt: string): HsnCode[];

/** Returns all codes whose code string contains the given value (partial match). */
export function getDesByCode(code: string | number): HsnCode[];

/** Returns the single entry matching the exact code, or undefined. */
export function getHsnByExactCode(code: string | number): HsnCode | undefined;

/** Returns true if the exact code exists in the HSN list. */
export function isValidHsnCode(code: string | number): boolean;

/** Returns all codes under a chapter (first two digits), e.g. '01' or 1. */
export function getHsnChapter(chapter: string | number): HsnCode[];

/** Advanced description search with matchType and pagination support. */
export function searchHsn(query: string, options?: SearchOptions): HsnCode[];

/** Returns metadata about the bundled dataset (version, date, totals). */
export function getStats(): HsnStats;
Loading
Loading