---
title: Migrating from DSL1
description: Migrate Nextflow pipelines from DSL1 to DSL2.
---

# Migrating from DSL1

In Nextflow version `22.03.0-edge`, DSL2 became the default DSL version. In version `22.12.0-edge`, DSL1 support was removed and the Nextflow documentation was updated to use DSL2 by default. Users who are still using DSL1 should migrate their pipelines to DSL2 to use the latest versions of Nextflow. This page describes the differences between DSL1 and DSL2 and how to migrate to DSL2.

## Processes and workflows

In DSL1, a process definition is also the process invocation. Process inputs and outputs are connected to channels using `from` and `into`. You can see a basic Nextflow script written in DSL1 here:

```nextflow
nextflow.enable.dsl=1

params.str = 'Hello world!'

process split_letters {
    output:
    file 'chunk_*' into letters

    script:
    """
    printf '${params.str}' | split -b 6 - chunk_
    """
}

process convert_to_upper {
    input:
    file x from letters.flatten()

    output:
    stdout result

    script:
    """
    cat $x | tr '[a-z]' '[A-Z]'
    """
}

result.view { it.trim() }
```

To migrate this code to DSL2, you need to move all of your channel logic throughout the script into a `workflow` definition. Additionally, you must call each process explicitly, passing any input channels as arguments (instead of `from ...`) and receiving any output channels as return values (instead of `into ...`).

See [Workflows][workflow-page] to learn how to define a workflow.

You can see the DSL1 Nextflow script from above written in DSL2 here:

```nextflow
params.str = 'Hello world!'

process split_letters {
    output:
    path 'chunk_*'

    script:
    """
    printf '${params.str}' | split -b 6 - chunk_
    """
}

process convert_to_upper {
    input:
    path x

    output:
    stdout

    script:
    """
    cat $x | tr '[a-z]' '[A-Z]'
    """
}

workflow {
    split_letters | flatten | convert_to_upper | view { v -> v.trim() }
}
```

## Channel forking

In DSL1, a channel can be used as an input only once; to use a channel multiple times, the channel must be forked using the `into` operator. In DSL2, channels are automatically forked when connecting two or more consumers. For example:

```nextflow
Channel
    .of('Hello','Hola','Ciao')
    .set { cheers }

cheers
    .map { v -> v.toUpperCase() }
    .view()

cheers
    .map { v -> v.reverse() }
    .view()
```

Similarly, in DSL2, process outputs can be consumed by multiple consumers automatically, which makes workflow scripts much easier to read and write.

## Includes

In DSL1, the entire Nextflow pipeline must be defined in a single file. For example, `main.nf`. This restriction becomes cumbersome as a pipeline grows and hinders the sharing and reuse of pipeline components.

DSL2 introduces the ability for scripts to *include* other scripts. While splitting a pipeline into multiple scripts is not mandatory in DSL2, it is useful for organizing a large pipeline and re-using modules created by others. See [Modules][module-page] for more information.

:::note
DSL2 scripts cannot exceed 64 KB in size. Split large DSL1 scripts into multiple smaller scripts to avoid this limit.
:::

## Deprecations

### Processes

- The `set` process input type is no longer supported, use [tuple][process-input-tuple] instead.
- The `set` process output type is no longer supported, use [tuple][process-out-tuple] instead.
- The `mode flatten` option for process outputs is no longer available. Use the [flatten][operator-flatten] operator on the corresponding output channel instead.
- Unqualified value and file elements in a tuple declaration are no longer allowed. Use an explicit `val` or `path` qualifier. For example:

  ```nextflow
  process sam2bam {
      input:
      tuple X, 'some-file.sam'

      output:
      tuple X, 'some-file.bam'

      script:
      """
      your_command --in $X some-file.sam > some-file.bam
      """
  }
  ```

  Use:

  ```nextflow
  process sam2bam {
      input:
      tuple val(X), path('some-file.sam')

      output:
      tuple val(X), path('some-file.bam')

      script:
      """
      your_command --in $X some-file.sam > some-file.bam
      """
  }
  ```

### Channels

- Channel factories should be accessed through the `channel` namespace instead of the `Channel` type, although they can still be accessed through either method.
- Channel method `bind` has been deprecated in DSL2.
- Channel method `<<` has been deprecated in DSL2.
- Channel factory `create` has been deprecated in DSL2.

### Operators

- Operator `choice` has been deprecated in DSL2. Use [branch][operator-branch] instead.
- Operator `close` has been deprecated in DSL2.
- Operator `countBy` has been deprecated in DSL2.
- Operator `into` has been deprecated in DSL2, as it is no longer needed.
- Operator `fork` has been renamed to [multiMap][operator-multimap].
- Operator `groupBy` has been deprecated in DSL2. Use [groupTuple][operator-grouptuple] instead.
- Operators `print` and `println` have been deprecated in DSL2. Use [view][operator-view] instead.
- Operator `route` has been deprecated in DSL2.
- Operator `separate` has been deprecated in DSL2.
- Operator `spread` has been deprecated in DSL2. Use [combine][operator-combine] instead.

### DSL2 Preview

An early preview of DSL2 was available in 2020. Note that some of that early DSL2 syntax has since changed.

- The `nextflow.preview.dsl=2` (and `nextflow.enable.dsl=1`) feature flags are no longer needed.

- Anonymous and unwrapped includes are no longer supported. Include each definition by name instead.

  For example:

  ```nextflow
  include './modules/hello'
  include bye from './modules/bye'

  workflow {
      hello()
      bye()
  }
  ```

  Should be replaced with:

  ```nextflow
  include { hello } from './modules/hello'
  include { bye } from './modules/bye'

  workflow {
      hello()
      bye()
  }
  ```

[module-page]: ../modules
[operator-branch]: ../reference/operator#branch
[operator-combine]: ../reference/operator#combine
[operator-flatten]: ../reference/operator#flatten
[operator-grouptuple]: ../reference/operator#grouptuple
[operator-multimap]: ../reference/operator#multimap
[operator-view]: ../reference/operator#view
[process-input-tuple]: ../process#input-tuples-tuple
[process-out-tuple]: ../process#output-tuples-tuple
[workflow-page]: ../workflow