Skip to content

The kiwi Command

kiwi [options] [script] [arguments]
CommandWhat it does
kiwi script.kiwiRun a script.
kiwiStart the REPL when stdin is a terminal.
kiwi -e 'code'Run a string of code.
echo 'code' | kiwiRun code piped on stdin.
kiwi -d script.kiwiRun a script in the debugger.
kiwi -c script.kiwiCheck a script for syntax errors without running it.

Scripts run from top to bottom. There is no entry-point function; if you define a main function, call it yourself. The standard library is loaded first, so every package is available without importing it.

A script can start with a shebang line and be run directly once it is executable:

#!/usr/bin/env kiwi
println "Hello from a script"
Terminal window
chmod +x hello.kiwi
./hello.kiwi

-e runs the code that follows it. Use shell $'...' quoting to include newlines:

Terminal window
kiwi -e 'println 6 * 7'
kiwi -e $'for i in [1 to 3] do\n println i\nend'

When no script is given and stdin is not a terminal, Kiwi reads the whole of stdin as a program and runs it:

Terminal window
echo 'println "Hello from a pipe"' | kiwi
cat script.kiwi | kiwi -env=prod

To process piped data instead of code, run a script and read stdin with the stdin package.

Options go before the script; the first argument that isn’t an option is the script, and everything after it belongs to the script. Only one of -e, -c, -d, -a, -t, -i, -n, -s and -v can be used at a time, except that -h overrides the rest. A mistake, such as an unknown option or a script that doesn’t exist, is reported on stderr with exit code 1.

OptionDescription
-h, --helpPrint usage and the list of options.
-v, --versionPrint the version.
-i, --interactiveStart the REPL, even when stdin isn’t a terminal.
-e, --execute <code>Run a string of code.
-c, --check <file>Report every syntax error in a file without running it. Exits 0 if the file is clean and 1 otherwise.
-d, --debug <file>Run a file in the kdb debugger.
-a, --ast <file>Print a file’s syntax tree.
-t, --tokens <file>Print a file’s tokens.
-n, --new <name>Create an empty script, adding .kiwi if needed. Refuses to overwrite an existing file.
-sm, --safemodeDisable file, network, process and system access (see below).
-ns, --no-stdlibDon’t load the standard library.
-p, --stdlib-path <dirs>Load the standard library from other locations instead, separated by ; (see below).
-cd, --crash-dumpAppend errors to kiwi_crash.log in the current directory.
-s, --settingsPrint the interpreter settings.
-<key>=<value>Pass a named argument to the script.
--End the options. What follows is the script and its arguments, even if they start with -.

--check parses the file (and the standard library) and reports every syntax error, not just the first, which makes it useful in editors and CI:

$ kiwi -c broken.kiwi
[SyntaxError]: Unexpected token `*`.
File: broken.kiwi:1:9
x = 1 + *
^
[SyntaxError]: Unexpected token `+`.
File: broken.kiwi:2:7
$ kiwi -c hello.kiwi
No syntax errors found in: hello.kiwi

--stdlib-path replaces the standard library with the locations you give it. Separate several with ;, or repeat the option (it isn’t valid in a path, unlike : in C:\kiwi\lib). Each one can be a directory, whose scripts are all loaded, or a single script. Quote the value so the shell doesn’t treat ; as the end of the command:

$ kiwi -p "/opt/kiwi/lib;~/kiwi/mylibs" app.kiwi

To add your own scripts and keep the standard library, include its directory in the list. env::lib() returns the first location that is a directory, so put the standard library first if scripts rely on it.

--safemode runs untrusted code without access to the outside world. These packages throw a SafeModeError when used: fio, http, httpserver, socket, tls, udp, ipc, smtp, signal, sys, ffi, native::load and crypto::file_hash, and env::set is blocked.

$ kiwi -sm -e 'fio::read("secrets.txt")'
[SafeModeError]: 'fio' is not available in safe mode.

--tokens and --ast show how Kiwi reads a file, which helps when a syntax error is confusing:

$ kiwi -a hello.kiwi
Generating AST: hello.kiwi
Program:
PrintLine:
Literal: "Hello, World!"

Everything after the script path is passed to the script, including arguments that look like kiwi options. A -key=value argument before the script is passed to it too. With -e, the arguments after the code are passed to it. Read arguments with the env package:

  • env::args() returns the raw arguments as a list, in order.
  • env::argv() returns them parsed into a hashmap. -key=value becomes key: "value", a bare --flag becomes flag: "true", and a positional argument maps to itself.
args.kiwi
println env::args()
println env::argv()
$ kiwi args.kiwi report.csv -limit=10 --verbose
["report.csv", "-limit=10", "--verbose"]
{"report.csv": "report.csv", "limit": "10", "verbose": "true"}

Use env::args() for positional arguments. Because env::argv() is a hashmap, repeated positional values collapse into one key.

For anything beyond a couple of options, use cli::CliParser from the cli package, which handles flags, typed options, defaults and help text.

CodeMeaning
0The script finished normally.
1An uncaught error, a failed --check, or a bad command-line option, such as an unknown flag or a missing value.
nThe script called exit n.

kiwi-settings.json, next to the kiwi binary, configures where the standard library lives, which file extensions count as Kiwi scripts, the default for safe mode, and the crash log path. Print the active settings with kiwi -s.