Migrating to 26.04 (preview)
This page summarizes the upcoming changes in Nextflow 26.04, which will be released in April 2026.
Note
This page is a work in progress and will be updated as features are finalized. It should not be considered complete until the 26.04 release.
New features
Module system
Nextflow now has native support for publishing, installing, running, and including remote modules using the Nextflow registry.
The new module command can be used to work with remote modules:
# Run a module directly
nextflow module run nf-core/fastqc --meta.id 1 --reads sample1.fastq
# Search for modules in registry
nextflow module search bwa
# Get info about a module
nextflow module info nf-core/bwa/mem
# Install a module
nextflow module install nf-core/bwa/mem
Remotes modules are installed into the modules directory of your project. They can be included in scripts by name instead of relative path:
// before
include { BWA_MEM } from '../../../modules/nf-core/bwa/mem'
// after
include { BWA_MEM } from 'nf-core/bwa/mem'
Note
All nf-core modules are automatically synced to the registry from GitHub. They are available as nf-core/<name> as shown above.
See Registry-based modules and the module command reference for details.
Record types
Records are a new data structure for modeling composite data. They serve as an alternative to tuples – whereas tuple elements must be accessed by index, record fields are accessed by name. This allows you to model data with meaningful names instead of keeping track of how tuple elements are ordered.
A record can be created using the record() function:
sample = record(
id: '1',
fastq_1: file('1_1.fastq'),
fastq_2: file('1_2.fastq')
)
println sample.id
println sample.foo // error: unrecognized property `foo`
Record types are a way to define custom types for validating records:
record Sample {
id: String
fastq_1: Path
fastq_2: Path?
}
While records created with the record() function can have any set of fields, record types can be used to specify a minimum set of requirements in a particular context, such as a process, function, or workflow:
def hello(sample: Sample) {
println "Hello sample ${sample.id}!"
}
workflow {
sample1 = record(id: '1', fastq_2: file('1_2.fastq'))
hello(sample1) // error: `sample1` is missing `fastq_1` field required by Sample
sample2 = record(id: '1', fastq_1: file('1_1.fastq'))
hello(sample2) // ok
sample3 = record(id: '1', single_end: true, fastq_1: file('1_1.fastq'))
hello(sample3) // also ok
}
See Records for details. See Migrating to static typing for more information about migrating from tuples to records.
Static typing (preview)
Note
Typed processes and typed workflows require the nextflow.preview.types feature flag to be enabled in every script that uses them.
Nextflow 26.04 brings full support for static typing with typed processes and typed workflows.
Typed processes can now declare record inputs and outputs:
nextflow.preview.types = true
process FASTQC {
input:
record(
id: String,
fastq_1: Path,
fastq_2: Path
)
output:
record(
id: id,
fastqc: file('fastqc_logs')
)
script:
// ...
}
Typed workflows can declare typed inputs and outputs, and provide first-class support for static typing in dataflow logic:
nextflow.preview.types = true
workflow RNASEQ {
take:
read_pairs_ch: Channel<Sample>
transcriptome: Path
main:
index = INDEX(transcriptome)
fastqc_ch = FASTQC(read_pairs_ch)
quant_ch = QUANT(read_pairs_ch, index)
samples_ch = fastqc_ch.join(quant_ch, by: 'id')
emit:
samples: Channel<AlignedSample> = samples_ch
}
record Sample { /* ... */ }
record AlignedSample { /* ... */ }
Several operators have been extended to support static typing and records:
combinecan now combine records or tuplesgroupBycan group channel values while being statically typed (replacesgroupTuple)joincan now join records by matching field
Breaking changes from the first preview:
The syntax for process tuple inputs has been updated:
// 25.10 input: (id, fastq_1, fastq_2): Tuple<String,Path,Path> // 26.04 input: tuple(id: String, fastq_1: Path, fastq_2: Path)
The method signature for the
stageAsdirective was changed from(filePattern, value)to(value, filePattern).The
nextflow.preview.typesfeature flag must be enabled in order to use type annotations in workflow takes/emits.
See Migrating to static typing for more information about migrating to static typing. See Using operators with static typing for best practices on using operators with static typing.
Enhancements
Strict syntax parser enabled by default
The strict syntax parser is now enabled by default. This change brings the rich error checking of nextflow lint to nextflow run, and makes it easier to adopt new language features.
The legacy parser can be re-enabled by setting the NXF_SYNTAX_PARSER environment variable to v1.
Agent logging mode
Nextflow prints logs in an agent-friendly format when enabled via NXF_AGENT_MODE=1:
$ NXF_AGENT_MODE=1 nextflow run [...]
[PIPELINE] nf-core/rnaseq 3.14.0 | profile=test,docker
[WORKDIR] /path/to/work
[PROCESS b8/623fc3] sayHello (3)
[PROCESS 5f/761e51] sayHello (2)
[WARN] Task runtime metrics are not reported when using macOS
[ERROR] FASTQC (sample_1)
exit: 127
cmd: fastqc --version
stderr: bash: fastqc: command not found
workdir: /path/to/work/ab/123456
[SUCCESS] completed=10 failed=0 cached=5
Agent mode provides minimal structured logging for efficient token usage. It is ideal when using agents to run and debug Nextflow runs.
Multi-revision checkout for pipelines
Nextflow now checks out pipelines separately by revision when running remote pipelines, allowing you to run multiple revisions of a pipeline at the same time.
Nextflow uses the default branch specified by the Git repository when no revision is specified, instead of defaulting to the master branch. Since each revision is checked out separately, using a specific revision doesn’t prevent the use of the default branch on subsequent runs.
Because of this update, the manifest.defaultBranch config option is no longer needed.
Load collection-type params automatically from files
When using the params block, collection-type parameters such as List<Record> can be loaded automatically from a CSV, JSON, or YAML file. This feature simplifies the loading of samplesheet inputs and allows a pipeline to support multiple structured data formats.
See Typed parameters for details. See Migrating to static typing for a migration example.
Print workflow outputs on run completion
Nextflow prints a summary of the workflow outputs at the end of a run, when the output block is defined.
For example, given the following output block:
workflow {
// ...
}
output {
samples {
path { sample -> "${sample.id}" }
index {
path 'samples.csv'
}
}
multiqc_report {
path 'multiqc_report.html'
}
}
Nextflow prints the following summary:
$ nextflow -q run main.nf
Outputs:
/path/to/results
samples: samples.csv
multiqc_report: multiqc_report.html
You can specify -output-format json to produce JSON output instead:
$ nextflow -q run main.nf -output-format json
{
"samples": "/path/to/results/samples.csv",
"multiqc_report": "/path/to/results/multiqc_report.html"
}
The module run command prints a summary of the module outputs:
$ nextflow -q module run nf-core/fastqc --meta.id 1 --reads sample1.fastq -output-format json
{
"html": [
{
"id": "SRR6357070_1"
},
"/path/to/results/SRR6357070_1_fastqc.html"
],
"zip": [
{
"id": "SRR6357070_1"
},
"/path/to/results/SRR6357070_1_fastqc.zip"
]
}
See the run command reference for details.
New -project-dir option for lint command
The lint command now has a -project-dir option, which can be used to specify the project root when linting files.
For example, given the following project structure:
├── lib
│ └── Utils.groovy
├── modules
│ └── nf-core
│ └── fastqc
│ ├── main.nf
│ └── ...
├── workflows
│ └── rnaseq.nf
├── main.nf
└── nextflow.config
You can specify -project-dir when linting from a location other than the project root:
cd workflows
nextflow lint -project-dir ../ rnaseq.nf
This option allows the linter to resolve remote module includes and Groovy code in the lib directory:
// workflows/rnaseq.nf
include { FASTQC } from 'nf-core/fastqc'
workflow RNASEQ {
// ...
Utils.validateInput( /* ... */ )
// ...
}
See the lint command reference for details.
Breaking changes
The strict syntax parser is now enabled by default. The legacy parser can be enabled by setting the
NXF_SYNTAX_PARSERenvironment variable tov1.
Deprecations
The
nextflow.enable.strictfeature flag is deprecated. It is not needed when strict syntax is enabled.The
manifest.defaultBranchconfig option is deprecated. Nextflow can automatically detect the default branch when using a remote pipeline.The Path
listFiles()method is deprecated. UselistDirectory()instead.Several operators have been deprecated. See Operators (legacy) for details.
Miscellaneous
New config option:
aws.batch.forceGlacierTransferNew config option:
executor.onlyJobStateNew config option:
google.batch.installOpsAgentNew config option:
google.batch.logsPathNew config option:
wave.build.conda.baseImageNew config option:
wave.build.templateNew standard library function:
listDirectory()Support Java 26