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

@webarkit/featureset-display

v0.5.0

Published

FeatureSET Display based on ARToolKit, ported thanks to Emscripten

Readme

FeatureSET-Display

Display the contents of NFT marker files (.iset, .fset, .fset3) — the image preview plus the feature points used for detection and tracking — in a browser, via WebAssembly.

Useful for inspecting markers generated with NFT-Marker-Creator or Nft-Marker-Creator-App : see at a glance whether a marker has enough trackable features, whether they're clustered in a corner, or whether the source image lost contrast during the dataset build.


What you get

For any marker triplet (name.iset + name.fset + name.fset3), the library:

  • Reads the imageSet preview into an HTML5 canvas.
  • Overlays the detection feature points as light green circles.
  • Overlays the tracking feature points as small red circles.
  • Logs the marker dimensions, DPI, and feature-point counts to the browser console.

Install

npm install @webarkit/featureset-display

Or load the UMD bundle directly:

<script src="https://unpkg.com/@webarkit/featureset-display"></script>

Quick start (ES module)

<script type="module">
  import ARFsetModule from '@webarkit/featureset-display';

  const ar = new ARFsetModule.ARFset();
  await ar.initialize();
  await ar.loadNFTMarker('path/to/marker'); // no extension
  ar.display();
</script>

The library will create a <canvas id="iSet"> element in the document body and render the marker preview into it. Use attachCanvas(id) before initialize() to mount it inside a specific container instead:

const ar = new ARFsetModule.ARFset();
ar.attachCanvas('my-container');
await ar.initialize();
await ar.loadNFTMarker('path/to/marker');
ar.display();

Quick start (<script> tag)

<script src="dist/ARFset.umd.js"></script>
<script>
  const ar = new ARFset.ARFset();
  ar.initialize().then(() => {
    ar.loadNFTMarker('path/to/marker');
    ar.display();
  });
</script>

window.ARFset resolves to the same default export as the ESM build.

API

new ARFset(options?)

| Option | Type | Default | Description | | -------- | ------ | ------- | --------------------------- | | width | number | 893 | Initial wasm canvas width. | | height | number | 1117 | Initial wasm canvas height. |

These set the wasm-side initial memory layout. The on-screen canvas is resized at marker-load time to the actual reported marker dimensions, so the defaults don't need to match your marker.

await ar.initialize()

Loads the WebAssembly runtime and prepares the canvas. Must be awaited before anything else.

ar.attachCanvas(id)

Mount the canvas inside an existing DOM element instead of body. Call before initialize().

await ar.loadNFTMarker(urlPrefix)

Fetches urlPrefix.iset, urlPrefix.fset, and urlPrefix.fset3, loads them into the wasm filesystem, and dispatches an 'nftMarker' CustomEvent on document when ready.

await ar.loadNFTMarkerBlob([isetUrl, fset3Url, fsetUrl])

Same as above but for user-uploaded data — pass an array of three URLs (or data URLs from FileReader.readAsDataURL) in the order [iset, fset3, fset].

ar.display()

Subscribe to the 'nftMarker' event and render the marker preview plus feature-point circles whenever a marker loads.

Events dispatched on document

| Event | Detail | | ----------- | ------------------------------------------------------------------- | | nftMarker | { numIset, widthNFT, heightNFT, dpi, numFpoints, nftPoints, ... } | | imageEv | (no detail) — fired after the canvas has been painted |

How it works

flowchart LR
  user[User code] -->|loadNFTMarker URL| js[ARFset class JS]
  js -->|fetch .iset .fset .fset3| net[network]
  net -->|Uint8Array| fs[wasm FS]
  js -->|_readNFTMarker arId path| wasm[ARimageFsetDisplay wasm]
  wasm -->|reads| fs
  wasm -->|nftMarker struct + nftPoints + nftFsetPoints| js
  js -->|nftMarker event| display[display handler]
  display -->|putImageData + arc| canvas[canvas iSet]

The C++ side (emscripten/ARimageFsetDisplay.cpp) links against WebARKitLib (a maintained fork of jsartoolkit5 / ARToolKit5) to parse the .iset / .fset / .fset3 files and extract feature points. The result is returned through an embind value_object, so JS reads the data directly from the returned struct — no EM_ASM side-channel.

Build from source

Prerequisites:

  • Node.js 22+

  • emsdk with EMSDK set (run emsdk_env.bat / source emsdk_env.sh once per shell).

  • Python 3 on PATH (needed by emcc.py on Windows).

  • Git submodules initialised:

    git submodule update --init --recursive

Then:

npm install          # devDependencies (vite, vitest, playwright)
npm run build        # wasm bundles -> build/
npm run build-es6    # JS bundle    -> dist/
npm test             # unit tests   (Vitest)
npm run test:e2e     # browser smoke test (Playwright)

To try the example locally:

npm run serve
# open http://localhost:8080/example/example_es6.html

Migration from 0.3.x

0.4.0 removed the legacy global window.ARfset API and the asm.js build targets.

Before (0.3.x):

<script src="build/arfset.min.js"></script>
<script>
  const ar = new ARfset();
  ar.loadNFTMarker('marker', (nft) => { ... });
</script>

After (0.4.x), ESM:

<script type="module">
  import ARFsetModule from '@webarkit/featureset-display';
  const ar = new ARFsetModule.ARFset();
  await ar.initialize();
  await ar.loadNFTMarker('marker');
  ar.display();
</script>

After (0.4.x), classic script:

<script src="dist/ARFset.umd.js"></script>
<script>
  const ar = new ARFset.ARFset();
  ar.initialize().then(() => {
    ar.loadNFTMarker('marker');
    ar.display();
  });
</script>

Note the new namespace: window.ARFset exposes { ARFset: class }, so the class is reached as ARFset.ARFset. The class also requires an initialize() await before loadNFTMarker, where the legacy global used to dispatch a FeatureSETDisplay-loaded event instead.

License

LGPL-3.0 — see LICENSE.txt.