This page covers the build tooling used across the Langflow monorepo: how Python packages are managed with uv, how the frontend is compiled with Vite, and how make ties everything together into common developer workflows.
For detailed workspace configuration and lock file semantics, see Workspace Configuration. For a guide to running backend and frontend together locally, see Local Development Workflow. For CI/CD pipeline details, see CI/CD and Quality Assurance.
The repository uses three primary tools, each owning a different part of the stack:
| Tool | Version / Constraint | Scope |
|---|---|---|
uv | Latest (managed via astral-sh/setup-uv) | Python dependency management, workspace coordination, package builds |
npm / Node.js | Node >= 20.19.0 | Frontend dependency installation |
vite | ^7.3.1 | Frontend bundling and dev server |
make | System make | Top-level task runner for all of the above |
hatchling | Build backend | Python wheel/sdist packaging for all three Python packages |
Sources: pyproject.toml400-402 src/frontend/package.json1-10 Makefile39-42
The monorepo contains three Python packages coordinated by a single uv workspace and one React/TypeScript frontend application.
Python workspace members (declared in pyproject.toml89-94):
pyproject.toml ← workspace root; langflow package (version 1.8.0)
src/backend/base/ ← langflow-base package (version 0.8.0)
src/lfx/ ← lfx package (version 0.3.0)
src/frontend/ ← React/TypeScript frontend (not a uv member)
The [tool.uv.workspace] table in the root pyproject.toml declares all three Python packages as workspace members, and uv.lock pins every transitive dependency across all of them in a single resolution.
The three Python packages have a strict dependency order:
Build dependency graph
Sources: pyproject.toml19-21 src/backend/base/pyproject.toml19-20 src/lfx/pyproject.toml1-5
All three Python packages use hatchling as their build backend. Each pyproject.toml declares:
Each package also specifies its Python source directory via [tool.hatch.build.targets.wheel]:
| Package | packages value |
|---|---|
langflow | src/backend/langflow |
langflow-base | langflow (relative to src/backend/base) |
lfx | src/lfx |
Sources: pyproject.toml96-97 src/backend/base/pyproject.toml140-141
The frontend lives in src/frontend/ and is a standard Vite + React + TypeScript application.
npm run build (which invokes vite build) compiles all assets into src/frontend/build/. The Makefile then copies this directory to src/backend/base/langflow/frontend/, where FastAPI's StaticFiles mounts it at startup.
Frontend build pipeline
Sources: src/frontend/package.json108-110 Makefile21-22 src/backend/base/langflow/main.py1-30
Key scripts defined in src/frontend/package.json106-126:
| Script | Command | Purpose |
|---|---|---|
start | vite | Dev server (proxies API to localhost:7860) |
dev:docker | vite --host 0.0.0.0 | Dev server bound to all interfaces |
build | vite build | Production build |
test | jest | Unit tests |
test:coverage | jest --coverage | Unit tests with coverage |
format | npx @biomejs/biome format --write | Format JS/TS files |
lint | npx @biomejs/biome lint | Lint JS/TS files |
type-check | tsc --noEmit | TypeScript type checking |
The proxy field in package.json is set to http://localhost:7860, so the Vite dev server forwards API calls to the local backend automatically.
Sources: src/frontend/package.json106-143
Relevant dev tooling packages:
| Package | Version | Role |
|---|---|---|
vite | ^7.3.1 | Bundler and dev server |
@vitejs/plugin-react-swc | ^4.2.2 | React JSX transform via SWC |
typescript | ^5.4.5 | Type checking |
@biomejs/biome | 2.1.1 | Linting and formatting |
jest | ^30.0.3 | Unit test runner |
jest-environment-jsdom | ^30.0.2 | DOM environment for Jest |
ts-jest | ^29.4.0 | TypeScript Jest transform |
@playwright/test | ^1.57.0 | End-to-end testing |
tailwindcss | ^3.4.4 | CSS framework |
Sources: src/frontend/package.json140-177
The Makefile at the repository root is the single entry point for all common development tasks. It delegates to uv for Python work and npm for frontend work.
make check_tools verifies that both uv and npm are present before any substantive target runs. make init calls this first.
Sources: Makefile39-42
| Target | What it runs |
|---|---|
make init | install_backend + install_frontend + uvx pre-commit install |
make install_backend | uv sync --frozen --extra "postgresql" |
make reinstall_backend | uv sync -n --reinstall --frozen (bypasses cache) |
make install_frontend | cd src/frontend && npm install |
make install_frontendci | cd src/frontend && npm ci (strict, for CI) |
Sources: Makefile74-88
| Target | What it does |
|---|---|
make run_cli | Builds frontend, runs langflow run via uv run |
make run_clic | Cleans build artifacts first, then same as run_cli |
make backend | Runs uvicorn --factory langflow.main:create_app --reload directly |
make build_frontend | Runs npm run build and copies output to backend static directory |
make setup_devcontainer | Full setup for VS Code dev containers |
The backend target is the most useful for active backend development because it enables uvicorn's --reload flag when workers=1 (the default).
Sources: Makefile236-304
The make build target accepts flag variables to control which packages are built:
Underlying commands:
| Target | Command |
|---|---|
build_langflow_base | cd src/backend/base && uv build |
build_langflow | uv lock --no-upgrade && uv build |
build_langflow_backup | uv lock && uv build |
Sources: Makefile317-349
| Target | Command |
|---|---|
make tests | unit_tests + integration_tests + coverage |
make unit_tests | uv run pytest src/backend/tests/unit with parallelism and split |
make integration_tests | uv run pytest src/backend/tests/integration |
make lfx_tests | cd src/lfx && uv run pytest tests/unit with coverage |
make template_tests | pytest src/backend/tests/unit/template/test_starter_projects.py |
make coverage | uv run coverage run |
The unit_tests target supports parallelism via --instafail -n auto (pytest-xdist) and test splitting via --splitting-algorithm least_duration (pytest-split) using stored durations in src/backend/tests/.test_durations.
Sources: Makefile143-206
| Target | What it runs |
|---|---|
make format | format_backend + format_frontend |
make format_backend | uv run ruff check . --fix + uv run ruff format . |
make format_frontend_check | cd src/frontend && npx @biomejs/biome check |
make lint | uv run mypy --namespace-packages -p "langflow" |
make codespell | uvx codespell --toml pyproject.toml |
Sources: Makefile211-233
| Target | What it does |
|---|---|
make docker_build | Builds full image from docker/build_and_push.Dockerfile |
make docker_build_backend | Builds backend-only image |
make docker_build_frontend | Builds frontend-only image |
make docker_compose_up | Builds and starts docker_example/docker-compose.yml |
The Makefile defaults to podman but accepts DOCKER=docker as an override.
Sources: Makefile352-399
Ruff handles both linting (ruff check) and formatting (ruff format) for all Python source. Configuration lives in the root pyproject.toml.
Key settings from pyproject.toml208-246:
| Setting | Value |
|---|---|
target-version | py310 |
line-length | 120 |
select | ["ALL"] (all rules enabled) |
| Notable ignores | C90 (complexity), ANN (annotations), D10 (missing docstrings), PLR09 (too-many-*) |
Per-file rule overrides exist for test files (disabling S101, SLF001, PLR2004), Alembic migration files, FastAPI route files (TCH), and several src/lfx files.
Mypy performs static type checking. Configuration in pyproject.toml392-398:
pydantic.mypyfollow_imports = "skip" — does not recursively type-check importsignore_missing_imports = truemake lint as uv run mypy --namespace-packages -p "langflow"Biome (@biomejs/biome version 2.1.1) handles both formatting and linting for TypeScript and JavaScript. It replaces ESLint + Prettier in this codebase. Configuration is in biome.json (not shown in provided files, but referenced by npx @biomejs/biome).
Defined in .pre-commit-config.yaml1-50 the following hooks run on each commit:
| Hook | Tool | What it checks |
|---|---|---|
check-case-conflict | pre-commit-hooks | Filename case conflicts |
end-of-file-fixer | pre-commit-hooks | Trailing newline in .py, .js, .ts |
trailing-whitespace | pre-commit-hooks | Trailing whitespace |
ruff | local (uv run) | Python lint with autofix |
ruff-format | local (uv run) | Python formatting |
vulture | local (uv run) | Unused Python code detection |
detect-secrets | local | Prevent secrets being committed (baseline: .secrets.baseline) |
no-commit-to-branch | pre-commit-hooks | Blocks direct commits to main |
check-migration | local | Validates Alembic migrations |
Sources: .pre-commit-config.yaml1-50
Complete build pipeline from source to runnable application
Sources: Makefile317-349 src/backend/base/langflow/main.py1-50 src/frontend/package.json106-115
Test settings are declared in the root pyproject.toml pyproject.toml164-185:
| Setting | Value |
|---|---|
testpaths | src/backend/tests, src/lfx/tests |
timeout | 150 seconds (via pytest-timeout) |
asyncio_mode | auto |
filterwarnings | Ignores DeprecationWarning and ResourceWarning |
log_cli_format | Structured with timestamp, level, message, file, line |
Custom markers:
| Marker | Purpose |
|---|---|
unit | Unit tests |
integration | Integration tests |
slow | Slow-running tests |
api_key_required | Tests that require real API keys |
benchmark | Performance benchmarks |
no_blockbuster | Skip blockbuster (blocking call detector) |
The addopts = "-p no:benchmark" line disables the benchmark plugin by default to avoid unintentional benchmarking during normal test runs.
Sources: pyproject.toml164-185
The uv.lock file at the repository root covers all three workspace members simultaneously. The [tool.uv.sources] table in pyproject.toml82-86 maps package names to workspace paths so that local editable installs are used:
The PyTorch CPU-only index is registered explicitly to avoid pulling in GPU variants:
langflow-base has a very large set of optional extras (LLM providers, vector stores, monitoring, etc.) declared in src/backend/base/pyproject.toml183-484 The root langflow package depends on langflow-base[complete], which includes everything.
For development, the [dependency-groups] dev section in the root pyproject.toml adds test tooling: pytest, ruff, mypy, httpx, pytest-asyncio, pytest-xdist, hypothesis, and many type stubs. These are installed automatically when running uv sync.
Sources: pyproject.toml24-75 src/backend/base/pyproject.toml183-484
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.