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

ai-image-detector

v1.0.1

Published

Detect and verify AI-generated images — check C2PA, SynthID, OpenAI DALL-E, Adobe Firefly, Google Gemini, and Stability AI provenance through a single unified API

Readme

ai-image-detector

Detect & Verify AI-Generated Images — C2PA, SynthID, DALL-E, Firefly, Gemini, Stable Diffusion

npm version CI License: MIT Node.js TypeScript

A single npm package that detects and verifies AI-generated images across all major AI image generators — C2PA, SynthID, OpenAI DALL-E, Adobe Firefly, Google Gemini/Imagen, and Stable Diffusion — through one unified API.

⚠️ ai-image-detector does NOT attempt to visually detect AI-generated images.
It only verifies official provenance evidence — metadata, Content Credentials, watermarks, and cryptographic signatures embedded by AI providers themselves.


Why ai-image-detector?

Before this package, you needed multiple provider-specific integrations:

// ❌ Before
import providerA from "some-c2pa-library";
import providerB from "some-openai-metadata-tool";
import providerC from "custom-stable-diffusion-parser";

With ai-image-detector:

// ✅ After
import { verifyImage, verifyC2PA, verifyOpenAI } from "ai-image-detector";

Installation

npm install ai-image-detector
yarn add ai-image-detector
pnpm add ai-image-detector

Requirements: Node.js ≥ 20, ESM or CJS project.


Quick Start

import { verifyImage } from "ai-image-detector";

const result = await verifyImage("./photo.png");

console.log(result.verified);    // true / false
console.log(result.confidence);  // 0 – 1
console.log(result.providers);   // ["Stability AI", "Metadata"]

Example output

{
  "verified": true,
  "confidence": 0.9625,
  "providers": ["Stability AI", "Metadata"],
  "checks": {
    "metadata": { "passed": true, "message": "Found AI-related PNG metadata chunks: parameters", "confidence": 0.85 },
    "stabilityAI": { "passed": true, "message": "Stable Diffusion PNG parameter chunk found: key=\"parameters\"", "confidence": 0.97 }
  },
  "providerResults": [ ... ],
  "verifiedAt": "2025-01-15T10:30:00.000Z"
}

CLI

npx ai-image-detector photo.png
npx ai-image-detector photo.png --verbose
npx ai-image-detector photo.png --json
npx ai-image-detector https://example.com/image.jpg

CLI output

  ╔══════════════════════════════════════╗
  ║   ai-image-detector  •  v1.0.1       ║
  ╚══════════════════════════════════════╝

  ✓ PROVENANCE VERIFIED  via Stability AI, Metadata

  Confidence   ████████████████░░░░ 94%
  Providers    Stability AI · Metadata
  Verified At  1/15/2025, 10:30:00 AM

  Checks
  ────────────────────────────────────────────
  ✓ metadata (85%)
     Found AI-related PNG metadata chunks: parameters
  ✓ stabilityAI (97%)
     Stable Diffusion PNG parameter chunk found

CLI options

| Option | Description | |--------|-------------| | --json | Machine-readable JSON output | | --verbose | Full per-provider check breakdown | | --providers <names> | Comma-separated provider list | | --timeout <ms> | Provider timeout (default: 10 000) | | --metadata | Run only the Metadata provider | | --c2pa | Run only the C2PA provider | | --synthid | Run only the SynthID provider | | --openai | Run only the OpenAI provider | | --adobe | Run only the Adobe provider | | --gemini | Run only the Gemini provider | | --stability | Run only the Stability AI provider | | --openai-key <key> | OpenAI API key | | --adobe-client <id> | Adobe I/O client ID | | --adobe-token <token> | Adobe I/O access token | | --gemini-key <key> | Google Cloud API key | | --synthid-key <key> | SynthID API key | | --help | Show usage | | --version | Show version |


API Reference

verifyImage(image, options?)

Runs all registered providers and returns an aggregated result.

import { verifyImage } from "ai-image-detector";

const result = await verifyImage("./image.png", {
  providers: ["OpenAI", "Adobe"],  // optional: run subset
  timeout: 15_000,                  // optional: ms per provider
  parallel: true,                   // optional: default true
  includeMetadata: true,            // optional: default true
});

