patent
A prior-art search for your code ideas. Stop building what already exists — find the state of the art in seconds, without leaving the terminal.
Give patent a plain-English dev-tool idea and it searches 11 open-source
registries — crates.io, npm, PyPI, GitHub, Docker Hub, and more — ranks the
matches with local semantic search, and writes an honest verdict on whether the
space is Open, Crowded, or Saturated. Everything runs on your
machine.
Like a patent search, but for code. A patent search finds prior art — it never certifies absence. Neither does this.
Why
- Prevent wasted effort — find out something already exists before you spend a month rebuilding it.
- Find inspiration & benchmarks — see the closest prior art, ranked, so you know exactly what you'd have to beat.
- Competitive analysis — survey an entire ecosystem in one command instead of tab-hopping across a dozen registries.
Quick demo
# A crowded space — lots of prior art, ranked by relevance
# Pipe structured output into your own tooling
|
# Skip the AI verdict for an instant, search-only result
Features
- Search the entire developer ecosystem at once — 11 registries (crates.io, npm, PyPI, GitHub, Go, Maven, NuGet, RubyGems, Docker Hub, VS Code Marketplace, Hacker News) in a single command.
- It searches the right places automatically — mention "rust" and it hits crates.io; mention "docker" and it hits Docker Hub. GitHub and Hacker News (both language-agnostic) are always searched; with no language signal it falls back to a broad sweep across the largest registries.
- Relevance you can trust — local embeddings (AllMiniLM-L6-V2 via fastembed) rank every match by cosine similarity to your idea, so the closest prior art floats to the top.
- An honest verdict, not hype — a local Ollama model
(or any OpenAI-compatible API via
--api-base) classifies the space as Open / Crowded / Saturated and names the gaps you could fill. It can prove something exists; it never claims something doesn't. - Instant mode —
--fastskips the LLM and gives you the ranked list immediately, with a saturation level derived straight from the similarity data. - See it, don't parse it — an interactive TUI with scrollable, filterable,
sortable matches, a detail popup for any result, mouse support, and one-key
URL opening. Need machine output?
--json. - Local-first & private — embeddings always run on your machine, and the
verdict uses a local LLM by default; point
--api-baseat a cloud API only if you want to. - Never fails loud — LLM down, model not pulled, or a cloud API rejecting the request? Results still render, ranked by similarity, without an AI verdict. A source fails? It's skipped (and shown as "not reached"), never fatal.
Install
From crates.io
From source
Prerequisites
Rust (stable 1.80+) via rustup.
Ollama (optional, recommended) — powers the AI verdict. Skip it and use
--fast, or just let patent fall back to a similarity-only verdict:
# macOS
# Linux
|
# Windows (or download the installer from https://ollama.com/download)
# Then (any platform):
Cloud or OpenAI-compatible API (alternative to Ollama) — point patent at
any server that speaks the OpenAI chat API with --api-base, plus --api-key
(or the OPENAI_API_KEY env var):
# OpenAI
# OpenRouter
# Local LM Studio / llama.cpp / vLLM (usually no key needed)
GitHub token (optional) — the unauthenticated GitHub search API is limited to 10 requests/minute. Set a token to raise that to 30 requests/minute (3×):
# macOS / Linux
# Windows (PowerShell)
$env:GITHUB_TOKEN = "ghp_your_token_here"
First run — patent downloads a small (~80 MB) embedding model the first
time it ranks results. You'll see a one-time downloading the embedding model…
notice. It's cached under your OS cache directory (e.g. ~/Library/Caches/patent
on macOS, ~/.cache/patent on Linux, %LOCALAPPDATA%\patent on Windows), so
it's a one-time download shared across every directory you run from.
Usage
# Basic search — opens the interactive TUI
# Instant, search-only result — no model warm-up, no inference wait
# Structured JSON output for scripting
|
# Use a smaller/faster Ollama model
# Use a cloud LLM instead of local Ollama
# Keep more matches after ranking
Options
| Flag | Description | Default |
|---|---|---|
--fast |
Skip the LLM verdict for an instant, search-only result | — |
--json |
Print JSON to stdout instead of the TUI | — |
--model <MODEL> |
LLM model for the verdict | qwen2.5 (Ollama) |
--api-base <URL> |
Use an OpenAI-compatible API (base URL ending in /v1) instead of Ollama |
— |
--api-key <KEY> |
API key for --api-base (or set OPENAI_API_KEY) |
— |
--limit <N> |
Max matches to keep after ranking | 50 |
--completions <SHELL> |
Generate shell completions and exit | — |
Shell completions
# Bash
# Zsh
# Fish
# PowerShell
TUI keybindings
| Key | Action |
|---|---|
↑ / k |
Scroll up |
↓ / j |
Scroll down |
g / Home |
Jump to top |
G / End |
Jump to bottom |
/ |
Filter matches |
s |
Cycle sort (similarity / popularity / name) |
m |
Show more / show less |
Enter |
Show match details (full description, popularity, URL) |
o |
Open selected match in browser |
? |
Help overlay |
q |
Quit |
The mouse works too — scroll with the wheel, click a row to select it. Press
? inside the TUI for the full keybinding reference.
How it works
idea ──► parse keywords
│
├──► fan out to sources (concurrent, with retry)
│ │
│ ▼
│ dedup matches
│ │
▼ ▼
load model ──► rank by cosine similarity
│
▼
verdict via LLM
│
▼
TUI or JSON
- Parse — extracts keywords, selects relevant sources based on the idea
- Search — fans out to selected sources concurrently; a failing source is skipped and retried once, never fatal
- Rank — embeds the idea and each match description with AllMiniLM-L6-V2, sorts by cosine similarity, keeps the top N
- Verdict — sends the ranked matches to an LLM (local Ollama by default, or
an OpenAI-compatible API via
--api-base) that classifies the space and identifies gaps (or, with--fast, derives the level straight from the similarity data) - Output — interactive TUI (default) or structured JSON (
--json)
The embedding model loads concurrently with source searches, so the model-load latency is hidden behind network I/O.
The integrity rule
patent can prove something exists. It can never prove something
doesn't — it only searched some sources. Every verdict is scoped to "what was
found in the sources checked," and a clean result means keep looking, not
start building.
The sources-checked list is always displayed for transparency, and sources that were selected but failed to respond are surfaced as "not reached" — so a thin result is never mistaken for "nothing out there."
Architecture
src/
├── lib.rs # library root
├── model.rs # Query, Match, Source, Verdict, Saturation
├── sources/
│ ├── mod.rs # trait Source, search_all fan-out, dedup, retry
│ ├── crates_io.rs # crates.io API
│ ├── github.rs # GitHub search API
│ ├── npm.rs # npm registry API
│ ├── pypi.rs # PyPI search (HTML scraping)
│ ├── hacker_news.rs # HN Algolia API
│ ├── go.rs # Go package search
│ ├── maven.rs # Maven Central API
│ ├── nuget.rs # NuGet API
│ ├── rubygems.rs # RubyGems API
│ ├── docker_hub.rs # Docker Hub API
│ └── vscode.rs # VS Code Marketplace API
├── rank.rs # fastembed embeddings + cosine similarity
├── verdict.rs # LLM prompt + response parsing
├── llm.rs # trait Llm (verdict backend interface)
├── ollama.rs # Llm impl: native Ollama client
├── openai.rs # Llm impl: OpenAI-compatible chat client
└── tui.rs # TUI state machine
src/bin/patent/
├── main.rs # CLI entry point, pipeline wiring
├── cli.rs # clap argument parsing
└── tui.rs # ratatui rendering + event loop
Lib/bin split: the testable core is the library; the binary is a thin CLI/TUI shell.
Development
The README demo GIF is generated with vhs:
Adding a new source
- Create
src/sources/your_source.rsimplementing theSourceAdaptertrait - Add the variant to
Sourceinsrc/model.rs - Register it in
sources::build_sourceandsources::detect_sources - Add wiremock integration tests in
tests/sources.rs
License
Licensed under either of MIT or Apache-2.0 at your option.