---
url: /en/build/script-vs-plugin.md
---
## Overview

In the CNB pipeline, a `Job` is the smallest execution unit, primarily categorized into three types: **Script Jobs**, **Plugin Jobs**, and **Built-in Jobs**. Both the first two types support specifying the `image` parameter to define the runtime environment, which can often be confusing for newcomers. This document provides a detailed comparison of the characteristics and use cases of these two job types to help you make informed decisions.

## Similarities

* Both can specify `image` to define the execution environment
* Both execute in isolated container environments, avoiding pollution of the host or other jobs
* Both can use CNB built-in system environment variables (e.g., `CNB_REPO_SLUG`, `CNB_COMMIT`)

## Differences

| Feature | Script Job | Plugin Job |
|---------|------------|------------|
| **Execution** | Uses `image` as environment, executes Shell commands specified by `script` or `commands` | Runs `ENTRYPOINT` built into `image`, acts as a functional module |
| **Default Environment** | Executes in pipeline container environment if `image` is not specified | Must specify `image` |
| **Parameter Passing** | Declares environment variables via `env` or `imports` | Specifies parameters via `settings`, injected as `PLUGIN_` + uppercase parameter name |
| **Environment Variable Restrictions** | No restrictions | Only CNB built-in variables available; `env`/`imports` not passed |
| **Flexibility** | High, can execute arbitrary Shell commands | Preset by plugin developer, configured via `settings` |
| **Reusability** | Strongly tied to business logic | Cohesive functionality, easy to reuse |
| **Version Control** | Script follows code repository version control | Defaults to `latest` if version not specified; plugin updates may cause configuration failures |

### Execution Method

**Script Job**: Uses image as environment, you have full control to execute arbitrary Shell commands.

```yaml
- name: install dependencies
  image: node:20 # Specify execution environment; if not specified, runs in pipeline container environment
  script: npm install # Execute Shell commands
  env:
    NODE_ENV: production # Declare environment variables via env
```

**Plugin Job**: Runs preset `ENTRYPOINT` from plugin image, configures plugin behavior via `settings` parameters.

```yaml
- name: npm publish
  image: plugins/npm # Run plugin image, execute built-in ENTRYPOINT
  settings:
    username: $NPM_USER # Specify parameters via settings
    password: $NPM_PASS
    registry: https://registry.npmjs.org/
```

The above plugin job injects environment variables:

* `PLUGIN_USERNAME`
* `PLUGIN_PASSWORD`
* `PLUGIN_REGISTRY`

### Parameter Passing

**Script Job** environment variable passing:

* Declare environment variables via `env`
* Import environment variables from files via `imports`
* Priority: `Job env` > `Stage env` > `Pipeline env`

**Plugin Job** parameter passing:

* Specify parameters via `settings` (parameters injected with `PLUGIN_` prefix)
* Load parameters from files via `settingsFrom`
* Pass command-line arguments via `args`
* **Note**: Custom environment variables declared via `env` and `imports` are not passed to plugins

### Environment Variable Restrictions

**Script Job**:

* ✅ Can use custom environment variables declared by `env`
* ✅ Can use environment variables imported via `imports`
* ✅ Can use CNB built-in system environment variables

**Plugin Job**:

* ❌ Cannot use custom environment variables declared by `env` (not passed)
* ❌ Cannot use environment variables imported via `imports` (not passed)
* ✅ Can use CNB built-in system environment variables
* ✅ Can reference environment variables via variable substitution in `settings` and `args`

```yaml
# Correct: Reference environment variables in settings
- name: correct plugin usage
  image: plugins/npm
  settings:
    username: $NPM_USER # ✅ Correct: Reference environment variables for variable substitution
    password: $NPM_PASS

# Incorrect: Attempt to pass parameters to plugin via env
- name: wrong plugin usage
  image: plugins/npm
  env:
    PLUGIN_USERNAME: $NPM_USER # ❌ Incorrect: This will not be passed to the plugin
    PLUGIN_PASSWORD: $NPM_PASS
```

