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

@image-marker/web

v0.1.0

Published

Standalone browser image watermarks, recipes and headless editing without React Native

Readme

@image-marker/web

Standalone browser SDK for Image Marker. It runs with Canvas 2D and Web APIs and does not install React Native, a Node sidecar, or native modules.

npm install @image-marker/[email protected]

Quick start

import Marker, { ImageFormat, Position } from '@image-marker/web';

const result = await Marker.markText({
  backgroundImage: { src: file }, // File, Blob, data URL, URL, or loaded image
  watermarkTexts: [
    {
      text: '© Acme',
      position: { position: Position.bottomRight, X: 24, Y: 24 },
      style: { color: '#FFFFFF', fontSize: 28 },
    },
  ],
  saveFormat: ImageFormat.png,
});

preview.src = result.uri;

The root entry exports the Web Marker, the existing public enums and types, Recipe v2 helpers, visible watermark methods, and invisible watermark embed/detect methods. Web results expose a data URL in result.uri.

Public subpaths

  • @image-marker/web/headless exports ImageMarkerEditorController, geometry, projection, presets, and editor types without React or React Native UI.
  • @image-marker/web/editor-adapter exports createWebEditorAdapter and resolveWebEditorSourceInfo. The adapter connects a headless Recipe to Canvas preview and original export.
  • @image-marker/web/worker and @image-marker/web/worker/invisible-watermark.js resolve to the packaged invisible-watermark Worker. Vite can resolve it with import workerUrl from '@image-marker/web/worker?url'.
import { ImageMarkerEditorController } from '@image-marker/web/headless';
import { createWebEditorAdapter } from '@image-marker/web/editor-adapter';

const controller = new ImageMarkerEditorController({
  document: { schemaVersion: 2, layers, output: { saveFormat: 'png' } },
});
const adapter = createWebEditorAdapter(1024);
const preview = await adapter.renderPreview({
  recipe: controller.exportRecipe(),
  input: { backgroundImage: { src: file } },
});

Cancellation and ownership

Pass an AbortSignal to Recipe jobs or Worker detection. Abort stops queued and cooperative work; synchronous Canvas work already in progress may only be discarded when it returns. A host that needs immediate CPU termination must stop the Worker or task it owns. Promise timeouts and ignoring late values do not stop work. Revoke object URLs and dispose controllers/listeners when their UI or task ends.

For a Tauri or other isolated host, use createWebMarker(options?) to inject resources (createImage, createCanvas, object-URL cleanup, and byte reads) and an execution adapter. execution.start() returns the real task promise plus optional terminate/cancel and dispose hooks. marker.cancel() and marker.dispose() wait for the host acknowledgement; a timeout or ignored late value is not termination. Inspect marker.capabilities to distinguish cooperative Worker detection from default DOM work that requires host termination.

Create Recipes from that instance when its cancellation boundary should include the Recipe task:

import { createWebMarker } from '@image-marker/web';

const marker = createWebMarker();
const recipe = marker.createRecipe(recipeDocument, { resultType: 'blob' });
const pending = recipe.apply(input, { signal: abortController.signal });
const completion = pending.catch(() => undefined);
abortController.abort();
await marker.cancel();
await completion;
await marker.dispose();

The packaged Worker handles invisible watermark detection only. It is not a general Canvas image engine. Remote URLs remain supported when the remote server allows CORS; local File and Blob inputs are recommended for desktop apps. C2PA is an optional integration boundary and is not installed by this package.

See the Web SDK guide and the runnable Vite example.