Model or dataset
stanfordnlp/dspy avatar
stanfordnlp/dspy

DSPy and the packaging details that decide whether it fits your stack

DSPy: The framework for programming—not prompting—language models

38,419 stars3,379 forksPythonMIT

At a glance

What is it?
DSPy is a Python framework for programming rather than prompting language models, MIT licensed and installable with one pip line, but its own metadata declares alpha status, a Linux classifier, and an exact pin on the GEPA optimizer that shapes what upgrading means.
Who is it for?
DSPy fits a Python team that wants to express a classifier, a RAG pipeline, or an agent loop as code and let an optimizer tune the prompts, and that is comfortable letting LiteLLM sit in the middle of its model calls. It is a poor fit if you need a declared non-Linux platform, an unpinned optimizer that tracks upstream fixes, or a repository that documents its own API.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two install lines, and one of them tracks a moving branch

Installation is the shortest section in the README:

bash
pip install dspy

The second option is for the very latest from main, and it is `pip install git+https://github.com/stanfordnlp/dspy.git`. Note what that line commits you to. It installs the tip of the default branch with no ref and no commit, so two people running it on different days can get different code, and nothing in the command tells you which. That matters more than usual here, because the release history shows 3.4.0b1 on 2026-09-11 and 3.4.0 on 2026-09-25, so betas and finals have been arriving close together while the branch keeps moving underneath them.

The supported interpreter range is stated in the package metadata rather than in the README: requires-python is >=3.10, <3.15. Check that before anything else, because a version ceiling is a harder wall than a missing feature.

The PyPI metadata says Alpha and declares only Linux

The project classifiers in pyproject.toml are short and worth quoting rather than paraphrasing: Development Status :: 3 - Alpha, Intended Audience :: Science/Research, and Operating System :: POSIX :: Linux.

Read together, those three lines describe a research library maintained on Linux, not a framework with a declared support matrix. The Alpha status is the one that should slow down a procurement conversation, because it is the classification the maintainers publish about their own package, and it sits next to a README that talks about building agent loops and RAG pipelines. The Linux classifier is the one that should slow down a developer on a Mac or a Windows box: the metadata makes no promise there, and no support statement exists to fill the gap. The authors field names Omar Khattab, and the license is the MIT file at the root.

openai and litellm are mandatory, so your provider choice is indirect

The runtime dependency list is where the real integration surface shows. It starts with openai>=1.66.2 and litellm>=1.65.8, then pydantic>=2.11.0, regex, orjson, tqdm, requests, diskcache, json-repair, anyio, cachetools, cloudpickle, and tenacity.

Two consequences follow. First, you install the OpenAI client whether or not you ever call OpenAI, and the actual provider abstraction is LiteLLM rather than an adapter layer of your own, which means model naming, retries, and error shapes are decided by a dependency you do not control. Second, tenacity is declared for a specific reason, and the file says so in a comment: it is an undeclared runtime dependency of litellm, needed for exponential_backoff_retry. That is a maintainer patching a gap in someone else's package in their own manifest. It is also a signal about what to expect when a transitive dependency changes underneath you.

gepa is pinned to one exact version, and it is the optimizer

The last runtime dependency is written differently from all the others:

toml
#replace_package_version_marker
version="3.4.0"

That is the version block of the package itself, and the dependency line to notice is gepa[dspy]==0.1.4. An exact equality pin, not a floor. The newest paper the README cites is GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning, dated Jul'25, so the pinned package is the implementation of the project's current optimizer line.

What the pin costs you is both directions at once. A gepa release with a fix does not reach you without editing pyproject.toml, and a gepa release that changes behaviour cannot reach you by accident either. For a library that advertises prompt and weight optimization as its reason to exist, having the optimizer frozen to a single patch version is the single most consequential line in the file. Upgrading the optimizer is a deliberate, reviewable act, which is a defensible choice and an operational one.

The neighbours are optional extras, including langchain_core

The extras answer most of the integration questions before you ask them. There is anthropic>=0.18.0,<1.0.0, typesafe-sdk, weaviate-client>=4.5.4,<4.22.0, mcp gated on python_version >= '3.10', deno>=2.4.5,<3.0.0, langchain_core>=0.3.0, optuna, numpy, and litellm again as an explicit extra.

