Registry & Defaults
Every swappable slot in indx is bound by a short name — parser, LLM, VLM, embedder, store, output writer, and pipeline stages.
This page is the reference for how those names resolve to classes:
- which registries hold them,
- how third-party plugins join in,
- which defaults you get out of the box.
For the protocol contracts each registered class must satisfy, see the protocols reference. To ship your own registrable component, see Authoring a plugin.
How resolution works
Section titled “How resolution works”Each sub-package (indx.parsers, indx.llm, indx.embed, indx.store, indx.output, …) keeps a registry that maps a short name to a class. A component can be bound two ways:
- By object — you pass an instance that structurally satisfies the slot’s protocol.
- By name — you pass a string in
indx.toml, on the CLI, or touse(). The registry resolves it to a class and constructs it.
Names may carry an optional :model suffix. The part before the colon selects the adapter class. The part after selects a model that adapter loads. For example, openai:gpt-5-mini picks OpenAILLM with gpt-5-mini, and ollama:qwen2.5 picks OllamaLLM with the local qwen2.5 model.
The resolve() pattern
Section titled “The resolve() pattern”Each registry exposes the same small resolver shape:
REGISTRY = {"openai": OpenAILLM, "ollama": OllamaLLM, "none": NullLLM}
def resolve(name: str) -> LLM: base, _, model = name.partition(":") cls = REGISTRY[base] # raises ConfigError (exit 3) if the name is unknown return cls(model=model or None)The base name selects the class; the optional model suffix is passed to the constructor. Slots without a model concept (such as store) ignore the suffix.
Resolution order
Section titled “Resolution order”For each slot, the effective value is chosen by precedence. The first source that supplies a value wins:
explicit code argument / use() or CLI flag > indx.toml > documented defaultAn instance or name passed in code (a constructor argument or use()) and a CLI flag both override the configuration file. The configuration file in turn overrides the built-in default. See Configuration for the full precedence rules across all keys.
Slot registry table
Section titled “Slot registry table”Each row lists the slot, the name strings the built-in registry accepts, and the default class indx constructs when nothing else is specified.
| Slot | Name strings | Default class |
|---|---|---|
parser | plaintext, docling, unstructured, llamaparse, markitdown | DoclingParser |
llm | openai:<model>, ollama:<model>, none | OpenAILLM (gpt-5-mini) |
vlm | none, <adapter> | NullVLM |
embedder | hash, openai:<model>, bge-m3, e5, cohere | OpenAIEmbedder (text-embedding-3-small) |
store | qdrant, pgvector, chroma, lancedb, jsonl | QdrantStore |
output | indx, jsonl, langchain, llamaindex | IndxWriter |
Notes on individual slots:
llm— the model suffix pins the model for cloud and local adapters. The documented default isopenai:gpt-5-mini;noneselects a null LLM so the Enrich stage produces no LLM-derived metadata. Local and alternate adapters (ollama,anthropic,azure,vllm) become available with the matching extra.vlm— defaults tonone(vision enrichment off). Adapter names likeqwen-vl,gpt4o, or a local served endpoint enable it.store—jsonlis the zero-dependency fallback that ships in core; the others require their client extra. See choosing a store.parser—plaintextis the zero-dependency fallback that ships in core;docling,unstructured,llamaparse, andmarkitdowneach require their matching extra. See choosing a parser.embedder—hashis the zero-dependency offline fallback. It is deterministic and useful for smoke tests or tiny air-gapped runs, but it is not a semantic embedding model.output—indxis the sealed portable archive (the.indxsuffix is the file extension; the registry name isindx);jsonlis the zero-dependency writer;langchainandllamaindexemit framework-native objects. See output formats.
Entry-point groups (plugin discovery)
Section titled “Entry-point groups (plugin discovery)”Third-party packages extend indx without modifying it, by advertising Python packaging entry points. At runtime the registry discovers them via importlib.metadata and merges them into the per-slot registries. Installing a plugin package is enough to make its name usable anywhere a built-in is.
| Entry-point group | Slot | Protocol |
|---|---|---|
indx.parsers | parser | Parser |
indx.llms | llm | LLM |
indx.vlms | vlm | VLM |
indx.embedders | embedder | Embedder |
indx.stores | store | Store |
indx.writers | output | OutputWriter |
indx.stages | pipeline | Stage |
A plugin registers under the relevant group in its own pyproject.toml:
# pyproject.toml of a third-party package "indx-weaviate"[project.entry-points."indx.stores"]weaviate = "indx_weaviate.store:WeaviateStore"After pip install indx-weaviate, the registry finds the entry point on first resolution, validates that the class satisfies the Store protocol, and registers it under the name weaviate. The name then works everywhere a built-in does:
[store]backend = "weaviate"DirectoryPipeline(store="weaviate")Canonical defaults
Section titled “Canonical defaults”The complete set of defaults applied when nothing is overridden in code, on the CLI, or in indx.toml:
| Slot | Default name | Default class | Notes |
|---|---|---|---|
parser | docling | DoclingParser | High-fidelity local parser; extra indx[docling]. |
llm | openai:gpt-5-mini | OpenAILLM (gpt-5-mini) | Cloud enrichment; none to disable, ollama:qwen2.5 for local. |
vlm | none | NullVLM | Vision enrichment off by default. |
embedder | openai:text-embedding-3-small | OpenAIEmbedder | Vector dimensionality 1536. |
store | qdrant | QdrantStore | Embedded or server; jsonl is the zero-dep fallback. |
output | indx | IndxWriter | Sealed portable ZIP archive (.indx file extension). |
These map directly to the indx.toml keys [parser].engine, [enrich].llm, [enrich].vlm, [embed].model, [store].backend, and [output].format. The full configuration schema and per-backend sub-tables are documented in the configuration reference.
The resolved choices are recorded in the produced archive’s manifest and in index.json metadata, so a knowledge space is self-describing. A consumer can confirm exactly which embedder (and dimensionality) produced its vectors before querying. See the .indx archive and index.json references.
See also
Section titled “See also”- Protocols reference — the contract every registered class implements.
- Authoring a plugin — ship a registrable component via entry points.
- Configuration reference — names, precedence, and sub-tables.
- Bring your own stack — the design behind swappable slots.