Input: string (path or URL), Buffer, Uint8Array, or URL


Individual Verification Methods

Run a single provider and get its result directly:

import {
  verifyMetadata,
  verifyC2PA,
  verifySynthID,
  verifyOpenAI,
  verifyAdobe,
  verifyGemini,
  verifyStabilityAI,
} from "ai-image-detector";

// Metadata (EXIF / XMP / PNG chunks)
const metadata = await verifyMetadata("./image.png");

// C2PA Content Credentials
const c2pa = await verifyC2PA("./image.jpg");

// Google SynthID
const synthid = await verifySynthID("./image.jpg", {
  apiKey: "your-google-cloud-api-key",
  projectId: "your-project-id",
});

// OpenAI DALL-E
const openai = await verifyOpenAI("./image.png", {
  apiKey: "sk-...",
});

// Adobe Firefly
const adobe = await verifyAdobe("./image.jpg", {
  clientId: "your-adobe-client-id",
  accessToken: "your-adobe-token",
});

// Google Gemini / Imagen
const gemini = await verifyGemini("./image.png", {
  apiKey: "your-google-api-key",
  projectId: "your-project-id",
});

// Stable Diffusion / Stability AI
const stability = await verifyStabilityAI("./image.png");

Provider Coverage

| Provider | Metadata | C2PA | Watermark | API Verification | |----------|----------|------|-----------|-----------------| | Metadata | ✅ EXIF/XMP/PNG/IPTC | — | — | — | | C2PA | — | ✅ JUMBF + Claims | — | ✅ optional c2pa-node | | SynthID | ✅ XMP/EXIF | — | 🔜 when API released | 🔜 Google API | | OpenAI | ✅ EXIF/XMP/PNG | ✅ DALL-E 3 C2PA | — | 🔜 when released | | Adobe | ✅ EXIF/XMP | ✅ Firefly C2PA | — | ✅ Adobe I/O API | | Gemini | ✅ EXIF/XMP/IPTC | ✅ C2PA actions | 🔜 SynthID co-proof | 🔜 Vertex AI API | | Stability AI | ✅ EXIF | — | — | ✅ PNG param chunks |


TypeScript Interfaces

interface VerificationResult {
  verified: boolean;
  confidence: number;          // 0 – 1
  providers: string[];

  checks: {
    metadata?: CheckResult;
    c2pa?: CheckResult;
    synthid?: CheckResult;
    openai?: CheckResult;
    adobe?: CheckResult;
    gemini?: CheckResult;
    stabilityAI?: CheckResult;
    [key: string]: CheckResult | undefined;
  };

  providerResults: ProviderResult[];
  metadata?: Record<string, unknown>;
  verifiedAt: string;          // ISO-8601
}

interface ProviderResult {
  provider: string;
  verified: boolean;
  confidence: number;
  checks: Record<string, CheckResult>;
  metadata?: Record<string, unknown>;
  verifiedAt: string;
  warnings?: string[];
  error?: string;
}

interface CheckResult {
  passed: boolean;
  message: string;
  confidence?: number;
  severity?: "info" | "warning" | "error";
  details?: Record<string, unknown>;
}

Plugin System

Extend ai-image-detector with your own provider — no core modification needed.

import { registerProvider, verifyImage } from "ai-image-detector";
import type { ProvenanceProvider, ProviderResult, ImageInput } from "ai-image-detector";

class MidjourneyProvider implements ProvenanceProvider {
  readonly name = "Midjourney";

  async verify(image: ImageInput): Promise<ProviderResult> {
    // Your verification logic here
    const buffer = /* load image */;
    const hasMjMeta = buffer.includes(Buffer.from("Midjourney"));

    return {
      provider: this.name,
      verified: hasMjMeta,
      confidence: hasMjMeta ? 0.9 : 0,
      checks: {
        midjourney_meta: {
          passed: hasMjMeta,
          message: hasMjMeta ? "Midjourney metadata found" : "No Midjourney metadata",
        },
      },
      verifiedAt: new Date().toISOString(),
    };
  }
}

// Register once at startup
registerProvider(new MidjourneyProvider());

// Now included in verifyImage automatically
const result = await verifyImage("./image.png");