## Best Practices

### 1. Version Control

**Plugin Job**: Always specify image version, avoid using `latest` tag to prevent plugin updates from causing pipeline failures.

```yaml
# Recommended: Specify version
- name: npm publish
  image: plugins/npm:1.2.3
  settings:
    username: $NPM_USER

# Not recommended: Using latest (plugin updates may cause configuration failures)
- name: npm publish
  image: plugins/npm # Defaults to latest
  settings:
    username: $NPM_USER
```

**Script Job**: Script logic follows code repository version control, no additional attention needed.

### 2. Security Considerations

**Plugin Job**:

* Use official or trusted plugin images
* Regularly check plugin image security updates
* Store sensitive information in secret vault

**Script Job**:

* Avoid hardcoding sensitive information in scripts
* Use environment variables to pass secrets
* Use secret vault to manage configuration

### 3. Reusability Considerations

**Plugin Job** is suitable for encapsulating reusable functionality:

* Message notifications (WeChat Work, Feishu, DingTalk, etc.)
* Generic CI/CD operations (publish, deploy, etc.)
* Code quality checks (lint, scanning, etc.)

These features can be published to the CNB plugin marketplace for other developers to use.

**Script Job** is suitable for business-related logic:

* Code building and testing
* Custom data processing
* Specific business workflows

These logic are often strongly related to the project and have lower reusability.

### 4. Selection Recommendations

| Scenario | Recommended Type | Reason |
|----------|-----------------|--------|
| Generic CI/CD operations (publish, deploy) | Plugin Job | Mature solutions available in plugin marketplace |
| Message notifications (WeChat, Feishu, DingTalk) | Plugin Job | Cohesive functionality, simple configuration |
| Code building and testing | Script Job | Flexible control, adapts to various tools |
| Custom business logic | Script Job | Need complete control over execution flow |
| Calling external APIs | Script Job | Flexible handling of various API formats |
| Generic functionality for reuse | Plugin Job | Can share to plugin marketplace |

## FAQ

### Q1: Why can't plugin jobs pass environment variables via env?

**A**: Plugin jobs are designed with functional modularity in mind, using `settings` to clearly define the parameters a plugin accepts rather than passing all environment variables. Benefits include:

* Clear plugin interface, avoiding parameter confusion
* Plugins can explicitly declare required parameters
* Improved security and maintainability

### Q2: Where do script jobs execute when image is not specified?

**A**: When a script job does not specify `image`, it executes in the pipeline container environment. The pipeline container environment is specified by `Pipeline.docker.image` or `Stage.image`.

```yaml
main:
  push:
    - docker:
        image: node:20 # Pipeline container environment
      stages:
        - name: without image
          # image not specified, executes in node:20 environment
          script: node -v

        - name: with image
          # Specify image, executes in python:3.9 environment
          image: python:3.9
          script: python --version
```

### Q3: How to use environment variables in plugin jobs?

**A**: Use variable substitution in `settings` or `args`.

```yaml
- name: plugin with env
  image: plugins/npm
  settings:
    username: $NPM_USER # Use variable substitution
    password: $NPM_PASS
```

### Q4: Can plugin jobs execute custom scripts?

**A**: Plugin job execution logic is preset by the plugin image and does not support executing custom scripts. If you need to execute custom scripts, use script jobs.

### Q5: How to decide whether to use script jobs or plugin jobs?

**A**: Ask yourself the following questions:

1. Is there an existing plugin that meets the requirements? → Use plugin job
2. Do you need flexible custom command execution? → Use script job
3. Can the functionality be reused and shared? → Consider plugin job
4. Is the functionality strongly related to business logic? → Use script job

## Summary

Script jobs and plugin jobs each have their advantages:

* **Script Job**: High flexibility, suitable for custom business logic
* **Plugin Job**: Cohesive functionality, easy to reuse and share

Choosing the appropriate job type can simplify configuration, improve reusability, while maintaining necessary flexibility.
