Skip to content
Code Recycle

Component · for humans & their agents

Reverse Image Search

basic checks · first-partyactively maintained$0 during beta (was $29)

Reverse image search that works without a paid key — and tells you when it fell back to the free lane.

by voxpop · Code Recycle maintainer

Get it free — beta

Every claim on this page is refundable if it is untrue — refund policy.

Verified: 8 tests · 6/6 mutations caught

| lane | cost | needs | |---|---|---| | `keylessWebProvider()` | **$0** | nothing — public HTML search, works on serverless | | `describeAndSearchProvider()` | your own stack | inject a vision "describe" fn + a web-search fn | | `serpApiLensProvider({ apiKey })` | paid | a SerpApi key — true pixel match |

Three lanes, none of them required

| lane | cost | needs | |---|---|---| | `keylessWebProvider()` | $0 | nothing — public HTML search, works on serverless | | `describeAndSearchProvider()` | your own stack | inject a vision "describe" fn + a web-search fn | | `serpApiLensProvider({ apiKey })` | paid | a SerpApi key — true pixel match |

```ts
const search = createReverseImageSearch([
  serpApiLensProvider({ apiKey: process.env.SERPAPI_KEY }), // skipped if unconfigured
  keylessWebProvider(),
]);

const result = await search.search({ imageUrl: "https://example.com/photo.jpg" }); // { provider: "keyless-web", matches: [...], degraded: true, note: "Used a free fallback lane." } ```

`degraded` is the point

A result that came from the free fallback — because your paid lane was unconfigured, could not serve the input, or found nothing — is marked as such. A search layer that quietly downgrades and reports success is how you end up trusting a weaker answer than you think you have.

And `unavailable` is not "no matches": nothing configured returns `unavailable: true`, never an empty match list. Otherwise a caller reads "no matches" and concludes the image is unique when nothing was ever searched.

A real bug this shipped WITH a fix for

The original module promised "everything fails soft: a provider that errors yields an empty result, never throws." That was false, and mutation testing during extraction found it.

Every built-in provider guarded its own fetch, which is what made it look true — but the orchestrator never guarded the providers, and a caller's injected provider has promised nothing. One throwing lane went straight through `search()` and past every fallback behind it, in exactly the configuration the pluggable design exists to serve.

Fixed, and pinned by test: a throwing provider is treated as a lane that returned nothing — fall through, and mark the result degraded.

Two further defects the suite did not catch, both core to the fallback chain: a provider that cannot serve an input (a URL-only lane handed a `data:` URL) must be skipped, not called, and an empty result must fall through rather than end the search — treating `[]` as final makes every fallback lane behind it unreachable.

Zero dependencies, verified by inspection

No imports at all. No env, no auth, no framework coupling — every dependency (a key, a vision fn, a web-search fn) is injected by the caller. A copy-paste is the whole install.

What it is for, and what it is not

For: provenance and listing verification — is this product image, artwork, or listing photo already published somewhere else, and is a seller reusing a photo from another listing?

Not a people-search or face-search tool, and it does not contain one. It is a thin orchestration layer over public search, adding no capability a public search box does not already give you; what it adds is fallback ordering, honest degradation reporting, and a pluggable provider seam. Whether an image depicts a person is not reliably determinable, and adding face detection to gate it would be both unreliable and a worse privacy intrusion than the thing it guarded — so that boundary is stated rather than enforced. Use it on assets, and observe the terms of whichever provider you configure.

Proof

8 tests, 6/6 deliberate defects caught.

Delivery

Source delivered as a private repository invite within 24 hours of purchase. Single-product commercial license: use and modify in any number of products; no redistribution or resale of the source.

Interface

What you call, and what comes back. Types and signatures only — the implementation ships with the source.

  export function keylessWebProvider(): ReverseImageProvider;
  export async function ddgSearch( query: string, limit: number, signal?: AbortSignal, ): Promise<ReverseImageMatch[]>;
  export function createReverseImageSearch(providers: ReverseImageProvider[]): ReverseImageSearch;
  export type DescribeFn = (input: { imageUrl?: string;

01Capabilities

Does

  • + Brand asset generation
  • + Search
  • + Content provenance

Doesn’t

  • No exclusions declared

02Requirements & stack

Depends on

No declared dependencies

Credentials needed

None declared

Stack

typescript

03Community

No endorsements yet

No verified confirmations yet — be the first.

Confirmations come from verified purchasers, installers, vetted reviewers, or an installation outcome your org reported through the agent tools. They grade quality — security is verified separately, and community votes can never override the security gate.

Open an issue

Sign in to confirm — weight comes from verified usage, not vote count.

0 open · 0 answered · 0 fixed · 1 said it worked

04Trust Passport

Full passport →
–/100

0/0 automated components pass. An automated score is never a security guarantee.

✓ Basic checks · first-partyreviewed Sep 20, 2026 · re-verification due Dec 19, 2026
  • publisher identity Publisher status verified; 1 verification(s) on file
  • malicious pattern scan No known malicious-behavior patterns across 8 source file(s) plus listing text
  • capability contract 3 undeclared (0 credential-class): serpapi.com, html.duckduckgo.com, duckduckgo.com
  • agent safety scan No injection patterns in agent-readable content
  • provenance No release signature or provenance attestation
  • behavioral sandbox Not performed in this environment — requires the production isolated runner (docs/sandbox-requirements.md). No untrusted code is ever executed on the application host.

Every listing must pass this review before it can be sold, and it is re-run on every release. Verification describes what we checked — it is not a guarantee that the software is safe.

VersionChannelReleasedNotes
1.0.0stableAug 10, 2026First public release.