Supported Programming Languages in Kestra icon 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:

  1. Python
  2. R
  3. Node.js
  4. Shell
  5. PowerShell
  6. Julia
  7. Ruby
  8. Go
  9. Deno
  10. Lua
  11. Bun
  12. PHP
  13. Perl
  14. Groovy

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: myflow
namespace: 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: myflow
namespace: 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.txt

Run 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:

  1. Its dependencies can be included in a Docker image.
  2. 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: rust
namespace: 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_world

The 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:

rust_output

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: java
namespace: 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 HelloWorld

The 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:

java_output

C

Here is an example flow that runs a C file inside of a container using a gcc image:

id: c
namespace: 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.out

The 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_output

C++

Here is an example flow that runs a C++ file inside of a container using a gcc image:

id: cplusplus
namespace: 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.out

The 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:

cpp_output

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: typescript
namespace: 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.js

This 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:

ts_output

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: php
namespace: 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.php

The PHP code is saved as a namespace file called hello_world.php:

<?php
echo "Hello, World!";
?>

When executed, the print statement is displayed in the Kestra logs:

php_output

There is a dedicated PHP plugin. An example flow might look like the following using a script task:

id: php_script
namespace: 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_commands
namespace: company.team
tasks:
- id: commands
type: io.kestra.plugin.scripts.php.Commands
inputFiles:
main.php: |
#!/usr/bin/php
<?php
echo "Hello, World!\\n";
?>
commands:
- php main.php

Scala

Here is an example flow that runs a Scala file inside of a container using a sbtscala/scala-sbt image:

id: scala
namespace: 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 HelloWorld

The 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:

scala_output

Perl

Here is an example flow that runs a Perl file inside of a container using a perl image:

id: perl
namespace: 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.pl

The Perl code is saved as a namespace file called hello_world.pl:

#!/usr/bin/perl
use warnings;
print("Hello, World!\n");

When executed, the print statement is displayed in the Kestra logs:

perl_output

There is a dedicated Perl plugin. An example flow might look like the following using a script task:

id: perl_inline
namespace: company.team
tasks:
- 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_commands
namespace: company.team
tasks:
- 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:latest
USER root
## Install Go
RUN 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 Docker
ENV 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:latest

Once 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_process
namespace: 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.csv

Was this page helpful?