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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@netsi/address-component

v1.0.1

Published

A fully encapsulated web component for Danish address lookup using DAWA.

Readme

Netsi Address Component

A fully encapsulated, zero-dependency web component for simple and robust Danish address lookup using Dataforsyningen's DAWA API. This component is written in TypeScript and provides strong typing for all configurations.

It is designed as a "headless" controller that attaches to your existing form fields, making it extremely flexible to integrate into any project.

Features

  • Headless & Flexible: Attaches to any form structure using CSS selectors.
  • TypeScript First: Provides strong types for configuration and API responses.
  • Smart Defaults: Works out-of-the-box with a standard set of element IDs. No configuration needed for a basic setup.
  • Advanced Data Mapping: Use a mapper function to transform API data before it's displayed in your UI.
  • Zero Dependencies: Compiles to a single, dependency-free JavaScript file.
  • Configurable: Easily configured, including all DAWA API parameters.
  • Fuzzy Search: Optionally falls back to a "fuzzy" search if no exact matches are found.
  • Keyboard Navigation: Full support for ArrowUp, ArrowDown, Enter, and Escape.
  • Tested: Includes a suite of unit tests for core logic.

Demo

A local demo is available in the /demo directory. To run it, you first need to build the component from its TypeScript source.

# First, install Deno: https://deno.com/manual/getting_started/installation
# Then, build the project:
deno task build

# Serve the demo folder
npx http-server -o demo/index.html

Installation

Via JSR (Recommended)

deno add @netsi/address

Via NPM

npm install @netsi/address

Via CDN

The component's source is TypeScript, so direct use in the browser requires a build step. For CDN usage, it's recommended to use a service that transpiles and bundles JSR packages, like esm.sh.

<script type="module">
  // The 'netsi-address' element is automatically defined.
  import "https://esm.sh/@netsi/address";
</script>

Usage

1. Basic Usage (with Default Selectors)

If your form fields follow a simple ID convention, you can use the component with minimal configuration.

HTML:

<!-- The standalone component tag -->
<netsi-address id="address-component"></netsi-address>

<!-- Your form with the default IDs -->
<div class="form-group">
  <label for="address">Search for a Danish address</label>
  <!-- The component defaults to looking for an input with id="address" -->
  <input type="text" id="address" placeholder="e.g., Rådhuspladsen 1, 1550">
</div>

<!-- Default fields to be populated -->
<input type="text" id="vejnavn" readonly>
<input type="text" id="husnr" readonly>
<input type="text" id="postnr" readonly>
<input type="text" id="postnrnavn" readonly>
<!-- ... etc. See full list of defaults below. -->

JavaScript:

import "@netsi/address-component";

const addressComponent = document.getElementById("address-component");
// Minimal config, as the component will use its smart defaults.
addressComponent.config = {
  useFuzzyFallback: true,
};

2. Advanced Usage (with Custom Selectors and Mappers)

For full control, provide a ui object in the configuration. You can specify custom selectors and use a mapper function to format the data.

HTML:

<netsi-address id="address-component"></netsi-address>

<input type="text" class="my-search-field">
<input type="text" class="my-road-name-field" readonly>
<div>
  <span>Address created on:</span>
  <strong id="created-date"></strong>
</div>

JavaScript:

import "@netsi/address-component";

const addressComponent = document.getElementById("address-component");

addressComponent.config = {
  // Component behavior
  useFuzzyFallback: true,

  // DAWA API Parameters
  postnr: "2100", // Filter all searches by a specific postal code

  // UI Mapping
  ui: {
    // --- This is mandatory for custom UI ---
    address: ".my-search-field",

    // --- Simple mapping ---
    "adgangsadresse.vejstykke.navn": ".my-road-name-field",

    // --- Advanced mapping with a mapper function ---
    "historik.oprettet": {
      selector: "#created-date",
      mapper: (isoDateString) => {
        if (!isoDateString) return "Unknown";
        // Format the date for better readability
        return new Date(isoDateString).toLocaleDateString("da-DK");
      },
    },
  },
};

Default UI Selectors

If the ui object is not provided, the component uses the following id selectors. The keys are dot-notation paths to the data in the DAWA API response.

| Data Path | Default Selector | | -------------------------------- | ---------------- | | address (The search input) | #address | | etage | #etage | | dør | #doer | | adgangsadresse.vejstykke.navn | #vejnavn | | adgangsadresse.husnr | #husnr | | adgangsadresse.postnummer.nr | #postnr | | adgangsadresse.postnummer.navn | #postnrnavn | | adgangsadresse.kommune.kode | #kommunekode | | adgangsadresse.kommune.navn | #kommune |

Development

This project uses Deno for development.

  • To build the browser-compatible bundle for the demo:

    deno task build

    This command uses esbuild to compile src/netsi-address.ts into demo/netsi-address.bundle.js.

  • To run the tests:

    deno task test

Events

The component emits a netsi-address:select event when an address is successfully selected. The event.detail property contains the complete address object from DAWA.

addressComponent.addEventListener("netsi-address:select", (event) => {
  console.log("Address selected:", event.detail);
});

This package was added to JSR and NPM with the help of Cursor. A fully encapsulated web component for Danish address lookup using DAWA.