This page describes how to run the Langflow backend and frontend locally for development, including environment setup, dependency installation, hot reload behavior, database initialization, and common day-to-day tasks. For a description of the available Makefile targets themselves, see 2.3. For configuration options and environment variables, see 7.1 and 7.2. For the build pipeline that produces release artifacts, see 8.3.
| Tool | Version Requirement | Purpose |
|---|---|---|
uv | latest | Python package management and workspace tooling |
npm | bundled with Node.js | Frontend dependency management |
| Node.js | >=20.19.0 | Frontend build and dev server |
| Python | >=3.10, <3.14 | Backend runtime |
The check_tools target in the Makefile verifies that both uv and npm are on PATH before any installation step runs. Makefile39-42
Run once after cloning the repository:
This target chains four steps Makefile84-88:
Initial Setup: make init Sequence
Sources: Makefile39-88 pyproject.toml89-94 src/frontend/package.json1-10 .pre-commit-config.yaml1-30
install_backend runs uv sync --frozen --extra "postgresql" at the repo root. Because pyproject.toml declares a uv workspace pyproject.toml89-94 this installs all three packages (langflow, langflow-base, lfx) and their dependencies from uv.lock in a single virtual environment. install_frontend runs npm install inside src/frontend/.
There are two common local development modes: split processes (recommended for active frontend or backend work) and integrated mode (frontend is built and served by the backend process).
Development Mode Overview
Sources: Makefile236-304 src/frontend/package.json106-113 src/backend/base/langflow/main.py1-30
This target Makefile282-304:
setup_env (executes scripts/setup/setup_env.sh to ensure a .env file exists).uv run uvicorn --factory langflow.main:create_app.When workers=1 (the default), --reload is passed to uvicorn, enabling hot reload for Python source changes. Setting workers to more than 1 disables reload.
Relevant Makefile variables:
| Variable | Default | Purpose |
|---|---|---|
port | 7860 | Listening port |
host | 0.0.0.0 | Bind address |
env | .env | Env file passed to --env-file |
log_level | debug | Uvicorn log level |
workers | 1 | Process count; enables --reload when 1 |
login | (unset) | If set, overrides LANGFLOW_AUTO_LOGIN |
To override the port:
To run with LANGFLOW_AUTO_LOGIN=true (skips the login form during local dev):
Sources: Makefile282-304
From src/frontend/:
This invokes Vite's dev server src/frontend/package.json107-113 Vite listens on port 5173 by default and proxies all requests that don't match a static asset to http://localhost:7860 (the backend). This proxy is configured in src/frontend/package.json139:
Vite provides Hot Module Replacement (HMR) — React component changes appear in the browser without a full reload. TypeScript compilation errors surface in the terminal.
For a Docker or devcontainer context where the frontend must bind to all interfaces:
This runs vite --host 0.0.0.0 src/frontend/package.json107
Sources: src/frontend/package.json106-113
Two Makefile targets build the frontend and serve it via the backend process:
| Target | When to Use |
|---|---|
make run_cli | Reuses existing build cache if available |
make run_clic | Always performs a clean frontend build first |
run_clic prepends clean_frontend_build, which deletes src/frontend/build/ and src/backend/base/langflow/frontend/ Makefile110-116 The build output is copied to src/backend/base/langflow/frontend/, which FastAPI serves as static files.
In integrated mode, there is no separate Vite process and no HMR.
Sources: Makefile236-254 Makefile110-116
Backend Startup: lifespan Function in langflow.main
Sources: src/backend/base/langflow/main.py147-200 src/backend/base/langflow/services/database/service.py42-56 src/backend/base/langflow/initial_setup/setup.py1-60
Key functions in the startup sequence:
| Function | Module | Effect |
|---|---|---|
create_app() | langflow.main | Constructs the FastAPI app with middleware and routers |
get_lifespan() | langflow.main | Returns the async context manager driving startup/shutdown |
initialize_services() | langflow.services.utils | Starts all services including DatabaseService |
DatabaseService.__init__() | langflow.services.database.service | Opens the DB engine, runs Alembic migrations |
create_or_update_starter_projects() | langflow.initial_setup.setup | Loads bundled starter flows into the DB |
initialize_auto_login_default_superuser() | langflow.initial_setup.setup | Creates a default superuser when AUTO_LOGIN=true |
The default database is SQLite. DatabaseService determines the database URL from Settings.database_url src/backend/base/langflow/services/database/service.py48-55 When no explicit URL is configured, the path defaults to a platform-specific user data directory (resolved via platformdirs).
Alembic migrations run automatically every time the backend starts — no manual migration step is needed in local development. To force a migration fix:
To use PostgreSQL instead of SQLite (requires postgresql extras already installed via make install_backend):
Sources: src/backend/base/langflow/services/database/service.py42-100 src/backend/base/pyproject.toml183-192
setup_env (called by the backend target) runs scripts/setup/setup_env.sh to create a .env file if none exists Makefile276-277 This file is passed to uvicorn via --env-file.
Commonly useful variables for local development:
| Variable | Effect |
|---|---|
LANGFLOW_AUTO_LOGIN | true skips the login form; creates a default superuser on first start |
LANGFLOW_DATABASE_URL | Override the SQLite path with any SQLAlchemy-compatible URL |
LANGFLOW_SECRET_KEY | JWT signing key; auto-generated if absent |
LANGFLOW_LOG_LEVEL | One of debug, info, warning, error, critical |
LANGFLOW_COMPONENTS_PATH | Comma-separated list of directories for custom components |
LANGFLOW_CORS_ORIGINS | Allowed CORS origins; defaults to * (permissive) with a warning |
See 7.1 for the full variable reference.
format_backend runs two Ruff passes Makefile218-220:
ruff check . --fix — lint and auto-fix import order, style issuesruff format . — opinionated code formatterFrontend formatting is handled by Biome:
After make init, pre-commit runs on every git commit. The hooks configured in .pre-commit-config.yaml are:
| Hook | Action |
|---|---|
check-case-conflict | Prevents case-conflicting filenames |
end-of-file-fixer | Ensures files end with a newline (.py, .js, .ts) |
mixed-line-ending | Enforces LF line endings |
trailing-whitespace | Strips trailing whitespace |
ruff | Runs ruff check --fix on staged Python files |
ruff-format | Runs ruff format on staged Python files |
Sources: .pre-commit-config.yaml1-30 Makefile218-232
unit_tests passes --instafail -n auto for parallel execution by default. To restrict to a specific test file or marker:
Frontend unit tests:
Sources: Makefile148-206 src/frontend/package.json107-115 pyproject.toml164-185
Code/Task Mapping
Sources: Makefile124-136 src/backend/base/langflow/services/database/service.py1-100
This runs install_backend, install_frontend, build_frontend, then starts the server with the built frontend path explicitly set Makefile270-274 Inside a devcontainer, use npm run dev:docker instead of npm start so that Vite binds to 0.0.0.0 rather than localhost only.
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.