This page describes how Langflow discovers, indexes, and loads component definitions at startup and at flow execution time. It covers the pre-built component index, the hash versioning mechanism, runtime class instantiation, and user-supplied component directories.
For details on how the frontend renders component fields from these definitions, see the Component System overview (3), the Input Type System (3.3), and the Component Registry page (3.1). For how loaded components are executed inside a running flow, see the Flow Execution Engine (4.4).
Langflow's component loading is split into two distinct phases:
| Phase | When | What happens |
|---|---|---|
| Index build | Package build time | All built-in component metadata is serialized into component_index.json |
| Runtime load | Server startup | The index is read; component classes are imported on demand via metadata.module |
Built-in components live in the lfx package (src/lfx/src/lfx/components/). User-supplied components are discovered from filesystem directories specified in the COMPONENTS_PATH environment variable.
Sources: src/lfx/src/lfx/_assets/component_index.json, src/lfx/src/lfx/_assets/stable_hash_history.json
component_index.jsonThe primary artifact driving component loading is component_index.json, bundled as package data in the lfx package at src/lfx/src/lfx/_assets/component_index.json.
Its top-level structure is:
{
"entries": [
["<BundleName>", { "<ClassName>": <ComponentMetadata> }],
...
]
}
Each entry is a two-element list: a bundle name string (e.g. "FAISS", "Notion") and a dict mapping class name to component metadata. A single bundle may contain multiple class entries (e.g. the "Notion" bundle contains AddContentToPage, NotionDatabaseProperties, etc.).
Each <ComponentMetadata> object contains the following fields:
| Field | Type | Purpose |
|---|---|---|
display_name | string | Human-readable label shown in the UI sidebar |
description | string | Short description |
base_classes | list of strings | Type names this component can emit (e.g. ["Data", "DataFrame"]) |
field_order | list of strings | Ordered list of input field names for the frontend |
outputs | list of objects | Output port definitions (name, method, types, tool_mode) |
template | dict | Complete field definitions including type, default, display metadata |
metadata.module | string | Fully qualified Python import path to the component class |
metadata.code_hash | string | 12-character hash of the component's source code |
metadata.dependencies | object | List of Python packages the component requires |
edited | bool | true if the user has modified the component's code in the UI |
legacy | bool | true for deprecated components kept for backwards compatibility |
beta | bool | true for components in preview |
Sources: src/lfx/src/lfx/_assets/component_index.json:1-276
Diagram: component_index.json entry mapped to code entities
Example metadata.module values and the files they resolve to:
metadata.module | File |
|---|---|
lfx.components.FAISS.faiss.FaissVectorStoreComponent | src/lfx/src/lfx/components/FAISS/faiss.py |
lfx.components.Notion.add_content_to_page.AddContentToPage | src/lfx/src/lfx/components/Notion/add_content_to_page.py |
lfx.components.input_output.chat.ChatInput | src/lfx/src/lfx/components/input_output/chat.py |
lfx.components.input_output.text.TextInputComponent | src/lfx/src/lfx/components/input_output/text.py |
lfx.components.models_and_agents.prompt.PromptComponent | src/lfx/src/lfx/components/models_and_agents/prompt.py |
lfx.components.files_and_knowledge.file.FileComponent | src/lfx/src/lfx/components/files_and_knowledge/file.py |
Sources: src/lfx/src/lfx/_assets/component_index.json:44-50, src/lfx/src/lfx/components/files_and_knowledge/file.py, src/lfx/src/lfx/components/files_and_knowledge/save_file.py
stable_hash_history.json (src/lfx/src/lfx/_assets/stable_hash_history.json) records the code hash for each component at each released version:
The metadata.code_hash in component_index.json is a 12-character hex digest computed from the component's source. The stable_hash_history.json lets the nightly build pipeline detect when a component's source has changed between versions. If a component's hash is not present in the history for the current version, it is considered changed and will be flagged.
This mechanism enables:
code_hash in their node metadata. The backend can detect if a flow was built against an older version of a component.Sources: src/lfx/src/lfx/_assets/stable_hash_history.json:1-30
Built-in components are those shipped with the lfx package. Their discovery is entirely static: the component_index.json is pre-computed during the build and bundled as package data. At startup the backend reads the index rather than scanning the filesystem.
Diagram: Built-in component loading pipeline
During flow execution, when a vertex needs to be built, the loader uses the metadata.module field to import the actual Python class:
importlib.import_module("lfx.components.FAISS.faiss")
getattr(module, "FaissVectorStoreComponent")
This import is deferred to execution time, not startup, which avoids loading optional dependencies (e.g. langchain_community, faiss-cpu) that may not be installed.
Sources: src/lfx/src/lfx/_assets/component_index.json:1-10, src/lfx/src/lfx/_assets/stable_hash_history.json:1-5
Users can place custom component Python files in directories pointed to by the COMPONENTS_PATH environment variable (see 7.1 for the environment variable reference). Unlike built-in components, these are discovered at runtime by scanning the filesystem.
The loading process for user components:
.py file is imported dynamically.Component (from lfx.custom.custom_component.component) are registered into the type registry alongside built-in components.template, outputs, base_classes) is computed at load time from the class definition rather than read from a pre-built index.Diagram: Built-in vs user-supplied component loading paths
Sources: src/lfx/src/lfx/_assets/component_index.json, src/lfx/src/lfx/base/data/base_file.py:1-30
All loadable components ultimately inherit from Component, defined in lfx.custom.custom_component.component. The lfx package provides several specialized base classes that components use:
| Base class | Module | Purpose |
|---|---|---|
Component | lfx.custom.custom_component.component | Root base class; all components must inherit this |
BaseFileComponent | lfx.base.data.base_file | Adds file upload, path resolution, and format parsing |
LCToolComponent | lfx.base.langchain_utilities.model | Adds LangChain tool wrapping (build_tool() → Tool) |
LCVectorStoreComponent | lfx.base.vectorstores.model | Adds vector store search output wiring |
ChatComponent | lfx.base.io.chat | Adds chat message persistence (send_message()) |
TextComponent | lfx.base.io.text | Simple text output base |
The Component class is what the loader checks for when discovering user-supplied components. Any class in a user .py file that subclasses Component (directly or transitively) is eligible for registration.
Sources: src/lfx/src/lfx/base/data/base_file.py:28, src/lfx/src/lfx/components/files_and_knowledge/file.py:23, src/lfx/src/lfx/components/files_and_knowledge/save_file.py:11
The template block in each component's index entry is the complete field definition consumed by the frontend. When the /api/v1/types endpoint serves component data, it returns these templates verbatim.
A template field entry contains the following key properties:
| Property | Role |
|---|---|
_input_type | The Python input class name (e.g. "StrInput", "BoolInput", "HandleInput") |
type | The canonical type string used for frontend rendering (e.g. "str", "bool", "other") |
dynamic | If true, the field is regenerated when the component's code field changes |
advanced | If true, the field is hidden by default in the UI |
required | Field must have a value before building |
tool_mode | If true, the field is shown in tool mode |
load_from_db | If true, the value is retrieved from global variables |
input_types | For HandleInput / connection ports: list of accepted type names |
The code field inside template is the only dynamic: true field. When a user edits a component's source code in the UI, the backend re-evaluates the class and regenerates all other template fields from the new class definition. The code_hash is updated accordingly and the edited flag is set to true.
Sources: src/lfx/src/lfx/_assets/component_index.json:82-270
Diagram: Entry lifecycle from source to registered type
Sources: src/lfx/src/lfx/_assets/component_index.json, src/lfx/src/lfx/_assets/stable_hash_history.json
Each component's index entry includes a metadata.dependencies object:
This lists Python packages the component imports. The version field is null for lfx itself (since it is always present) and pinned for optional external dependencies. This information is used:
Components with unresolvable dependencies will still load from the index, but will raise ImportError at execution time when the actual class is imported via metadata.module.
Sources: src/lfx/src/lfx/_assets/component_index.json:32-48, src/lfx/src/lfx/_assets/component_index.json:300-335
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.