I am currently setting up a CI/CD workflow at my company and I am confused by the two syntax options in Jenkins. I see that the Declarative syntax uses a pipeline {} block, while the Scripted syntax often starts with node {}. As we transition to a more Agile-focused delivery model, I want to know which one is better for long-term maintenance and which provides more robust error checking. Is one purely for beginners, or are there specific technical scenarios where the Scripted approach is mandatory for complex build logic?
3 answers
The fundamental difference lies in their programming models: Declarative uses a more structured, "opinionated" syntax designed to be easy to read and write, while Scripted is an imperative model based on full Groovy scripting. Declarative pipelines are the modern standard because they provide built-in syntax validation at the start of the build, helping you catch errors before execution begins. They also support features like "Restart from Stage," which can save significant time in an Agile environment.
In contrast, Scripted pipelines offer maximum flexibility and have fewer structural limits. Because they are essentially Groovy scripts, you can use any Java or Groovy API to handle highly complex logic that might be difficult to express in the stricter Declarative structure. However, this flexibility comes at the cost of readability and a higher risk of creating "spaghetti" code that is hard for a team to maintain.
Are you prioritizing ease of use for a large team, or do you have highly custom build requirements that need complex loops and conditional logic that might be restricted by a pre-defined structure? I ask because many teams start with Declarative for its simplicity but eventually find they need to "break out" of its constraints using a script {} block to run small portions of Scripted Groovy code without losing the benefits of the Declarative framework.
Declarative is definitely the way to go for most teams. It integrates better with the Blue Ocean UI and provides a much clearer visualization of the stages in your Software Development lifecycle.
I agree with Jennifer. For Robert's question: Yes, you can use a script block inside a stage and still keep all your global post and agent directives! It really is the best of both worlds. We've found this hybrid approach essential for handling our Docker-based microservices while keeping our Jenkinsfiles scannable for the whole team.
James, that's exactly where my head is at. I'm worried that if I choose Declarative, I'll hit a wall if our build process becomes more complex. If I use that script {} block you mentioned, does it still allow me to use Declarative features like the post {} section for notifications, or does the whole pipeline lose its "Declarative" status once I start injecting raw Groovy?