{"id":13611139,"url":"https://github.com/pgreze/kyper","last_synced_at":"2025-09-19T11:32:32.391Z","repository":{"id":65507768,"uuid":"584096495","full_name":"pgreze/kyper","owner":"pgreze","description":"Functional Kotlin friendly way to create command line applications.","archived":false,"fork":false,"pushed_at":"2023-08-17T08:49:14.000Z","size":109,"stargazers_count":17,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-07T17:50:19.954Z","etag":null,"topics":["kotlin","kotlin-cli","kotlin-functional-programming"],"latest_commit_sha":null,"homepage":"https://pgreze.github.io/kyper/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgreze.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-01T10:45:43.000Z","updated_at":"2023-12-20T16:44:27.000Z","dependencies_parsed_at":"2024-01-16T23:31:11.379Z","dependency_job_id":"9c09be50-c90b-48ac-9f43-d04ecd2f96f5","html_url":"https://github.com/pgreze/kyper","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgreze%2Fkyper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgreze%2Fkyper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgreze%2Fkyper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgreze%2Fkyper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgreze","download_url":"https://codeload.github.com/pgreze/kyper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233570373,"owners_count":18695852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","kotlin-cli","kotlin-functional-programming"],"created_at":"2024-08-01T19:01:52.161Z","updated_at":"2025-09-19T11:32:32.381Z","avatar_url":"https://github.com/pgreze.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# kyper [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![](https://github.com/pgreze/kyper/actions/workflows/main.yml/badge.svg)](https://github.com/pgreze/kyper/actions/workflows/main.yml) [![codecov](https://codecov.io/gh/pgreze/kyper/branch/main/graph/badge.svg?token=T5R37803P4)](https://codecov.io/gh/pgreze/kyper)\n\nFunctional Kotlin friendly way to create command line applications.\n\nIt comes from the basic need to have a function like:\n\n```kotlin\n@Commmand(\"function help message\")\nfun main(\n    @Parameter(\"the name to greet\")\n    name: String,\n) {\n    println(\"hello $name\")\n}\n```\n\nand turns it into a Kotlin script powered command line application:\n\n```bash\n$ ./script.main.kts there\nhello there\n```\n\n\u003e Kyper? Is it a name?\n\nThis library is hugely inspired by the wonderful [typer](https://typer.tiangolo.com/)\nfrom the Python ecosystem.\n\nAlso naming is hard 😇\n\n\u003e But we already have [clikt](https://ajalt.github.io/clikt/)? (or any alternative)\n\nCorrect, but I try to keep my Kotlin scripts as small as possible,\nand having to deal with classes is not what I would describe as simple.\n\nAlso chained property delegates are great,\nbut I always need to read the documentation to figure out all the options.\n\n\u003e So let's migrate everything to this wonderful library?\n\nFor simple usecases like Kotlin scripts, feel free.\n\nFor more complex applications, where readability is important,\nI would stick with [clikt](https://ajalt.github.io/clikt/)\nor any alternative not relying on ~magic~ reflection\nand/or implicit behaviors like this library is doing.\n\n## Installation  [![central](https://maven-badges.herokuapp.com/maven-central/com.github.pgreze/kyper/badge.svg?style={style})](https://search.maven.org/artifact/com.github.pgreze/kyper) ![](https://img.shields.io/badge/Java-11-blue) [![](https://img.shields.io/badge/Kotlin-1.7.22-blue)](https://kotlinlang.org/)\n\n```kotlin\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    // Check the 🔝 maven central badge 🔝 for the latest $kyperVersion\n    implementation(\"com.github.pgreze:kyper:$kyperVersion\")\n}\n```\n\nOr in your kotlin script:\n\n```kotlin\n@file:DependsOn(\"com.github.pgreze:kyper:$kyperVersion\")\n```\n\n## Usage with function(s)\n\n### Start with a single function\n\nWe can start by defining a simple function handling our logic:\n\n```kotlin\n#!/usr/bin/env kotlinc -script\n\nimport com.github.pgreze.kyper.Command\nimport com.github.pgreze.kyper.Parameter\nimport com.github.pgreze.kyper.kyper\n\n@Commmand(\"function help message\")\nfun main(\n    @Parameter(\"the name to greet\")\n    name: String,\n) {\n    println(\"hello $name\")\n}\n\nkyper().invoke(args)\n```\n\nAnd run it with the name parameter:\n\n```bash\n$ ./script.main.kts there\nhello there\n```\n\nNotice we also defined help messages for both the command and its parameter:\n\n```bash\n$ # Use `--` to indicate that the following arguments are for the script, not kotlinc itself\n$ ./script.main.kts -- --help\nUsage: main NAME\n\n  function help message\n\nOptions:\n  -h, --help      Show this message and exit\n\nArguments:\n  NAME  the name to greet\n```\n\n### Only @Command annotated methods are exported\n\nOur script can declare more methods, without exposing them as command:\n\n```kotlin\n#!/usr/bin/env kotlinc -script\n\nimport com.github.pgreze.kyper.Command\nimport com.github.pgreze.kyper.kyper\n\n@Command\nfun main(name: String) {\n    greet(name)\n}\n\nfun greet(name: String) {\n    println(\"Hello $name\")\n}\n\nkyper().invoke(args)\n```\n\nUsage is the same:\n\n```bash\n$ ./script.main.kts there\nhello there\n```\n\nBut having several `@Command` functions will turn our application into a multi-command mode:\n\n```kotlin\n#!/usr/bin/env kotlinc -script\n\nimport com.github.pgreze.kyper.Command\nimport com.github.pgreze.kyper.kyper\n\n@Command(\"Say hello in English\")\nfun hello(name: String) {\n    println(\"hello $name\")\n}\n\n@Command(\"Say hello in French\")\nfun bonjour(name: String) {\n    println(\"bonjour $name\")\n}\n\nkyper(help = \"Say hello to your user\").invoke(args)\n```\n\nWe can now notice several commands are available by calling --help:\n\n```bash\n$ ./kyper/hellos.main.kts -- --help\nUsage: [OPTIONS] COMMAND [ARGS]...\n\n  Say hello to your user\n\nOptions:\n  -h, --help      Show this message and exit\n\nCommands:\n  BONJOUR  Say hello in French\n  HELLO    Say hello in English\n```\n\nEach command can be requested for `--help`:\n```\n$ ./kyper/hellos.main.kts -- --help bonjour\nUsage: bonjour NAME\n\n  Say hello in French\n\nOptions:\n  -h, --help      Show this message and exit\n\nArguments:\n  NAME\n```\n\n### Handle more than strings as arguments\n\nThe following types are supported:\n\n```kotlin\nfun main(\n    string: String = \"arg\",\n    int: Int = 1,\n    float: Float = 1.2f,\n    double: Double = 3.14,\n    long: Long = Long.MAX_VALUE,\n    boolean: Boolean = true,\n    bigInteger: BigInteger = BigInteger.valueOf(12),\n    bigDecimal: BigDecimal = BigDecimal.valueOf(12.3),\n    file: File = File(\"file\"),\n    path: Path = Path.of(\"path\"),\n    choice: Choice = Choice.NO,\n    vararg strings: String, // For vararg, only String/File are supported.\n) {\n    TODO()\n}\n\nenum class Choice { YES, NO }\n```\n\n### Default values (unstable)\n\nAs shown in the last code block,\ndefault values are supported\nas long as they're at the end of the method.\n\n🚨️ WIP: the current implementation is quite simple; it is\njust based on parameter positioning,\nand does not allow any `--flag` logic.\n\n## Usage with lambda(s) (experimental)\n\nIf the Kotlin DSL syntax is something you're looking for in your Kotlin script,\nthis library also provides a similar syntax based on lambdas:\n\n```kotlin\n#!/usr/bin/env kotlinc -script\n\n@file:Suppress(\"OPT_IN_USAGE\")\n\nimport com.github.pgreze.kyper.kyper\n\nkyper(help = \"Run multiple commands from Kotlin script with ease\") {\n    register(name = \"time\", help = \"Display current timestamp\") { -\u003e\n        println(System.currentTimeMillis())\n    }\n\n    register(name = \"greet\") { name -\u003e\n        println(\"Hello $name\")\n    }\n}.invoke(args)\n```\n\nBut this comes with restrictions:\n- no default argument(s),\n- up to 4 arguments,\n- only String type is supported.\n\nThis may be dropped in the future if we cannot reach\nthe same support level as the functions-based usage.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgreze%2Fkyper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgreze%2Fkyper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgreze%2Fkyper/lists"}