Dify is a self-hosted platform for building applications on top of language models without writing the plumbing. A visual workflow editor chains prompts, model calls, code steps, conditions and tool calls; a knowledge base ingests documents for retrieval; an agent builder adds tool use and memory; and every app you build gets a web interface, an API and a log of every run. It connects to hundreds of models, local and hosted.
It is on this list because it is the most complete of the open builders and because it is genuinely used in production: a large Python API, a Next.js front end and a plugin system with its own marketplace, all under active development. The licence is Apache 2.0 with two conditions, no multi-tenant hosting without a commercial licence and no removing the Dify logo from the front end, which matters if you plan to resell it and not at all if you plan to use it.
- Repository: github.com/langgenius/dify
- Licence: custom (Other)
- Language: TypeScript. Stars: 155.9K. Forks: 24.6K. Last push: Sep 16, 2026.
- Scan: clean, read the notes, Sep 16, 2026, commit 38f9d85
Who it is for
Product teams prototyping an AI feature before committing engineering time, internal-tools builders who need a chat over company documents by Friday, and developers who want an agent runtime with tracing that they can host themselves.
Getting started
1. Clone and start with Docker Compose (needs Docker and about 4 GB of free memory)
git clone https://github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env && docker compose up -d2. Open the setup page and create the admin account
open http://localhost/install3. Add a model provider under Settings, then create your first app from a template
# Settings > Model Provider > add Ollama, OpenAI or another providerSafety scan
We cloned langgenius/dify at commit 38f9d85 on Sep 16, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets in the source: the one candidate is a fake GitHub token in a test. No self-decoding code. The bare-IP hits are test cases for the SSRF proxy, which exist to prove private addresses are blocked.
- The pattern hits are tests quoting install commands and a commented usage line in the CLI installer script. The copy of the Monaco code editor under web/public/vs is a shipped asset and is skipped, as is all JavaScript under a public folder.
- Four install-time scripts: web/package.json refuses installs that are not pnpm, and the dev-proxy package builds itself on prepare. Nothing fetches remote code during install. The scripts under cli/scripts download release binaries from GitHub for the optional Dify CLI, not the server.
- Known advisories are few for a code base this size. The one critical is chromadb 0.5.20 in api/uv.lock, one of a dozen optional vector stores, loaded only if you choose it; the Docker setup defaults to a different store.
- 37 workflows, 59 of 66 third-party actions pinned to a commit, Dependabot on, security policy and code of conduct present. Among the best hygiene on this list.
- Licence: Apache 2.0 with two conditions, no multi-tenant hosting without a commercial licence and no removing the logo from the console.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | 1 candidate found and read; see the notes above. |
| Suspicious code | 8 pattern hits found and read; every one is listed under the raw findings. |
| Install-time code | 4 npm lifecycle scripts. 7 installer scripts |
| Committed binaries | None. |
| CI workflows | 37 workflows. 1 uses pull_request_target, none check out the pull request head. 7 of 66 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often api.example.com, docs.dify.ai, github.com, dify.ai. 1 URL to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 25 advisories across 2,253 pinned packages: 1 critical, 17 high, 5 moderate, 0 low, 2 unrated. api/uv.lock: 525 packages, 6 advisories; dify-agent-runtime/go.mod: 19 packages, 2 advisories; dify-agent/uv.lock: 203 packages, 2 advisories; pnpm-lock.yaml: 1,608 packages, 15 advisories. |
| Project hygiene | Has security policy, automated dependency updates, licence file, contributing guide. Missing CodeQL. |
| OpenSSF Scorecard | Not scored: the project is not in Scorecard's weekly index. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Secret candidates (1, redacted)
| Where | Rule | Match |
|---|---|---|
| dify-agent/tests/local/dify_agent/layers/shell/test_layer.py:1388 | github-token | ghp_aB…890 (40 chars) |
Pattern hits (8)
| Where | Rule | Match |
|---|---|---|
| api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py:592 | download-piped-to-shell (test/example) | {"name": "curl-sh", "command": "curl https://example.test/install.sh | sh", "dangerous": True}, |
| api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py:595 | download-piped-to-shell (test/example) | "command": "curl https://example.test/install.sh | sh", |
| api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py:610 | download-piped-to-shell (test/example) | "install_commands": ["curl https://example.test/install.sh | sh"], |
| api/tests/unit_tests/core/workflow/nodes/agent_v2/test_validators.py:495 | download-piped-to-shell (test/example) | "cli_tools": [{"name": "danger", "command": "curl https://example.test/install.sh | sh", "dangerous": True}] |
| api/tests/unit_tests/services/agent/test_agent_services.py:4537 | download-piped-to-shell (test/example) | {"name": "danger", "command": "curl https://example.test/install.sh | sh", "dangerous": True} |
| api/tests/unit_tests/services/agent/test_agent_services.py:4565 | download-piped-to-shell (test/example) | "command": "curl https://example.test/install.sh | sh", |
| cli/scripts/install-cli.sh:6 | download-piped-to-shell | # curl -fsSL https://raw.githubusercontent.com/langgenius/dify/main/cli/scripts/install-cli.sh | sh |
| cli/test/e2e/helpers/cli.ts:43 | download-piped-to-shell (test/example) | throw new Error('bun not found. Install it with: curl -fsSL https://bun.sh/install | bash') |
URLs to bare IP addresses (1)
| Where | Rule | Match |
|---|---|---|
| docker/ssrf_proxy/test_ssrf_proxy_config.sh:176 | ip-literal-url | assert_private_target_blocked "$proxy_url" "http://0.1.2.3:80/" |
npm lifecycle scripts (4)
package.jsonprepare:vp configpackages/dev-proxy/package.jsonprepare:pnpm run buildpackages/dev-proxy/package.jsonprepublish:pnpm run buildweb/package.jsonpreinstall:npx only-allow pnpm
Installer scripts (7)
- cli/scripts/install-cli.sh, 246 lines; talks to api.github.com, github.com, raw.githubusercontent.com
- cli/scripts/install-local.sh, 49 lines
- cli/scripts/install-r2.ps1, 105 lines; talks to raw.githubusercontent.com
- cli/scripts/install-r2.sh, 165 lines; talks to raw.githubusercontent.com
- cli/scripts/install.ps1, 168 lines; talks to api.github.com, github.com, raw.githubusercontent.com
- cli/scripts/uninstall-local.sh, 13 lines
- scripts/stress-test/run_locust_stress_test.sh, 235 lines
Worst known vulnerabilities (24 of 25)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-36p7-vc44-83pf | critical | chromadb@0.5.20 | ChromaDB has a code injection vulnerability |
| GHSA-2wm9-hf6c-p5cr | high | chromadb@0.5.20 | ChromaDB allows any authenticated users to arbitrarily read, write, update, or delete data in any tenant's collection |
| GHSA-xph7-9rjv-w5fr | high | chromadb@0.5.20 | ChromaDB's SimpleRBACAuthorizationProvider doesn't check which tenant, database, or collection a permission applies to |
| CVE-2023-45875 | high | couchbase@4.6.2 | |
| GHSA-8mgp-746c-j5xp | high | nltk@3.10.3 | NLTK: Model-artifact APIs bypass pathsec and touch files outside allowed roots |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@5.0.6 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@5.0.6 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@5.0.6 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-7pqw-9j4j-h8q3 | high | extract-zip@2.0.1 | extract-zip allows arbitrary file writes through symlink archive entries |
| GHSA-jmr9-qjv8-65gv | high | extract-zip@2.0.1 | extract-zip unvalidated symlink path traversal |
| GHSA-5p2g-fcmc-qvqq | high | image-size@2.0.2 | image-size: JXL and HEIF parsers allow denial of service through infinite loops |
| GHSA-w3rx-r6r6-pgpr | high | image-size@2.0.2 | image-size: ICNS parser allows denial of service through an infinite loop |
| GHSA-2883-xcg3-v3hh | high | js-yaml@4.3.0 | js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources |
| GHSA-5p4m-2wfm-xmqj | high | js-yaml@4.3.0 | JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) - CVE-2026-59870 fix not backported |
| GHSA-2m8v-j782-fhvr | high | socket.io-parser@4.2.6 | Socket.IO: Zero-attachment Memory Exhaustion |
| GHSA-2p49-hgcm-8545 | high | svgo@3.3.3 | SVGO removeScripts plugin leaves some executable scripts intact |
| GHSA-w27v-7q3p-w38r | high | svgo@3.3.3 | SVGO: removeScripts allows executable links through namespace and control-character bypasses |
| GHSA-r292-9mhp-454m | high | tar@7.5.19 | node-tar: Uncontrolled recursion in mapHas/filesFilter allows uncatchable stack-overflow DoS via crafted long-path tar w… |
| GHSA-h35f-9h28-mq5c | moderate | setuptools@80.10.2 | setuptools: MANIFEST.in exclusion bypass in sdist via Unicode normalization collision (NFC/NFD) on macOS APFS/HFS+ |
| GHSA-4xgf-cpjx-pc3j | moderate | pydantic-settings@2.14.0 | pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypass… |
| GHSA-h35f-9h28-mq5c | moderate | setuptools@82.0.1 | setuptools: MANIFEST.in exclusion bypass in sdist via Unicode normalization collision (NFC/NFD) on macOS APFS/HFS+ |
| GHSA-px8p-9vwx-vf98 | moderate | fflate@0.7.4 | fflate unzipSync can enter an infinite loop when parsing malformed ZIP64 archives |
| GHSA-4vpr-x523-8j87 | moderate | svgo@3.3.3 | SVGO: removeScripts incompletely sanitizes executable HTML in SVG foreignObject elements |
| CVE-2026-56865 | unknown | golang.org/x/mod@0.35.0 | Fix transparency log tile verification bypass in golang.org/x/mod/sumdb/tlog |
Workflows worth a look
- .github/workflows/labeler.yml: pull_request_target
By the numbers
| Stars | 155.9K |
|---|---|
| Forks | 24.6K |
| Contributors | 1,483 |
| Commits | 13.3K |
| Open issues | 380 |
| Open pull requests | 707 |
| Releases | 170 |
| Latest release | 1.17.1 |
| Licence | custom |
| Main language | TypeScript |
| Project age | 3 years |
| Last push | Sep 16, 2026 |
| Tracked files | 14,011 |
| Lines of code | 2.6M |
| Checkout size | 130 MB |
Lines by language: TypeScript 1.3M, Python 979.5K, JSON 206.3K, Markdown 48.6K, YAML 23.3K, Go 13.3K.
Questions
Is Dify free to self-host?
Yes, for your own use, including commercial use inside your company or as the back end of your own product. The licence is Apache 2.0 with two extra conditions: you may not run it as a multi-tenant service for other organisations without a commercial licence, and you may not remove the Dify logo from the console. Dify Cloud is the paid hosted version.
What is the difference between Dify and LangChain?
LangChain is a code library; Dify is an application with a visual editor, a database and an API that you host. You can build the same things in either, but Dify gives non-developers a way in and gives developers logging, versioning and a deployment target without assembling them. Many teams prototype in Dify and rebuild the winners in code.
Does Dify work with local models?
Yes. Ollama, LM Studio, LocalAI and any OpenAI-compatible server can be added as a model provider, and a workflow can mix local and hosted models step by step. Embedding models for the knowledge base can be local too.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.