{"id":49960155,"url":"https://github.com/elixir-vibe/exograph","last_synced_at":"2026-05-18T02:01:29.412Z","repository":{"id":356334442,"uuid":"1230638734","full_name":"elixir-vibe/exograph","owner":"elixir-vibe","description":"Structural Elixir code intelligence and search powered by ExAST, Reach, Ecto, and Postgres/ParadeDB","archived":false,"fork":false,"pushed_at":"2026-05-14T17:25:35.000Z","size":274,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-14T18:04:40.507Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elixir-vibe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T07:20:21.000Z","updated_at":"2026-05-14T17:25:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/elixir-vibe/exograph","commit_stats":null,"previous_names":["elixir-vibe/exograph"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elixir-vibe/exograph","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-vibe%2Fexograph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-vibe%2Fexograph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-vibe%2Fexograph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-vibe%2Fexograph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elixir-vibe","download_url":"https://codeload.github.com/elixir-vibe/exograph/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-vibe%2Fexograph/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33149519,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-18T02:01:28.178Z","updated_at":"2026-05-18T02:01:29.407Z","avatar_url":"https://github.com/elixir-vibe.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exograph\n\nLocal CodeQL-style code search for Elixir, backed by Postgres and ExAST.\n\nExograph indexes Elixir source code into normalized Ecto/Postgres tables: files,\nAST fragments, comments, definitions, references, package versions, and optional\nReach call graph facts. You can then query that index with structural AST\npatterns, text/regex search, symbol/reference filters, and Ecto-shaped joins.\n\n## What is Exograph?\n\nExograph is:\n\n- a library for indexing Elixir source code into Postgres\n- a set of Ecto schemas and migrations for normalized code facts\n- a structural search engine using ExAST for exact AST verification\n- an optional Reach-backed call graph index\n- a foundation for CodeQL-like Elixir queries over one project or many package versions\n\nExograph is not:\n\n- a hosted search service\n- a language server\n- a general multi-language analyzer\n- a replacement for ExAST or Reach\n\n## Why?\n\nUse Exograph when text search is not enough:\n\n- find functions matching an AST shape\n- search definitions and references across packages\n- ask \"which private functions call `Repo.transaction/1`?\"\n- index multiple Hex package versions into one database\n- combine relational filters with exact ExAST verification\n- persist Reach call graph facts for caller/callee queries\n\n## Installation\n\n```elixir\ndef deps do\n  [\n    {:exograph, \"~\u003e 0.7\"}\n  ]\nend\n```\n\nExograph requires Postgres. ParadeDB's `pg_search` extension is optional and\nenables BM25-backed text/code-fact retrieval.\n\n## Quickstart\n\nPoint Exograph at Elixir source and an Ecto repo:\n\n```elixir\n{:ok, index} =\n  Exograph.index(\"lib\",\n    repo: MyApp.Repo,\n    migrate?: true\n  )\n\n{:ok, hits} = Exograph.search(index, \"Repo.get!(_, _)\")\n```\n\nPostgres retrieves candidates by term index; ExAST verifies the structural match.\n\n## Index Hex.pm\n\nDownload and index packages directly from Hex.pm:\n\n    mix exograph.index.hex --mode latest --concurrency 8 --prefix hex\n\nModes: `latest` (one version per package), `top --limit 5000`, `all` (every version).\nResumes automatically — already-indexed packages are skipped.\n\nOn a full Hex.pm run: ~21k packages, 13.8M fragments, 35M references, ~34 GB, 28 minutes.\n\n## Web UI\n\nExograph includes an embedded web interface for exploring indexes:\n\n    mix exograph.web --prefix myindex --port 4200\n\nAdd `--web` to `mix exograph.index.hex` for a live progress dashboard while indexing runs.\n\nFeatures:\n- Monaco editor with Elixir syntax highlighting and autocompletion\n- Structural, text, and regex search modes\n- IDE-style error diagnostics\n- Collapsible results grouped by package with code previews\n- Hex.pm links on package names\n- Live progress dashboard at `/progress` during Hex.pm indexing\n\n## JSON API\n\nThe web server exposes a JSON API:\n\n    POST /api/search   — structural, text, or regex search\n    POST /api/query    — DSL query execution\n    GET  /api/packages — list indexed packages\n    GET  /api/stats    — index statistics\n\nCursor pagination via `cursor`/`next_cursor`. Rate limited (60 req/min).\n\n## Query with code facts\n\nUse `Exograph.DSL` to combine structural AST patterns with indexed code facts:\n\n```elixir\nimport Exograph.DSL\n\nquery =\n  from(f in Fragment,\n    join: r in assoc(f, :references),\n    where: r.qualified_name == \"Repo.transaction/1\",\n    where: matches(f, \"def _ do ... end\")\n  )\n\n{:ok, hits} = Exograph.all(index, query)\n```\n\nReach call graph facts can also be queried directly:\n\n```elixir\nExograph.search_callers(index, \"Repo.transaction/1\")\nExograph.search_callees(index, \"MyApp.Accounts.update_user/2\")\n```\n\n## How it compares\n\n| Tool | Scope | Storage | Query style | Elixir AST-aware? | Best for |\n|------|-------|---------|-------------|-------------------|----------|\n| `ripgrep` | local text search | none | regex/text | no | fast ad-hoc text search |\n| ExAST | structural AST matching | none/advisory terms | AST patterns/selectors | yes | exact search and patching |\n| Reach | dependence analysis | in-memory graph/reports | APIs / Mix tasks | yes | call/data/control-flow analysis |\n| CodeQL | semantic code analysis | CodeQL database | QL language | not first-class Elixir | security analysis at scale |\n| Sourcegraph | cross-repo search | external index | text/structural depending setup | not Elixir-specific | organization-wide search |\n| Exograph | Elixir code fact index | Postgres/ParadeDB | ExAST + Ecto-shaped DSL | yes | local/self-hosted Elixir code intelligence, 21k+ package indexing |\n\n## Features\n\n- ExAST-backed structural search with exact verification\n- normalized Ecto/Postgres storage for files, fragments, comments, definitions, references, packages, versions, and call edges\n- `mix exograph.index.hex` — streaming pipeline to index all of Hex.pm\n- package/version-scoped indexes for Hex or other source archives\n- text and regex search via `pg_trgm` GIN indexes (ParadeDB BM25 optional)\n- optional Reach call graph extraction\n- ExDNA-powered structural similarity\n- web UI with Monaco editor, live progress dashboard, and JSON API\n\n## Documentation\n\n| Guide | Content |\n|-------|---------|\n| [Getting Started](guides/getting-started.md) | Installation, Postgres setup, first index/search |\n| [Querying](guides/querying.md) | Structural, text, and regex search; planning/explain |\n| [DSL](guides/dsl.md) | `Exograph.DSL`, joins, selects, predicates |\n| [Code Facts](guides/code-facts.md) | Definitions, references, comments, typed hits |\n| [Call Graph](guides/call-graph.md) | Reach extraction, callers/callees, call edge DSL |\n| [Postgres and ParadeDB](guides/postgres-paradedb.md) | Storage backend, migrations, BM25, performance tuning |\n| [Package Indexing](guides/package-indexing.md) | Indexing Hex.pm and manual package archives |\n| [Mix Tasks](guides/mix-tasks.md) | CLI indexing, searching, web UI |\n| [Web UI](guides/web-ui.md) | Monaco editor, search modes, progress dashboard |\n| [API](guides/api.md) | JSON API endpoints, pagination, rate limiting |\n| [Comparisons](guides/comparisons.md) | Exograph vs ExAST, Reach, CodeQL, Sourcegraph |\n| [Architecture](guides/architecture.md) | Storage model, verifier contract, extraction pipeline |\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-vibe%2Fexograph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felixir-vibe%2Fexograph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-vibe%2Fexograph/lists"}