Supported Programming Languages in Kestra
Kestra is language agnostic — you can use any programming language inside your workflows.
Choose languages and plugins for script tasks
Kestra works with any programming language, with some having dedicated plugins and libraries that make it easier to send outputs and metrics back to Kestra.
Dedicated plugins
Kestra currently supports the following programming languages with dedicated plugins:
Each of these plugins provides two task types:
- Commands: Execute scripts using a command-line interface (ideal for longer, pre-written files).
- Script: Write your code directly in YAML (best for short inline scripts).
Script example
An example of an inline Python script:
id: myflownamespace: company.team
tasks: - id: script type: io.kestra.plugin.scripts.python.Script beforeCommands: - pip install requests kestra script: | from kestra import Kestra import requests
response = requests.get('https://google.com') print(response.status_code)
Kestra.outputs({'status': response.status_code, 'text': response.text})Commands example
An example using Shell commands, similar to a terminal session:
id: myflownamespace: company.team
tasks: - id: commands type: io.kestra.plugin.scripts.shell.Commands outputFiles: - first.txt - second.txt commands: - echo "1" >> first.txt - echo "2" >> second.txtRun any language using the Shell task
With the Commands task, you can execute arbitrary commands inside a Docker container. This means you can run any language, as long as:
- Its dependencies can be included in a Docker image.
- It can be executed from a Shell command.
For handling outputs and metrics, use the same ::{}:: syntax as the Shell task.
Read more in Shell outputs and metrics.
Rust
Here is an example flow that runs a Rust file inside of a container using a rust image:
id: rustnamespace: company.team
tasks: - id: rust type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: rust:latest namespaceFiles: enabled: true commands: - rustc hello_world.rs - ./hello_worldThe Rust code is saved as a namespace file called hello_world.rs:
fn main() { println!("Hello, World!");}When executed, the print statement is displayed in the Kestra logs:

Check out the full guide which includes using outputs and metrics.
Java
You can build custom plugins in Java which enable you to add custom tasks to your workflows. If you’re looking to execute something simpler, you can use the Shell task with a Docker container.
Here is an example flow that runs a Java file inside of a container using a eclipse-temurin image:
id: javanamespace: company.team
tasks: - id: java type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: eclipse-temurin:latest namespaceFiles: enabled: true commands: - javac HelloWorld.java - java HelloWorldThe Java code is saved as a namespace file called HelloWorld.java:
class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); }}When executed, the print statement is displayed in the Kestra logs:

C
Here is an example flow that runs a C file inside of a container using a gcc image:
id: cnamespace: company.team
tasks: - id: c type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: gcc:latest namespaceFiles: enabled: true commands: - gcc hello_world.c - ./a.outThe C code is saved as a namespace file called hello_world.c:
#include <stdio.h>
int main() { printf("Hello, World!"); return 0;}When executed, the print statement is displayed in the Kestra logs:

C++
Here is an example flow that runs a C++ file inside of a container using a gcc image:
id: cplusplusnamespace: company.team
tasks: - id: cpp type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: gcc:latest namespaceFiles: enabled: true commands: - g++ hello_world.cpp - ./a.outThe C++ code is saved as a namespace file called hello_world.cpp:
#include <iostream>
int main() { std::cout << "Hello World!"; return 0;}When executed, the print statement is displayed in the Kestra logs:

TypeScript
You can execute TypeScript using the NodeJS plugin. To do so, you need to install TypeScript and compile our code to JavaScript using tsc.
Once done, you can then execute with NodeJS. However, do note that the file is now a .js file.
id: typescriptnamespace: company.team
tasks: - id: ts type: io.kestra.plugin.scripts.node.Commands namespaceFiles: enabled: true commands: - npm i -D typescript - npx tsc example.ts - node example.jsThis example can be found in the Node.js docs. The file is saved as example.ts.
type User = { name: string; age: number;};
function isAdult(user: User): boolean { return user.age >= 18;}
const justine: User = { name: 'Justine', age: 23,};
const isJustineAnAdult: boolean = isAdult(justine);console.log(isJustineAnAdult)When executed, the print statement is displayed in the Kestra logs:

