npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

cpv-eu

v1.0.1

Published

Common Procurement Vocabulary (CPV) for EU procurement

Readme

cpv-eu

A TypeScript/JavaScript library for working with Common Procurement Vocabulary (CPV) codes used in EU public procurement. Supports 24 European languages including English, German, French, Swedish and more.

What is CPV?

The Common Procurement Vocabulary (CPV) is a standardized classification system used throughout the European Union for public procurement. It consists of a main vocabulary for defining the subject of a contract, and a supplementary vocabulary for adding further qualitative information.

Features

  • 9,454 CPV Codes: Complete EU CPV vocabulary
  • Hierarchical Data: Full CPV hierarchy with parent-child relationships
  • Multi-language Support: 24 European languages including EN, DE, FR, SV, ES, IT, NL, PL, PT, and more
  • TypeScript Support: Full type definitions included

Installation

npm install cpv-eu

Quick Start

import { 
  getLabelByCPVCode, 
  getCategoryChildrenByCPVCode, 
  getAllCategories,
  getAllRaw,
  SupportedLanguages 
} from 'cpv-eu';

// Get a label for a CPV code - e.g.
const label = getLabelByCPVCode("45000000", "en");
console.log(label);

// Get children of a CPV code - e.g.
const children = getCategoryChildrenByCPVCode("45", "en");
console.log(children);

// Get all categories in a language - e.g.
const allCategories = getAllCategories("en", 2); // Up to level 2
console.log(allCategories);

Core Functions

getLabelByCPVCode(cpvCode: string, language: SupportedLanguages): string

Get the label for a specific CPV code in the specified language.

import { getLabelByCPVCode, SupportedLanguages } from 'cpv-eu';

// Get English label
const label = getLabelByCPVCode("45000000", "en");
// Returns: "Construction work"

// Get Swedish label
const swedishLabel = getLabelByCPVCode("45000000", "sv");
// Returns: "Byggarbeten"

// Get German label
const germanLabel = getLabelByCPVCode("45000000", "de");
// Returns: "Bauarbeiten"

getCategoryChildrenByCPVCode(cpvCode: string, language: SupportedLanguages): StructuredCPVItem[]

Get the immediate children of a CPV code.

import { getCategoryChildrenByCPVCode } from 'cpv-eu';

// Get children of construction work
const children = getCategoryChildrenByCPVCode("45000000", "en");
// Returns array of child categories like:
// [
//   {
//     code: "45100000",
//     label: "Site preparation work",
//     emoji: "🏗️",
//     level: 2,
//     parent: "45000000"
//   },
//   // ... more children
// ]

getAllCategories(language: SupportedLanguages, maxLevel?: 1 | 2 | 3 | 4): StructuredCPVItem[]

Get all CPV categories in a hierarchical structure.

import { getAllCategories } from 'cpv-eu';

// Get all categories up to level 2
const categories = getAllCategories("en", 2);

// Get all categories (default: up to level 4)
const allCategories = getAllCategories("en");

getAllRaw(): CPVItem[]

Get all raw CPV data items.

import { getAllRaw } from 'cpv-eu';

const allItems = getAllRaw();
console.log(`Total CPV items: ${allItems.length}`); // 9,454

Data Types

CPVItem

interface CPVItem {
  code: string;           // 8-digit CPV code
  labels: Record<string, string>; // Multi-language labels
  emoji: string;          // Category emoji
  level: number;          // Hierarchy level (1-4)
  parent?: string;        // Parent CPV code (if any)
}

StructuredCPVItem

interface StructuredCPVItem {
  code: string;
  label: string;          // Label in specified language
  emoji: string;
  level: number;
  parent?: string;
  children?: StructuredCPVItem[]; // Nested children
}

SupportedLanguages

type SupportedLanguages = 
  | "en" | "de" | "fr" | "sv" | "es" | "it" | "nl" | "pl" | "pt"
  | "bg" | "cs" | "da" | "et" | "el" | "fi" | "hu" | "ga" | "hr"
  | "lv" | "lt" | "mt" | "ro" | "sk" | "sl";

CPV Code Structure

CPV codes follow a hierarchical structure:

  • Level 1 (XX000000): Division (45 categories)
  • Level 2 (XXXX0000): Group
  • Level 3 (XXXXXX00): Class
  • Level 4 (XXXXXXXX): Category

Example Hierarchy

45 (Construction work)
├── 4510 (Site preparation work)
│   ├── 451100 (Demolition work)
│   └── 451200 (Test drilling and boring work)
└── 4520 (Works for complete or part construction)
    ├── 452100 (Building construction work)
    └── 452200 (Engineering works and construction works)

Supported Languages

The library supports all 24 official EU languages:

| Language | Code | Language | Code | |----------|------|----------|------| | English | en | German | de | | French | fr | Swedish | sv | | Spanish | es | Italian | it | | Dutch | nl | Polish | pl | | Portuguese | pt | Bulgarian | bg | | Czech | cs | Danish | da | | Estonian | et | Greek | el | | Finnish | fi | Hungarian | hu | | Irish | ga | Croatian | hr | | Latvian | lv | Lithuanian | lt | | Maltese | mt | Romanian | ro | | Slovak | sk | Slovenian | sl |

Examples

Get Construction Categories

import { getCategoryChildrenByCPVCode } from 'cpv-eu';

const constructionCategories = getCategoryChildrenByCPVCode("45000000", "en");
constructionCategories.forEach(category => {
  console.log(`${category.code}: ${category.label} ${category.emoji}`);
});

Search by Label

import { getAllRaw } from 'cpv-eu';

const searchTerm = "construction";
const allItems = getAllRaw();

const matches = allItems.filter(item => 
  Object.values(item.labels).some(label => 
    label.toLowerCase().includes(searchTerm.toLowerCase())
  )
);

console.log(`Found ${matches.length} items containing "${searchTerm}"`);

Build Category Tree

import { getAllCategories } from 'cpv-eu';

function printCategoryTree(categories, indent = 0) {
  categories.forEach(category => {
    console.log('  '.repeat(indent) + `${category.code}: ${category.label} ${category.emoji}`);
    if (category.children) {
      printCategoryTree(category.children, indent + 1);
    }
  });
}

const tree = getAllCategories("en", 3);
printCategoryTree(tree);

Development

For development setup, build instructions, and contributing guidelines, see README-DEV.md.

Quick Testing

// Test individual functions
import { getLabelByCPVCode } from 'cpv-eu';

console.log(getLabelByCPVCode("45000000", "en")); // "Construction work"
console.log(getLabelByCPVCode("45000000", "sv")); // "Byggarbeten"

Data Source

The CPV data is sourced from the official EU TED (Tenders Electronic Daily) Excel files and includes:

  • 9,454 CPV codes across all levels
  • 24 language translations for each code
  • Hierarchical relationships with parent-child links
  • Emoji mappings for visual categorization
  • Level classification (1-4) for each code

⚠️ Emoji Matching Disclaimer

The emoji mappings in this library are automatically generated based on keyword matching in CPV labels. While they provide visual categorization, they are not 100% accurate and should be used with caution in production environments.

Limitations:

  • Emoji selection is based on simple keyword matching
  • Some categories may have inappropriate or misleading emojis
  • The matching algorithm may not capture all nuances of CPV categories
  • Emojis are for visual reference only and should not be used for categorization logic

Recommendation: Use emojis for display purposes only, not for programmatic decision-making or filtering.

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

GitHub Repository: https://github.com/samhallskod/cpv-eu

Support

For support, please open an issue on GitHub or contact the maintainers.


Made with ❤️ by Samhällskod