Processes (typed)
New in version 25.10.0.
Warning
Typed processes are a preview feature. The syntax and behavior may change in future releases.
Typed processes use a new syntax for inputs and outputs based on static types.
nextflow.preview.types = true
process hello {
input:
message: String
output:
file('hello.txt')
script:
"""
echo '${message}' > hello.txt
"""
}
To use this feature:
Enable the strict syntax by setting the
NXF_SYNTAX_PARSERenvironment variable tov2:export NXF_SYNTAX_PARSER=v2
Set
nextflow.preview.types = truein every script that uses typed processes.
See Process (typed) for the complete syntax reference and Migrating to static types to migrate existing code to static types.
Inputs
The input: section declares process inputs. In typed processes, each input declaration consists of a name and type:
process fastqc {
input:
(meta, fastq): Tuple<Map,Path>
extra_args: String
script:
"""
echo 'meta: ${meta}`
echo 'fastq: ${fastq}'
echo 'extra_args: ${extra_args}'
"""
}
All standard types except for the dataflow types (Channel and Value) can be used as type annotations in processes.
File inputs
Nextflow automatically stages Path inputs and Path collections (such as Set<Path>) into the task directory.
Nullable inputs
By default, tasks fail if any input receives a null value. To allow null values, add ? to the type annotation:
process cat_opt {
input:
input: Path?
stage:
stageAs 'input.txt', input
output:
stdout()
script:
'''
[[ -f input.txt ]] && cat input.txt || echo 'empty input'
'''
}
Record inputs
Inputs with type Record can declare the name and type of each record field:
process fastqc {
input:
(id: String, fastq: Path): Record
script:
"""
echo 'id: ${id}`
echo 'fastq: ${fastq}'
"""
}
This pattern is called record destructuring. Each record field is staged into the task the same way as an individual input.
When the process is invoked, the incoming record should contain the specified fields, or else the run will fail. If the record has additional fields not declared by the process input, they are ignored.
Tip
Record inputs are a useful way to select a subset of fields from a larger record. This way, the process only stages what it needs, allowing you to keep related data together in your workflow logic.
Tuple inputs
Inputs with type Tuple can declare the name of each tuple component:
process fastqc {
input:
(id, fastq): Tuple<String,Path>
script:
"""
echo 'id: ${id}`
echo 'fastq: ${fastq}'
"""
}
This pattern is called tuple destructuring. Each tuple component is staged into the task the same way as an individual input.
The generic types inside the Tuple<...> annotation specify the type of each tuple compomnent and should match the component names. In the above example, id has type String and fastq has type Path.
Stage directives
The stage: section defines custom staging behavior using stage directives. It should be specified after the input: section. These directives serve the same purpose as input qualifiers such as env and stdin in the legacy syntax.
Environment variables
The env directive declares an environment variable in terms of task inputs:
process echo_env {
input:
hello: String
stage:
env 'HELLO', hello
script:
'''
echo "$HELLO world!"
'''
}
Standard input (stdin)
The stdin directive defines the standard input of the task script:
process cat {
input:
message: String
stage:
stdin message
script:
"""
cat -
"""
}
Custom file staging
The stageAs directive stages an input file (or files) under a custom file pattern:
process blast {
input:
fasta: Path
stage:
stageAs 'query.fa', fasta
script:
"""
blastp -query query.fa -db nr
"""
}
The file pattern can also reference task inputs:
process grep {
input:
id: String
fasta: Path
stage:
stageAs "${id}.fa", fasta
script:
"""
cat ${id}.fa | grep '>'
"""
}
See Inputs and outputs (typed) for available stage directives.
Outputs
The output: section declares the outputs of a typed process. Each output declaration consists of a name, an optional type, and an output value:
process echo {
input:
message: String
output:
out_env: String = env('MESSAGE')
out_file: Path = file('message.txt')
out_std: String = stdout()
script:
"""
export MESSAGE='${message}'
echo \$MESSAGE > message.txt
cat message.txt
"""
}
When there is only one output, the name can be omitted:
process echo {
input:
message: String
output:
stdout()
script:
"""
echo '${message}'
"""
}
See Inputs and outputs (typed) for available output functions.
File outputs
You can use the file() and files() functions in the output: section to get a single file or collection of files from the task directory.
By default, the file() function fails if the specified file is not present in the task directory. You can specify optional: true to allow missing files. The file() function returns null for missing files. For example:
process foo {
output:
file('output.txt', optional: true)
script:
"""
exit 0
"""
}
Structured outputs
Whereas legacy process outputs could only be structured using specific qualifiers like val and tuple, typed process outputs are regular values.
The record() standard library function can be used to create a record:
process fastqc {
input:
(id: String, fastq: Path): Record
output:
record(id: id, fastqc: file('fastqc_logs'))
script:
// ...
}
The tuple() standard library function can be used to create a tuple:
process fastqc {
input:
(id, fastq): Tuple<String,Path>
output:
tuple(id, file('fastqc_logs'))
script:
// ...
}
Topics
The topic: section emits values to topic channels. A topic emission consists of an output value and a topic name:
process cat {
input:
message: Path
output:
stdout()
topic:
tuple('bash', eval('bash --version')) >> 'versions'
tuple('cat', eval('cat --version')) >> 'versions'
script:
"""
cat ${message}
"""
}
Topic emissions can use the same output functions as the output: section.
Script
The script: and exec: sections behave the same way as legacy processes.
Stub
The stub: section behaves the same way as legacy processes.
Directives
Directives behave the same way as legacy processes.