IDE Integration
Dagger uses GraphQL as its low-level language-agnostic API query language, and each Dagger SDK generates native code-bindings for all dependencies from this API. This gives you all the benefits of type-checking, code completion and other IDE features for your favorite language when developing Dagger Functions.
The dagger develop
command bootstraps a Dagger module template in the selected programming language and sets up or updates all the resources needed to develop a module. After running this command, follow the steps below to have your IDE recognize the Dagger module.
- Go
- Python
- TypeScript
To get your IDE to recognize a Dagger Go module, configure your go.work
file to include the path to your module.
When you generate a Dagger module for the first time, Dagger will create a go.mod
file just for the module. If the module exists in a sub-directory of an outer Go project (such as dagger/
, the default), this might confuse the IDE.
If there is already a go.mod
in the parent directory that you would like to use instead, delete the newly-generated go.mod
and go.sum
and Dagger will use the parent one instead. This is not advisable if your Dagger module has certain dependencies that are not relevant to your core product, since most consumers will prefer a narrower set of dependencies.
To keep the generated go.mod
file and edit your Dagger module in the same IDE session as your project code, one option is to set up a Go workspace:
# in the root of your repository
go work init
go work use ./
go work use ./path/to/mod
After restarting the IDE, you should be able to use IDE features such as go-to-definition, even when editing dagger/main.go
from the project root.
In most cases, go.work
should not be committed to the repository, so it is advisable to add it to the project's .gitignore
file:
echo go.work >> .gitignore
echo go.work.sum >> .gitignore
You can also choose to omit the local Go files generated by dagger develop
from your version control system, as they aren't required to run the module.
When working with multiple inter-dependent Dagger modules, it can be challenging to navigate between Dagger Functions defined in different modules. Source-maps offer a solution to this problem, by allowing developers to directly click through or navigate to type declarations in their IDE.
The Go SDK automatically attaches source-maps to the module code. These are a record of the filename, the line number, and the column number that a type declaration corresponds to in the source code. The SDK analyzes the source code, and outputs these (as line comments of the form ./path/to/filename:line
) when creating the type definitions during module initialization.
Most popular IDEs support source-maps, either natively or with an external plugin, such as the Open file plugin for Visual Studio Code.
To get your IDE to recognize a Dagger Python module and any added Dagger module dependencies in the generated client, all dependencies must be installed in an activated virtual environment (for example, in .venv
, next to pyproject.toml
). This can either be done manually or transparently by a package manager.
For example, to open the Visual Studio Code from the terminal, with functioning autocompletions (assuming the Python extensions are installed):
dagger develop
uv run code .
For NeoVim, just replace code
with vim
, or any other terminal based editor.
The uv run
command works with a uv.lock
file. If you need to use a requirements.lock
or other, continue reading for more examples.
Project environment
The following examples show how to get a working project environment (.venv
) from the terminal, just make sure you run dagger develop
first, to get the necessary sdk
directory locally.
- uv
- uv pip
- pip
- hatch
- poetry
When using a uv.lock
:
uv sync
If you have an older Dagger module, without a uv.lock
file, you can create it with:
uv add --editable ./sdk
rm requirements.lock
uv with uv.lock
needs to have the SDK library (dagger-io
, generated in ./sdk
) defined as a production dependency, unlike the other installation methods where it should be a development dependency.
When using a requirements.lock
file, uv provides a "pip interface" that replaces multiple tools, while still being much faster. It can manage the Python installation, virtual environment creation, and dependency installation.
For example:
uv venv
uv pip install -r requirements.lock -e ./sdk -e .
By default, uv venv
will create an environment with Python 3.12. To pin Python 3.11 both locally and in Dagger, run this first:
echo 3.11 > .python-version
Make sure you have the same Python version that Dagger uses first. By default it's Python 3.12, unless it's overridden in pyproject.toml
or in .python-version
.
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.lock -e ./sdk -e .
First, update pyproject.toml
to allow direct references, and add the local SDK library (dagger-io
) as a dev
dependency:
[project]
name = "main"
version = "0.0.0"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.envs.dev]
dependencies = [
"dagger-io @ {root:uri}/sdk",
]
Then, open the editor with the dev
Hatch environment:
hatch run dev:vim .
Hatch manages the project environment in a central location by default instead of .venv
.
First, add ./sdk
as a development dependency:
poetry add --group=dev -e ./sdk
Then, open the editor with:
poetry run vim .
Poetry manages the project environment in a central location instead of .venv
.
If you place the virtual environment (.venv
) inside the module, don't forget to add it to .gitignore
and to "exclude"
in dagger.json
to avoid uploading those files to the runtime container unnecessarily.
- Visual Studio Code
- PyCharm
The simplest way to get autocompletions and IntelliSense working is to open it with the directory that has .venv
(next to .pyproject.toml
), because the IDE picks it up automatically when it's in the root of the workspace:
code .
VS Code doesn't need to be opened from the terminal though. The same directory can be opened with VS Code's File > Open Folder from the graphical interface (GUI).
The virtual environment can also be created and managed from within the IDE instead of from the terminal, if it supports the chosen lock file format. To know more, see Visual Studio Code Python Environments.
PyCharm is a very popular IDE for Python projects. The simplest way for PyCharm to recognize the dagger
package is to open the IDE in the directory that has .venv
and pyproject.toml
, via the terminal or the GUI.
It can also create and manage the project environment, but may not support uv.lock
yet, so best run uv
from the terminal instead.
When opening the generated dagger/src/index.ts
in an IDE, most IDEs will automatically recognize the @dagger.io/dagger
package, so long as the tsconfig.json
file has a path configured on it.
For Dagger modules initialized using dagger init
, the default template is already configured this way:
"experimentalDecorators": true,
"paths": {
"@dagger.io/dagger": ["./sdk"]
}
This configuration doesn't require separate installation of the dependency to enable type-hinting or other IDE features.
When working with multiple inter-dependent Dagger modules, it can be challenging to navigate between Dagger Functions defined in different modules. Source-maps offer a solution to this problem, by allowing developers to directly click through or navigate to type declarations in their IDE.
The TypeScript SDK automatically attaches source-maps to the module code. These are a record of the filename, the line number, and the column number that a type declaration corresponds to in the source code. The SDK analyzes the source code, and outputs these (as line comments of the form ./path/to/filename:line
) when creating the type definitions during module initialization.
Most popular IDEs support source-maps, either natively or with an external plugin, such as the Open file plugin for Visual Studio Code.