# How to Use Jenkins Declarative Pipeline: Architecture and Code Implementation

> Learn to use Jenkins Declarative Pipeline efficiently. Understand its architecture and implement code with our comprehensive guide for streamlined CI/CD.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: architecture
- Published: 2026-07-29

---

**Jenkins Declarative Pipeline compiles high-level `pipeline {}` syntax into an executable Scripted Pipeline model at runtime through the `pipeline-model-definition` plugin's parser and CPS conversion layer.**

The jenkinsci/jenkins repository contains the `pipeline-model-definition` plugin that transforms user-friendly declarative configurations into robust Jenkins executions. Understanding how to use Jenkins Declarative Pipeline effectively requires familiarity with its parsing architecture, the `DeclarativePipeline` entry point, and the CPS (Continuation-Passing-Style) engine that ultimately runs your build logic.

## Core Architecture and Entry Points

The Declarative Pipeline system functions as a transpiler: it accepts the restricted `pipeline {}` DSL, validates it through a dedicated parser, and generates a standard Scripted Pipeline model that executes within the existing Jenkins workflow engine.

### The DeclarativePipeline Class

At the center of this architecture is [[`DeclarativePipeline.java`](https://github.com/jenkinsci/jenkins/blob/main/DeclarativePipeline.java)](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java), which extends `CpsScmFlowDefinition`—the same base class used for traditional Scripted Pipelines. This inheritance ensures that declarative blocks ultimately resolve to executable CPS code stored in the backing `WorkflowJob`.

The class stores three critical components populated via its [`@DataBoundConstructor`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java#L27) and [`@DataBoundSetter`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java#L33) annotations:

- **`pipelineScript`** (line 23): The raw string content of your `Jenkinsfile`
- **`agent`** (line 24): The execution environment configuration injected through `setAgent()`
- **`options`** (line 25): Pipeline-level configurations like timeouts injected through `setOptions()`

When Jenkins instantiates the job, the `createFlowDefinition()` method transforms these stored values into a runnable flow definition attached to a `WorkflowJob`. The plugin descriptor at line 48 registers this functionality under the display name "Declarative Pipeline".

### The Parser and Error Handling

Before execution begins, the [[`DeclarativeParser.java`](https://github.com/jenkinsci/jenkins/blob/main/DeclarativeParser.java)](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java) class handles syntax validation. Extending the base `Parser` from the `workflow-cps` plugin, this component accepts the script content through its [`@DataBoundConstructor`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java#L11) and validates declarative sections (`agent`, `stages`, `environment`, `options`, `post`).

The parser's [`parse()`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java#L17) method returns a fully configured `DeclarativePipeline` object, effectively converting static DSL text into an executable model. Syntax errors are wrapped using [`DeclarativeErrorHandler`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/errors/DeclarativeErrorHandler.java) to provide line-specific feedback in the Jenkins UI.

## Runtime Execution Model

Once parsed, the declarative model executes through the standard CPS engine, but with structural guarantees enforced by the model definition layer.

### Agent Resolution

The `agent` directive maps to specific implementations of [`AgentImpl`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/agent/AgentImpl.java) referenced in lines 9-11 of the main class:

- **`LabelAgent`**: Allocates a node matching a label expression
- **`DockerAgentImpl`**: Provisions a container environment

These agents are instantiated via `@DataBoundSetter` calls during pipeline configuration and are resolved when the CPS flow begins execution.

### Stage Execution and Steps

Individual steps within `steps { ... }` blocks resolve to classes in the [`org.jenkinsci.plugins.pipeline.modeldefinition.steps`](https://github.com/jenkinsci/jenkins/tree/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/steps) package. Each step extends Jenkins' standard `Step` class and can be registered via the `@Extension` annotation, allowing plugins to contribute new declarative capabilities without modifying core parser logic.

## Practical Jenkinsfile Implementation

Below is a complete `Jenkinsfile` demonstrating declarative syntax that maps directly to the Java classes discussed above:

```groovy
pipeline {
    agent any  // Maps to LabelAgent implementation via AgentImpl
    
    options {
        timeout(time: 30, unit: 'MINUTES')  // Stored in DeclarativePipeline.options
        retry(2)
    }
    
    environment {
        BUILD_VERSION = "1.0.${BUILD_NUMBER}"
    }
    
    stages {
        stage('Compile') {
            steps {
                // Executes via pipeline-model-definition steps infrastructure
                sh 'mvn clean compile'
            }
        }
        
        stage('Parallel Testing') {
            parallel {
                unit: {
                    sh 'mvn test'
                }
                integration: {
                    sh 'mvn verify -Pintegration'
                }
            }
        }
        
        stage('Deploy') {
            when {
                branch 'main'  // Conditional logic enforced by DeclarativeParser
            }
            steps {
                // Custom steps from the modeldefinition steps package
                kubernetesDeploy(
                    configs: 'k8s/*.yaml',
                    kubeConfig: [path: '$KUBECONFIG']
                )
            }
        }
    }
    
    post {
        always {
            archiveArtifacts artifacts: '**/target/*.jar'
        }
        failure {
            // Error output integrated with DeclarativeErrorHandler
            notifySlack(message: "Build failed: ${env.JOB_NAME}")
        }
    }
}

```

This configuration demonstrates how the `pipeline {}` block structure is parsed by [`DeclarativeParser`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java), stored in the [`DeclarativePipeline`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java) model, and executed through the CPS engine using the specified `AgentImpl`.

## Extending Declarative Pipelines

To add custom functionality, developers can create new classes in the `org.jenkinsci.plugins.pipeline.modeldefinition.steps` directory extending `Step` and register them with `@Extension`. These steps become available immediately within any declarative `steps` block without requiring changes to [[`DeclarativeParser.java`](https://github.com/jenkinsci/jenkins/blob/main/DeclarativeParser.java)](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java), maintaining the separation between syntax definition and execution logic.

## Summary

- **Entry Point**: The [`DeclarativePipeline`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java) class extends `CpsScmFlowDefinition` and stores your `pipelineScript`, `agent`, and `options` via its data-bound constructor and setters.
- **Parsing**: [`DeclarativeParser`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java) validates the DSL and converts it into a scripted model, using [`DeclarativeErrorHandler`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/errors/DeclarativeErrorHandler.java) for error reporting.
- **Execution**: The model transforms into a CPS flow that executes on `WorkflowJob` instances using specialized [`AgentImpl`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/agent/AgentImpl.java) implementations like `LabelAgent` or `DockerAgentImpl`.
- **Extensibility**: Custom steps reside in the [`steps`](https://github.com/jenkinsci/jenkins/tree/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/steps) package and integrate via standard Jenkins step extensions.

## Frequently Asked Questions

### What is the difference between Declarative and Scripted Pipeline?

Declarative Pipeline provides a structured, opinionated syntax through the `pipeline {}` block that enforces organizational standards and simplifies maintenance, while Scripted Pipeline offers unrestricted Groovy code execution. Internally, Declarative Pipeline compiles into a Scripted Pipeline model via the [`DeclarativeParser`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java) before CPS execution, meaning both ultimately run on the same engine but Declarative adds validation and abstraction layers.

### How does the `agent` directive work at the source code level?

When you specify `agent any` or `agent { docker 'node:18' }`, the [`DeclarativePipeline`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/DeclarativePipeline.java) class stores this configuration via `setAgent()` using `@DataBoundSetter` at line 33. At runtime, this resolves to concrete implementations like [`LabelAgent`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/agent/LabelAgent.java) or `DockerAgentImpl` (both extending [`AgentImpl`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/agent/AgentImpl.java)), which handle node allocation or container provisioning before your stages execute.

### Can I inject Scripted Pipeline code inside a Declarative Pipeline?

Yes, via the `script` step available in the [`steps`](https://github.com/jenkinsci/jenkins/tree/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/steps) package. This step provides an escape hatch to run arbitrary Groovy within a `steps` block. The [`DeclarativeParser`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java) allows this specific step to contain unvalidated scripted logic, which executes directly in the CPS engine alongside the structured declarative elements.

### Where does Jenkins handle syntax errors in Declarative Pipelines?

Syntax validation occurs in [[`DeclarativeParser.java`](https://github.com/jenkinsci/jenkins/blob/main/DeclarativeParser.java)](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/parser/DeclarativeParser.java), which invokes [`DeclarativeErrorHandler`](https://github.com/jenkinsci/jenkins/blob/master/plugins/pipeline-model-definition/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/errors/DeclarativeErrorHandler.java) to wrap exceptions. This handler provides line-specific error messages in the Jenkins UI during the initial parsing phase before any CPS execution begins, distinguishing declarative syntax errors from runtime failures.