For more information, you can read more about Node.js with TypeScript on their official site.
PHP
Here is an example flow that runs a PHP file inside of a container using a php image:
id: phpnamespace: company.team
tasks: - id: php type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: php:8.4-rc-alpine namespaceFiles: enabled: true commands: - php hello_world.phpThe PHP code is saved as a namespace file called hello_world.php:
<?phpecho "Hello, World!";?>When executed, the print statement is displayed in the Kestra logs:

There is a dedicated PHP plugin. An example flow might look like the following using a script task:
id: php_scriptnamespace: company.team
tasks: - id: script type: io.kestra.plugin.scripts.php.Script script: | #!/usr/bin/php <?php echo "Hello, World!\\n"; ?>Check out the following example for the commands task:
id: php_commandsnamespace: company.teamtasks: - id: commands type: io.kestra.plugin.scripts.php.Commands inputFiles: main.php: | #!/usr/bin/php <?php echo "Hello, World!\\n"; ?> commands: - php main.phpScala
Here is an example flow that runs a Scala file inside of a container using a sbtscala/scala-sbt image:
id: scalanamespace: company.team
tasks: - id: scala type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: sbtscala/scala-sbt:eclipse-temurin-17.0.4_1.7.1_3.2.0 namespaceFiles: enabled: true commands: - scalac HelloWorld.scala - scala HelloWorldThe Scala code is saved as a namespace file called HelloWorld.scala:
object HelloWorld { def main(args: Array[String]) = { println("Hello, World!") }}When executed, the print statement is displayed in the Kestra logs:

Perl
Here is an example flow that runs a Perl file inside of a container using a perl image:
id: perlnamespace: company.team
tasks: - id: perl type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker containerImage: perl:5.41.2 namespaceFiles: enabled: true commands: - perl hello_world.plThe Perl code is saved as a namespace file called hello_world.pl:
#!/usr/bin/perluse warnings;print("Hello, World!\n");When executed, the print statement is displayed in the Kestra logs:

There is a dedicated Perl plugin. An example flow might look like the following using a script task:
id: perl_inlinenamespace: company.teamtasks: - id: perl_script type: io.kestra.plugin.scripts.perl.Script script: | my $message = "Hello from an inline Perl script!"; print $message . "\\n";Check out the following example for the commands task:
id: perl_commandsnamespace: company.teamtasks: - id: perl type: io.kestra.plugin.scripts.perl.Commands commands: - perl -e 'print "Hello from Kestra!Run any language using a custom Docker image
You can pre-install any language using a custom Docker image and use the Process Task Runner to execute it. Example using Go:
FROM kestra/kestra:latestUSER root
## Install GoRUN apt-get update -y && apt-get install -y wget && \ wget -qO- https://go.dev/dl/go1.24.3.linux-amd64.tar.gz | tar -C /usr/local -xzf - && \ echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/golang.sh
## Set Go environment variables for DockerENV PATH="/usr/local/go/bin:${PATH}"Then, point to that Dockerfile in your docker-compose.yml file:
services: kestra: build: context: . dockerfile: Dockerfile image: kestra-go:latestOnce you start Kestra using docker compose up -d, you can create a flow that directly runs Go tasks with your custom dependencies using the io.kestra.plugin.core.runner.Process task runner:
id: golang_processnamespace: company.team
tasks: - id: go_custom_dependencies type: io.kestra.plugin.scripts.go.Script taskRunner: type: io.kestra.plugin.core.runner.Process beforeCommands: - go mod init go_script - go get github.com/go-gota/gota/dataframe - go mod tidy script: | package main import ( "os" "github.com/go-gota/gota/dataframe" "github.com/go-gota/gota/series" ) func main() { names := series.New([]string{"Alice", "Bob", "Charlie"}, series.String, "Name") ages := series.New([]int{25, 30, 35}, series.Int, "Age") df := dataframe.New(names, ages) file, _ := os.Create("output.csv") df.WriteCSV(file) defer file.Close() } outputFiles: - output.csvWas this page helpful?