The LangChain line is the informative one: langchain_core is an extra, not a dependency, so DSPy is built to sit next to that ecosystem rather than inside it. The weaviate and mcp extras tell you which retrieval store and tool protocol have first class treatment. The deno extra is the surprising one, since it pulls a JavaScript runtime at a pinned range for people who only wanted a Python library.

The consequence for a reader comparing frameworks is that the packaging tells you more than any comparison would. DSPy's cost is the model call stack, not an agent framework, and the extras are the list of things it expects you to bring.

The publish workflow rewrites the version through marker comments

pyproject.toml carries an instruction aimed at contributors rather than users, and it is the kind of thing that gets reformatted away:

toml
# Do not add spaces around the '=' sign for any of the fields
# preceded by a marker comment as it affects the publish workflow.

The fields in question are name="dspy" and version="3.4.0", each preceded by a marker comment, #replace_package_name_marker and #replace_package_version_marker. A contributor who tidies the file into name = "dspy" with spaces, as most formatters would, breaks the release automation, and no test in the repository is positioned to catch it. The build backend is setuptools>=77.0.1, the tree carries uv.lock alongside .pre-commit-config.yaml, so the lock file and the pre-commit hooks are the two places where that kind of change usually gets caught.

The repository is a package, a paper list, and a docs link

The README is a signpost. It points at dspy.ai for documentation, repeats the instruction, and then spends its remaining space on citations: nine papers from Demonstrate-Search-Predict in Dec'22 through DSPy Assertions, In-Context Learning for Extreme Multi-Label Classification, and the multi-stage optimization work, up to GEPA in Jul'25. There is a BibTeX block for the ICLR 2024 paper, though that is for citing, not for running.

What that means for a reader is that the repository contains no example program, no API listing, and no configuration reference. The framing is there: DSPy stands for Declarative Self-improving Python, you write compositional Python instead of brittle prompts, and it targets classifiers, RAG pipelines, and agent loops. The mechanics are not. The quality gates are in the tree, with tests/, docs/, scripts/, and an .agents/ directory, so the code is meant to be read even though the usage documentation lives somewhere else.

Editorial conclusion

DSPy fits a Python team that wants to express a classifier, a RAG pipeline, or an agent loop as code and let an optimizer tune the prompts, and that is comfortable letting LiteLLM sit in the middle of its model calls. It is a poor fit if you need a declared non-Linux platform, an unpinned optimizer that tracks upstream fixes, or a repository that documents its own API. Before you build on it, read the operating system classifier, decide whether the exact gepa pin is acceptable in your dependency policy, and confirm the Python range you deploy on sits inside the declared bounds.

Frequently asked questions

What is DSPy used for?

It is used to build modular AI systems, and the README names three shapes: simple classifiers, sophisticated RAG pipelines, and agent loops. Instead of hand written prompts it has you write compositional Python code, and it supplies algorithms that optimize the prompts and weights of those programs.

What are the key differences between LangChain and DSPy?

The repository makes no comparison, but the packaging does: langchain_core>=0.3.0 is an optional extra of DSPy, not one of its required dependencies. The required list is openai, litellm, pydantic, regex, orjson, tqdm, requests, diskcache, json-repair, tenacity, anyio, cachetools, cloudpickle and gepa.

Can DSPy be used for prompt optimization?

Yes. The README states that DSPy offers algorithms for optimizing prompts and weights, and the most recent paper it cites is GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning from Jul'25. The GEPA implementation is a required dependency pinned to the exact version 0.1.4.

What are the DSPy frameworks?

The repository describes one framework, DSPy, for programming rather than prompting language models, and it stands for Declarative Self-improving Python. Its neighbours appear as optional extras rather than as alternatives: anthropic, typesafe-sdk, weaviate-client, mcp, deno, langchain_core, optuna, numpy and litellm.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stanfordnlp-dspy.svg)](https://hysenlabs.com/projects/stanfordnlp-dspy)