CLI Reference
skotch emit
Section titled “skotch emit”Compile a single .kt file to a target format. This is the lowest-level
entry point — it runs the full lex/parse/typeck/MIR/backend pipeline on
one source file and writes the output directly.
skotch emit --target <TARGET> <input.kt> -o <output>Targets
Section titled “Targets”| Target | Output | Description |
|---|---|---|
jvm | .class | Java 17 class file (v61) |
dex | .dex | Dalvik executable (v035) |
klib | .klib | Kotlin library (zip with serialized IR) |
llvm | .ll | Textual LLVM IR (19+) |
native | executable | Host binary (via LLVM IR + clang link) |
| Flag | Description |
|---|---|
--target <TARGET> | Required. One of jvm, dex, klib, llvm, native. |
-o <FILE> / --output <FILE> | Required. Output file path. |
--norm-out <FILE> | Write a normalized text representation alongside the binary output. Used for fixture testing. |
Examples
Section titled “Examples”# Compile to JVM bytecode and runskotch emit --target jvm hello.kt -o HelloKt.classjava -cp . HelloKt
# Compile to DEX (for Android)skotch emit --target dex hello.kt -o classes.dex
# Compile to LLVM IR (text)skotch emit --target llvm hello.kt -o hello.llcat hello.ll
# Compile to native binaryskotch emit --target native hello.kt -o hello./hello
# Emit a klib archiveskotch emit --target klib hello.kt -o hello.klibunzip -l hello.klibskotch build
Section titled “skotch build”Build a project from its build.gradle.kts. Discovers source files under
src/main/kotlin/, compiles them, and packages the result.
skotch build [-C <dir>] [--target <TARGET>]| Flag | Description |
|---|---|
-C <DIR> / --project-dir <DIR> | Project directory. Defaults to the current directory. |
--target <TARGET> | Override the build target: jvm, android, or native. By default, inferred from build.gradle.kts plugins. |
Output
Section titled “Output”| Target | Output path | Format |
|---|---|---|
| JVM | build/<name>.jar | Executable JAR with Main-Class manifest |
| Android | build/app-unsigned.apk | Unsigned APK with classes.dex and binary AndroidManifest.xml |
What Skotch reads from build.gradle.kts
Section titled “What Skotch reads from build.gradle.kts”Skotch parses a subset of the Gradle Kotlin DSL. It recognizes:
plugins { kotlin("jvm") // → JVM target id("com.android.application") // → Android target application // marker plugin}
group = "com.example"version = "1.0.0"
application { mainClass.set("com.example.MainKt") // JVM main class}
android { namespace = "com.example.app" compileSdk = 34 defaultConfig { applicationId = "com.example.app" minSdk = 24 targetSdk = 34 versionCode = 1 versionName = "1.0" }}Multi-module projects
Section titled “Multi-module projects”Skotch reads settings.gradle.kts to discover modules:
rootProject.name = "myapp"include(":app", ":lib")Inter-module project(":lib") dependencies in the dependencies block are
recognized. Modules are compiled in dependency order and their class files
are merged into the final JAR.
Examples
Section titled “Examples”# Build a JVM project (infers target from build.gradle.kts)skotch build
# Build from a specific directoryskotch build -C /path/to/project
# Override target to Androidskotch build --target android
# Build a multi-module projectcd myapp/skotch build # reads settings.gradle.kts, compiles :lib then :appskotch repl
Section titled “skotch repl”Interactive Kotlin REPL with line editing, backed by an in-process JVM via JNI.
skotch repl [--exec <CODE>] [--file <PATH>] [--exit-after]| Flag | Description |
|---|---|
-e <CODE> / --exec <CODE> | Execute a snippet before entering interactive mode. Separate statements with ;. |
-f <PATH> / --file <PATH> | Execute a script file before entering interactive mode. |
--exit-after | Exit after running --exec / --file instead of entering the interactive prompt. |
REPL commands
Section titled “REPL commands”| Command | Description |
|---|---|
:quit / :exit | Leave the REPL. |
:help | Show available commands. |
:history | Show accumulated declarations. |
How it works
Section titled “How it works”The REPL accumulates top-level declarations (val, var, fun) across
turns. Each expression you type is wrapped in a synthetic fun main() { }
along with all prior declarations, compiled to a .class file, and
executed in the embedded JVM.
skotch> val x = 10skotch> val y = 20skotch> println(x + y)30Line editing
Section titled “Line editing”The interactive REPL uses reedline for line editing:
- Arrow keys for cursor movement
- Up/Down for history browsing
- Ctrl-R for reverse history search
- Ctrl-C to abort the current line
- Ctrl-D to exit
Examples
Section titled “Examples”# Interactive REPLskotch repl
# Run a one-liner and exitskotch repl --exec 'println("hello")' --exit-after
# Load a setup script, then go interactiveskotch repl --file setup.kts
# Pipe input (non-interactive mode)echo 'println(1 + 2)' | skotch replskotch run
Section titled “skotch run”Execute a .kts Kotlin script file.
skotch run <script.kts>The script’s contents are wrapped in a synthetic fun main() { },
compiled, and executed. Top-level val and var declarations become
locals inside main.
# example.ktsval name = "Kotlin"println("Hello from $name script!")skotch run example.ktsHello from Kotlin script!skotch lsp
Section titled “skotch lsp”Start the Language Server Protocol server on stdin/stdout for use by editors (VS Code, Neovim, Helix, Zed, etc.).
skotch lspThe LSP server provides:
| Feature | Description |
|---|---|
| Real-time diagnostics | Syntax and type errors highlighted as you type |
| Semantic tokens | Syntax highlighting with semantic awareness (keywords, functions, types, variables, parameters) |
| Hover | Type information and signatures on hover (val x: Int, fun greet(n: String): String) |
| Go-to-definition | Navigate to function, parameter, and top-level val declarations |
| Completions | Keywords, scope identifiers, function signatures, Java class names |
Editor setup
Section titled “Editor setup”VS Code — add to settings.json:
{ "kotlin.languageServer.path": "skotch", "kotlin.languageServer.arguments": ["lsp"]}Neovim (nvim-lspconfig):
require('lspconfig.configs').skotch = { default_config = { cmd = { 'skotch', 'lsp' }, filetypes = { 'kotlin' }, root_dir = function(fname) return vim.fs.dirname(fname) end, },}require('lspconfig').skotch.setup({})skotch test
Section titled “skotch test”Discover and run tests.