Jenkins Pipeline Comparison: Declarative vs Scripted

AspectDeclarative PipelineScripted Pipeline
SyntaxStructured, block-oriented (pipeline {})Groovy-based script (node {})
ReadabilityHighly readable, clean, and standardizedCan get complex and harder to read as logic grows
ValidationValidated before runtime — syntax errors detected earlyLess validation — errors often show during execution
FlexibilityLimited — some advanced Groovy not supportedHighly flexible — full power of Groovy available
Ease of LearningEasier for beginners — ideal for teams starting with JenkinsSteeper learning curve — requires Groovy understanding
Parallel Exec.Supported via declarative parallel blockFully flexible parallelism via Groovy methods
ParametersBuilt-in parameters blockUse properties() + Groovy scripting
Dynamic BehaviorLimited — hard to generate dynamic stages or stepsVery dynamic — logic and stages can be created dynamically
Error HandlingBasic — only post {} blockRich handling with try/catch/finally
When to Use- Simple pipelines - Need standardization- Complex pipelines - Dynamic workflows - Groovy-heavy logic

Example Code Snippets


Declarative Pipeline Example

groovyCopyEditpipeline {
    agent any

    parameters {
        string(name: 'BRANCH_NAME', defaultValue: 'main', description: 'Branch to build')
        choice(name: 'ENVIRONMENT', choices: ['dev', 'qa', 'prod'], description: 'Deployment environment')
        booleanParam(name: 'DEPLOY', defaultValue: true, description: 'Deploy to server')
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: "${params.BRANCH_NAME}", url: 'https://github.com/example/repo.git'
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }

        stage('Deploy') {
            when {
                expression { return params.DEPLOY }
            }
            steps {
                echo "Deploying to ${params.ENVIRONMENT} environment..."
                // deployment script
            }
        }
    }

    post {
        always {
            echo 'Pipeline completed!'
        }
    }
}

Why use Declarative?

  • Clear structure

  • Built-in validation

  • Easy to read and maintain


Scripted Pipeline Example

groovyCopyEditnode {
    def branch = params.BRANCH_NAME ?: 'main'
    def environment = params.ENVIRONMENT ?: 'dev'

    stage('Checkout') {
        checkout([$class: 'GitSCM',
                  branches: [[name: branch]],
                  userRemoteConfigs: [[url: 'https://github.com/example/repo.git']]])
    }

    stage('Build') {
        sh 'mvn clean package'
    }

    stage('Conditional Deploy') {
        if (params.DEPLOY) {
            echo "Deploying to ${environment}..."
            // deployment script
        } else {
            echo "Skipping deployment."
        }
    }

    stage('Post') {
        echo 'Pipeline completed!'
    }
}

Why use Scripted?

  • Full Groovy control

  • Dynamic logic and flows

  • Advanced error handling with try/catch


Quick Reference: When to Use What

Use CaseRecommended Type
Simple build/test/deploy flowsDeclarative Pipeline
Standard team pipelines for consistent structureDeclarative Pipeline
Need for dynamic generation of stages or stepsScripted Pipeline
Complex Groovy scripting and conditional logicScripted Pipeline
Beginners starting with JenkinsDeclarative Pipeline
1
Subscribe to my newsletter

Read articles from Sandeep Lagishetti directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sandeep Lagishetti
Sandeep Lagishetti