// Research Hex packages (Sobelow, Phoenix, Ecto, Credo, Ash, etc). Use when investigating packages, understanding integration patterns, or finding module/function docs and usage examples. Automatically fetches missing documentation and source code locally.
| name | hex-docs-search |
| description | Research Hex packages (Sobelow, Phoenix, Ecto, Credo, Ash, etc). Use when investigating packages, understanding integration patterns, or finding module/function docs and usage examples. Automatically fetches missing documentation and source code locally. |
| allowed-tools | Read, Grep, Glob, Bash, WebSearch, AskUserQuestion |
Comprehensive search for Elixir and Erlang package documentation, following a cascading strategy to find the most relevant and context-aware information.
Use this skill when you need to:
This skill implements a cascading search that prioritizes local and contextual information:
deps/ directory (both source code AND generated docs).hex-docs/ and .hex-packages/Extract the package name and optionally the module or function name from the user's question.
Examples:
phoenix_live_view, Module: Phoenix.LiveViewecto, Module: Ecto.Queryjason, Module: Jason, Function: decode!Use the Glob and Grep tools to search the deps/ directory for BOTH code and documentation:
Find the package directory:
Use Glob: pattern="deps/<package_name>/**/*.ex"
If no results, the package isn't installed locally. Skip to Step 4.
Search for module definition in source code:
Use Grep: pattern="defmodule <ModuleName>", path="deps/<package_name>/lib"
Search for function definition in source code (if looking for specific function):
Use Grep: pattern="def <function_name>", path="deps/<package_name>/lib", output_mode="content", -A=5
Find documentation in source code (@moduledoc/@doc annotations):
Use Grep: pattern="@moduledoc|@doc", path="deps/<package_name>/lib", output_mode="content", -A=10
Check for generated HTML documentation (if available):
Use Glob: pattern="deps/<package_name>/doc/**/*.html"
If HTML docs exist, search them for relevant content:
Use Grep: pattern="<ModuleName>|<function_name>", path="deps/<package_name>/doc"
Read the relevant files using the Read tool to get full context from either source or HTML docs.
If the package wasn't found in deps/, check for previously fetched documentation or source code, or fetch it now.
Use the Glob tool to check if documentation was previously fetched:
Use Glob: pattern=".hex-docs/docs/hexpm/<package_name>/*/*.html"
If found, search the fetched documentation using the same patterns as Step 2 (sections 5 and 6).
Use the Glob tool to check if source code was previously fetched:
Use Glob: pattern=".hex-packages/<package_name>-*/**/*.ex"
If found, search the fetched source using the same patterns as Step 2 (sections 2-4).
If no cached docs or source found, determine which version to fetch:
Check mix.lock for locked version:
Use Bash: grep '"<package_name>"' mix.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'
Check mix.exs for version constraint:
Use Bash: grep -E '\{:<package_name>' mix.exs | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'
Get latest version from hex.pm:
Use Bash: curl -s "https://hex.pm/api/packages/<package_name>" | jq -r '.releases[0].version'
If version ambiguous, use AskUserQuestion to prompt:
Question: "Package '<package_name>' not found locally. Which version would you like to fetch?"
Options:
- "Latest (X.Y.Z)" - Fetch most recent release
- "Project version (X.Y.Z)" - Use version from mix.exs/mix.lock (if available)
- "Specific version" - User provides custom version in "Other" field
- "Skip fetching" - Continue to HexDocs API search without fetching
Once version is determined, fetch documentation to project-local cache:
# Use custom HEX_HOME to store in project directory
HEX_HOME=.hex-docs mix hex.docs fetch <package_name> <version>
Storage location: .hex-docs/docs/hexpm/<package_name>/<version>/
If successful:
If documentation fetch fails (package has no docs) or docs lack sufficient detail:
If documentation is insufficient or unavailable, fetch package source code:
# Fetch and unpack to project-local directory
mix hex.package fetch <package_name> <version> --unpack --output .hex-packages/<package_name>-<version>
Storage location: .hex-packages/<package_name>-<version>/
If successful:
If source fetch fails:
Inform the user that fetched content should be git-ignored. Suggest adding to .gitignore:
# Fetched Hex documentation and packages
/.hex-docs/
/.hex-packages/
This only needs to be mentioned once per session, and only if fetching actually occurred.
Use the Grep tool to find usage patterns in the current project:
Find imports and aliases:
Use Grep: pattern="alias <ModuleName>|import <ModuleName>", path="lib", output_mode="content", -n=true
Find function calls:
Use Grep: pattern="<ModuleName>\.", path="lib", output_mode="content", -A=3
Search test files for examples:
Use Grep: pattern="<ModuleName>", path="test", output_mode="content", -A=5
This provides real-world usage examples from the current project, which is often the most helpful context.
If local search doesn't provide sufficient information, use the Bash tool to search the HexDocs search API.
Full-text search across documentation:
# Search across all packages
curl -s "https://search.hexdocs.pm/?q=<query>&query_by=doc,title" | jq -r '.found, .hits[0:5][] | .document | "\(.package) - \(.title)\n\(.doc)\n---"'
# Search within a specific package (get version first)
VERSION=$(curl -s "https://hex.pm/api/packages/<package_name>" | jq -r '.releases[0].version')
curl -s "https://search.hexdocs.pm/?q=<query>&query_by=doc,title&filter_by=package:=[<package>-$VERSION]" | jq -r '.hits[] | .document | "\(.title)\n\(.doc)\nURL: https://hexdocs.pm\(.url)\n---"'
Examples:
# Search for "mount" in phoenix_live_view
VERSION=$(curl -s "https://hex.pm/api/packages/phoenix_live_view" | jq -r '.releases[0].version')
curl -s "https://search.hexdocs.pm/?q=mount&query_by=doc,title&filter_by=package:=[phoenix_live_view-$VERSION]" | jq -r '.hits[0:3][] | .document | "\(.title)\n\(.doc)\n---"'
# General search for Ecto.Query
curl -s "https://search.hexdocs.pm/?q=Ecto.Query&query_by=doc,title" | jq -r '.hits[0:5][] | .document | "\(.package) - \(.title)\n\(.doc)\n"'
API Response structure:
found: Total number of resultshits[]: Array of results with:
document.package: Package namedocument.ref: Versiondocument.title: Function/module namedocument.doc: Documentation textdocument.url: Path to docs (append to https://hexdocs.pm)Requirements: curl and jq (available on Linux/Mac, use Git Bash or WSL on Windows)
If the above steps don't provide sufficient information, use the WebSearch tool:
First try searching hexdocs.pm specifically:
Use WebSearch: query="site:hexdocs.pm <package_name> <module_or_function>"
If that doesn't help, do a general search:
Use WebSearch: query="elixir <package_name> <module_or_function> documentation examples"
When presenting results, organize them as follows:
Found <package_name> in local dependencies:
**Location**: deps/<package_name>
**Version**: <version from mix.lock>
**Documentation**:
<relevant documentation or code snippets>
**Usage in this project**:
<usage examples from codebase>
Found <package_name> on HexDocs:
**Package**: <package_name>
**Latest version**: <version>
**Documentation**: https://hexdocs.pm/<package_name>/<version>/<Module>.html
<summary of key information>
Searching web for <package_name> documentation:
<summary of web search results>
User asks: "How do I use Phoenix.LiveView mount/3?"
Search process:
deps/phoenix_live_view/ existsdef mount in deps/phoenix_live_view/lib/ (source code)@doc annotation for mount/3 from sourcedeps/phoenix_live_view/doc/ and read if availablemount implementations in lib/*/live/*.ex (usage examples)User asks: "Show me Ecto.Query examples"
Search process:
deps/ecto/ for source codeimport Ecto.Querylib/*/queries/*.ex or lib/*_context.excurl -s "https://search.hexdocs.pm/?q=Ecto.Query&query_by=doc,title" | jq '.hits[0:3]'
User asks: "How do I use the Timex library?"
Search process:
deps/timex/ (not found).hex-docs/docs/hexpm/timex/ (not found).hex-packages/timex-*/ (not found)curl -s "https://hex.pm/api/packages/timex" | jq -r '.releases[0].version'
# Returns: 3.7.11
HEX_HOME=.hex-docs mix hex.docs fetch timex 3.7.11
# Stores in: .hex-docs/docs/hexpm/timex/3.7.11/
mix hex.package fetch timex 3.7.11 --unpack --output .hex-packages/timex-3.7.11
Future queries: Documentation and source cached locally for instant offline access
User asks: "Show me Phoenix.LiveView.mount/3 again"
Search process:
deps/phoenix_live_view/ (not found).hex-docs/docs/hexpm/phoenix_live_view/ (found version 0.20.0!).hex-docs/docs/hexpm/phoenix_live_view/0.20.0/Phoenix.LiveView.htmlResult: Fast, offline search without network requests. Works even when disconnected.
User asks: "Show me the implementation of Jason.decode!/2"
Search process:
deps/jason/ (not found).hex-docs/docs/hexpm/jason/ (not found){:jason, "~> 1.4"}HEX_HOME=.hex-docs mix hex.docs fetch jason 1.4.4
mix hex.package fetch jason 1.4.4 --unpack --output .hex-packages/jason-1.4.4
.hex-packages/jason-1.4.4/lib/jason.exResult: Both docs and source cached for comprehensive future queries
Use Claude's built-in tools in this order:
Requirements: curl and jq (Linux/Mac native, use Git Bash or WSL on Windows)
.hex-docs/ and .hex-packages/ before fetching.hex-docs/ and .hex-packages/ for previously fetched contentmix deps.get if it should be a project dependencyDocumentation fetch fails:
Source fetch fails:
Fetched content not found on repeat queries:
.hex-docs/ and .hex-packages/ directories existsite:hexdocs.pm filter