What Each Provider Checks

Metadata Provider

Scans EXIF, XMP, IPTC, and PNG tEXt/iTXt chunks for AI generation evidence:

  • EXIF Software field (e.g. "Stable Diffusion", "DALL-E", "Adobe Firefly")
  • XMP xmp:CreatorTool namespace
  • EXIF UserComment / ImageDescription with prompt-like content
  • PNG parameters / workflow / prompt text chunks

C2PA Provider

Verifies C2PA Content Credentials (the Coalition for Content Provenance and Authenticity standard):

  • JUMBF box detection in JPEG APP11 / PNG caBX / WebP
  • C2PA label validation ("c2pa" inside JUMBF superbox)
  • Claim signature block presence (ES256, ES384, etc.)
  • AI generation action assertions (c2pa.ai.generatedContent, com.adobe.firefly.generated)
  • XMP-based C2PA provenance reference
  • Optional c2pa-node native full validation (install separately)

SynthID Provider

Checks for Google SynthID evidence:

  • SynthID XMP field detection
  • Google AI EXIF software hints
  • IPTC source field scanning
  • Official Google Cloud API (when credentials provided)

OpenAI Provider

Checks for DALL-E provenance:

  • EXIF Software = "DALL-E" / "OpenAI DALL-E 3"
  • OpenAI XMP namespace fields
  • C2PA action com.openai.generated (DALL-E 3 always includes C2PA)
  • PNG metadata chunks from the OpenAI API response
  • Optional OpenAI provenance API

Adobe Provider

Checks for Adobe Firefly and Photoshop Generative Fill provenance:

  • EXIF Software = "Adobe Firefly"
  • Adobe XMP namespaces (photoshop:, xmpMM:, Iptc4xmpExt:)
  • C2PA action com.adobe.firefly.generated
  • contentcredentials.org origin marker
  • Optional Adobe I/O Content Authenticity API

Gemini Provider

Checks for Google Gemini / Imagen provenance:

  • EXIF / binary Google AI software hints
  • Google XMP namespace fields
  • C2PA Google action assertions
  • IPTC source field
  • SynthID co-presence (expected for Gemini images)
  • Optional Vertex AI API

Stability AI Provider

Checks for Stable Diffusion provenance (the richest metadata of any AI generator):

  • PNG parameters tEXt chunk (AUTOMATIC1111/InvokeAI/Fooocus format)
  • PNG workflow tEXt chunk (ComfyUI JSON format)
  • EXIF Software field (many SD frontends write this)
  • Parsed AUTOMATIC1111 parameter extraction (prompt, seed, model, steps, etc.)
  • Stability AI XMP fields

Advanced Usage

Parallel vs Sequential

// Parallel (default) — fastest
const result = await verifyImage(image, { parallel: true });

// Sequential — useful for debugging
const result = await verifyImage(image, { parallel: false });

Stream / Buffer

import { readFile } from "fs/promises";

const buffer = await readFile("./image.png");
const result = await verifyImage(buffer);

From URL

const result = await verifyImage("https://example.com/photo.jpg");

Custom Timeout

const result = await verifyImage(image, { timeout: 5_000 });

Per-provider Options

const result = await verifyImage(image, {
  providerOptions: {
    SynthID: { apiKey: "gcloud-key", projectId: "my-project" },
    Adobe:   { clientId: "adobe-id", accessToken: "adobe-token" },
    OpenAI:  { apiKey: "sk-..." },
  },
});

Exit Code Integration (CI)

npx ai-image-detector image.png --providers openai,adobe || echo "No provenance found"
# Exit code 0 = verified, 1 = not verified / error

Confidence Scoring

| Score | Meaning | |-------|---------| | 0.90 – 1.00 | Strong evidence — cryptographic signature or authoritative API confirmation | | 0.75 – 0.89 | High confidence — multiple independent signals agree | | 0.50 – 0.74 | Moderate — one clear signal but no cryptographic proof | | 0.00 – 0.49 | Low — weak hints only or conflicting signals | | 0.00 | No provenance evidence found |

The final confidence in VerificationResult is the weighted mean of all successful providers' confidence scores.


License

MIT — Copyright © 2025 ai-image-detector contributors