Files
langflow/docs/versioned_docs/version-1.9.0/Contributing/contributing-components.mdx
Mendon Kissling 71fbf5ff00 docs: cut version 1.9.0 (#12681)
* version-1.9.0-docs

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-14 02:07:01 +00:00

114 lines
5.4 KiB
Plaintext

---
title: Contribute components
slug: /contributing-components
---
import PartialBasicComponentStructure from '../_partial-basic-component-structure.mdx';
New components are added as objects of the [`Component`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/custom/custom_component/component.py) class.
Dependencies are added to the [pyproject.toml](https://github.com/langflow-ai/langflow/blob/main/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.
<PartialBasicComponentStructure />
5. Save the `dataframe_processor.py` to the `src/lfx/src/lfx/components` directory.
This example adds a data component, so add it to the `/data` directory.
6. Add the component dependency to `src/lfx/src/lfx/components/data/__init__.py` as `from .DataFrameProcessor import DataFrameProcessor`.
You can view the [/data/__init__.py](https://github.com/langflow-ai/langflow/blob/dev/src/lfx/src/lfx/components/data/__init__.py) in the Langflow repository.
7. Add any new dependencies to the [pyproject.toml](https://github.com/langflow-ai/langflow/blob/main/pyproject.toml#L20) file.
8. Submit documentation for your component. For this example component, you would submit documentation to the [Data components page](https://github.com/langflow-ai/langflow/blob/main/docs/docs/Components/components-data.mdx).
9. 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:
```python
class MyCustomComponent(BaseComponent):
name = "my_custom_component_internal"
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](/contributing-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:
<details>
<summary>Example PR</summary>
```markdown
# Pull request with changes to Notify component
This pull request updates the Notify component.
## What changed
- Added new `timeout` field to control how long the component waits for a response.
- Renamed `message` field to `notification_text` for clarity.
- Added support for async operations.
- Deprecated the `retry_count` field in favor of `max_retries`.
## Why it changed
- `timeout` field addresses user requests for better control over wait times.
- `message` to `notification_text` change makes the field's purpose clearer.
- Async support improves performance in complex flows.
- `retry_count` to `max_retries` aligns with common retry pattern terminology.
## Impact on users
- New `timeout` field is optional (defaults to 30 seconds).
- Users will see a deprecation warning for `retry_count`.
- Migration: Replace `retry_count` with `max_retries` in existing flows.
- Both fields will work until version 2.0.
- No action needed for async support - it's backward compatible.
```
</details>
## 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](/contributing-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.