Skip to main content

Contribute components

New components are added as objects of the Component class.

Dependencies are added to the pyproject.toml file.

Contribute an example component to Langflow

Anyone can contribute an example component. For example, to create a new Data component called DataFrame processor, follow these steps to contribute it to Langflow.

  1. Create a Python file called dataframe_processor.py.
  2. Write your processor as an object of the Component class. You'll create a new class, DataFrameProcessor, that will inherit from Component and override the base class's methods.

_10
from typing import Any, Dict, Optional
_10
import pandas as pd
_10
from langflow.custom import Component
_10
_10
class DataFrameProcessor(Component):
_10
"""A component that processes pandas DataFrames with various operations."""

  1. Define class attributes to provide information about your custom component:

_13
from typing import Any, Dict, Optional
_13
import pandas as pd
_13
from langflow.custom import Component
_13
_13
class DataFrameProcessor(Component):
_13
"""A component that processes pandas DataFrames with various operations."""
_13
_13
display_name: str = "DataFrame Processor"
_13
description: str = "Process and transform pandas DataFrames with various operations like filtering, sorting, and aggregation."
_13
documentation: str = "https://docs.langflow.org/components-dataframe-processor"
_13
icon: str = "DataframeIcon"
_13
priority: int = 100
_13
name: str = "dataframe_processor"

  • display_name: A user-friendly name shown in the UI.
  • description: A brief description of what your component does.
  • documentation: A link to detailed documentation.
  • icon: An emoji or icon identifier for visual representation. For more information, see Contributing bundles.
  • priority: An optional integer to control display order. Lower numbers appear first.
  • name: An optional internal identifier that defaults to class name.
  1. Define the component's interface by specifying its inputs, outputs, and the method that will process them. The method name must match the method field in your outputs list, as this is how Langflow knows which method to call to generate each output. This example creates a minimal custom component skeleton. For more information on creating your custom component, see Create custom Python components.

_21
from typing import Any, Dict, Optional
_21
import pandas as pd
_21
from langflow.custom import Component
_21
_21
class DataFrameProcessor(Component):
_21
"""A component that processes pandas DataFrames with various operations."""
_21
_21
display_name: str = "DataFrame Processor"
_21
description: str = "Process and transform pandas DataFrames with various operations like filtering, sorting, and aggregation."
_21
documentation: str = "https://docs.langflow.org/components-dataframe-processor"
_21
icon: str = "DataframeIcon"
_21
priority: int = 100
_21
name: str = "dataframe_processor"
_21
_21
# input and output lists
_21
inputs = []
_21
outputs = []
_21
_21
# method
_21
def some_output_method(self):
_21
return ...

  1. Save the dataframe_processor.py to the src > backend > base > langflow > components directory. This example adds a Data component, so add it to the /data directory.

  2. Add the component dependency to src > backend > base > langflow > components > data > __init__.py as from .DataFrameProcessor import DataFrameProcessor. You can view the /data/init.py in the Langflow repository.

  3. Add any new dependencies to the pyproject.toml file.

  4. Submit documentation for your component. For this example component, you would submit documentation to the Data components page.

  5. Submit your changes as a pull request. The Langflow team will review, suggest changes, and add your component to Langflow.

Best practices for modifying components

When creating or updating components, follow these best practices to maintain backward compatibility and ensure a smooth experience for users.

Don't rename the class or name attribute

Changing the class name or the name attribute breaks the component for all existing users. This happens because the frontend tests the type attribute, which is set to the class' name or the name attribute. If these names change, the component effectively becomes a new component, and the old component disappears.

Instead, do the following:

  • Change only the display name if the old name is unclear.
  • Change only the display name if functionality changes but remains related.
  • If a new internal name is necessary, mark the old component as legacy=true and create a new component.

For example:


_10
class MyCustomComponent(BaseComponent):
_10
name = "my_custom_component_internal"
_10
legacy = True

Don't remove fields and outputs

Removing fields or outputs can cause edges to disconnect and change the behavior of components.

Instead, mark fields as deprecated and keep them in the same location. If removal is absolutely necessary, you must define and document a migration plan. Always clearly communicate any changes in the field's information to users.

Maintain outdated components as legacy

When updating components, create them as completely separate entities while maintaining the old component as a legacy version. Always ensure backward compatibility and never remove methods and attributes from base classes, such as LCModelComponent.

Favor asynchronous methods

Always favor asynchronous methods and functions in your components. When interacting with files, use aiofile and anyio.Path for better performance and compatibility.

Include tests with your component

Include tests for your changes using ComponentTestBase classes. For more information, see Contribute component tests.

Documentation

When documenting changes in pull requests, clearly explain what changed, such as display name updates or new fields, why it changed, such as improvements or bug fixes, and the impact on existing users.

For example:

Example PR

_22
# Pull request with changes to Notify component
_22
_22
This pull request updates the Notify component.
_22
_22
## What changed
_22
- Added new `timeout` field to control how long the component waits for a response.
_22
- Renamed `message` field to `notification_text` for clarity.
_22
- Added support for async operations.
_22
- Deprecated the `retry_count` field in favor of `max_retries`.
_22
_22
## Why it changed
_22
- `timeout` field addresses user requests for better control over wait times.
_22
- `message` to `notification_text` change makes the field's purpose clearer.
_22
- Async support improves performance in complex flows.
_22
- `retry_count` to `max_retries` aligns with common retry pattern terminology.
_22
_22
## Impact on users
_22
- New `timeout` field is optional (defaults to 30 seconds).
_22
- Users will see a deprecation warning for `retry_count`.
_22
- Migration: Replace `retry_count` with `max_retries` in existing flows.
_22
- Both fields will work until version 2.0.
_22
- No action needed for async support - it's backward compatible.

Example pull request flow

  1. Create or update a component. Maintain the class name and name attribute if the purpose remains the same. Otherwise, create a new component and move the old component to legacy.
  2. Add tests. Create tests using one of the ComponentTestBase classes. For more information, see Contribute component tests.
  3. Flag outdated fields and outputs as deprecated and keep them in the same location to ensure backward compatibility.
  4. Document your changes. Include migration instructions if breaking changes occur.
Search