Core Concepts
Dagger is built around a few core concepts that work together to enable powerful, reusable automation workflows. Understanding these concepts will help you get the most value from Dagger, whether you're consuming existing toolchains or building your own.
Toolchains​
Install pre-built tools and checks for your project. No code required.
Toolchains are Dagger modules that provide ready-to-use functions and checks for common development workflows. Install a toolchain and immediately get linting, testing, security scanning, and more for your codebase.
Perfect for: Application developers who want better CI/testing without writing infrastructure code.
# Install a toolchain for your tools
dagger install github.com/dagger/jest
# Run all checks
dagger check
Checks​
Validate every commit with automated quality, security, and standards checks.
Checks are functions that validate your code without requiring any arguments. They run linting, tests, security scans, and other validations to ensure your code meets quality standards. Checks run identically in local development and CI.
Perfect for: Ensuring code quality and catching issues before they reach production.
# Run all checks concurrently
dagger check
# Or run individual checks
dagger check lint
dagger check security-*
Functions​
Building blocks for creating custom workflows.
Functions are the fundamental units of computation in Dagger. They accept inputs, perform operations (often in containers), and return outputs. Functions can be composed together to build complex workflows. When you write Dagger code, you're creating functions.
Perfect for: Platform engineers and developers building custom automation or creating toolchains.
- Go
- Python
- TypeScript
- PHP
- Java
// A Dagger Function in Go
func (m *MyModule) Build() *Container {
return dag.Container().
From("golang:1.21").
WithDirectory("/src", m.Source).
WithWorkdir("/src").
WithExec([]string{"go", "build", "-o", "app"})
}
# A Dagger Function in Python
@function
def build(self) -> dagger.Container:
return (
dag.container()
.from_("python:3.11")
.with_directory("/src", self.source)
.with_workdir("/src")
.with_exec(["pip", "install", "-r", "requirements.txt"])
.with_exec(["python", "setup.py", "build"])
)
// A Dagger Function in TypeScript
@func()
build(): Container {
return dag
.container()
.from("node:20")
.withDirectory("/src", this.source)
.withWorkdir("/src")
.withExec(["npm", "install"])
.withExec(["npm", "run", "build"]);
}
// A Dagger Function in PHP
#[DaggerFunction]
public function build(): Container
{
return dag()
->container()
->from('php:8.2')
->withDirectory('/app', $this->source)
->withWorkdir('/app')
->withExec(['composer', 'install'])
->withExec(['php', 'artisan', 'build']);
}
// A Dagger Function in Java
@DaggerFunction
public Container build() {
return dag.container()
.from("maven:3.9-eclipse-temurin-21")
.withDirectory("/app", source)
.withWorkdir("/app")
.withExec(List.of("mvn", "clean", "package"));
}
How They Work Together​
These concepts compose to create powerful workflows:
- Toolchains package Functions and Checks for reuse
- Checks are Functions that validate without required arguments
- Functions can call other Functions, including those from Toolchains
Example: Full Development Workflow​
# Install a toolchain (provides functions and checks)
dagger install github.com/example/node-toolchain
# Use toolchain functions
dagger call node build # Build your application
dagger check node:test # Run tests
dagger check # Run all validation checks
# Customize by adding your own functions
dagger develop --sdk=typescript # Add custom functions
# Write functions that use toolchain capabilities
Next Steps​
- Use a Toolchain - Get started in 5 minutes
- Daggerverse - Discover toolchains for your stack
- Types - Learn about data types in Dagger
- Building with Dagger - Create your own functions and toolchains