Kestra is language agnostic. Use any programming language inside of your workflows.

Kestra works with any programming language with some having dedicated plugins to make it easier to use as well as libraries to make sending outputs and metrics back to Kestra easy.

Dedicated Plugins

Kestra currently supports the following programming languages with their own dedicated plugins:

  1. Python
  2. R
  3. Node.js
  4. Shell
  5. Powershell
  6. Julia
  7. Ruby

Each of them have the following subgroup of plugins:

  • Commands: Execute scripts from a command line interface (good for longer files that may be written separately)
  • Script: Write your code directly inside of your YAML (good for short scripts that don't need a dedicated file)

Script Example

In this example, the Python script is inline:

yaml
id: myflow
namespace: company.team

tasks:
  - id: "script"
    type: "io.kestra.plugin.scripts.python.Script"
    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})
    beforeCommands:
      - pip install requests kestra

Commands Example

In this example, the shell task is running dedicated commands, similar to how you would inside of your terminal.

yaml
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

Using Commands, you can run arbitrary commands in a Docker container. This means that you can use other languages as long as:

  1. Their dependencies can be packaged into a Docker image
  2. Their execution can be triggered from a Shell command line.

Below are a number of examples showing how you can do this with different programming languages.

For handling outputs and metrics, you can use the same approach that the Shell task uses by using ::{}:: syntax in log messages. Read more about it here.

Go

Here is an example flow that runs a Go file inside of a container using a golang image:

yaml
id: golang
namespace: company.team

tasks:
  - id: go
    type: io.kestra.plugin.scripts.shell.Commands
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: golang:latest
    namespaceFiles:
      enabled: true
    commands:
      - go run hello_world.go

The Go code is saved as a namespace file called hello_world.go:

go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

When executed, we can see the print statement in the Kestra logs:

golang_output

Check out the full guide which includes using outputs and metrics.

Rust

Here is an example flow that runs a Rust file inside of a container using a rust image:

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

rust
fn main() {
    println!("Hello, World!");
}

When executed, we can see the print statement 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 will allow 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:

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

java
class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

When executed, we can see the print statement 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:

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

c
#include <stdio.h>

int main() {
   printf("Hello, World!");
   return 0;
}

When executed, we can see the print statement 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:

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

cpp
#include <iostream>

int main() {
    std::cout << "Hello World!";
    return 0;
}

When executed, we can see the print statement in the Kestra logs:

cpp_output

TypeScript

You can execute TypeScript using the NodeJS plugin. To do so, we'll need to install TypeScript and compile our code to JavaScript using tsc.

Once we've done this, we can then execute it as we normally would with NodeJS. However, do note that our file is now a .js file.

yaml
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. We're going to save it as example.ts.

typescript
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, we can see the print statement in the Kestra logs:

ts_output

You can read more about Node.js with TypeScript here.

PHP

Here is an example flow that runs a PHP file inside of a container using a php image:

yaml
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
<?php
echo "Hello, World!";
?>

When executed, we can see the print statement in the Kestra logs:

php_output

Scala

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

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

scala
object HelloWorld {
    def main(args: Array[String]) = {
        println("Hello, World!")
    }
}

When executed, we can see the print statement 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:

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

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

When executed, we can see the print statement in the Kestra logs:

perl_output

Was this page helpful?