CLI tool
koto-lang/koto avatar
koto-lang/koto

Koto: a small scripting language you can embed in a Rust program

A simple, expressive, embeddable programming language

887 stars48 forksRustMIT

At a glance

What is it?
Koto is a Rust implementation of a simple and expressive programming language that works either as a standalone scripting language or as an extension language inside a Rust application, with a compiler pipeline split across lexer, parser, bytecode and runtime crates. The interesting part is not the language itself but the shape of the workspace, where a second memory configuration is tested alongside the default one and the documentation is compiled with warnings as errors.
Who is it for?
Adopt Koto if you want to give users of a Rust application a scripting layer, or if you want a small scripting language for your own tooling, and if you are willing to track a language that is still under active development. Do not adopt it if you need a language with a large package ecosystem or a long track record of compatibility, since the version line is still in the zero series and the project is tested against the latest stable Rust rather than a pinned minimum.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 78 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem: a scripting layer for a Rust program

Plenty of applications need a language that is not the one they are written in. A build tool needs a configuration language. A game needs a way for designers to change behaviour without a recompile. A simulation needs rules that a domain expert can write. In a Rust codebase, the usual answer is a scripting language that can be embedded, which is a much harder problem than having a standalone interpreter.

Koto is a simple and expressive programming language, usable as an extension language for Rust applications, or as a standalone scripting language. The project description is deliberately short, and the repository topics name the pieces: compiler, language, programming language, rust and scripting language.

The audience is therefore Rust developers who want to embed a small, readable language, and it is worth noticing that the two uses pull in different directions. As a standalone script, Koto competes with every other small scripting language on ergonomics. As an embedded language, it competes with the embedding facilities of other hosts, and the constraint that matters is how much of the runtime the host has to expose.

The implementation is Rust, published on crates.io as koto, with API documentation on docs.rs and the language home at koto.dev. The licence is MIT, the default branch is main, and the last push was on 2026-08-06. The published releases are v0.16.1 from 2026-01-05, v0.16.0 from 2025-07-23 and v0.15.3 from 2025-04-07.

The compiler pipeline, split into crates you can read

The workspace dependencies in the manifest are the clearest description of the architecture, because each crate is named for its stage.

There is koto_lexer, koto_parser, koto_bytecode and koto_runtime, which together are the path a script takes from text to execution. Around them sit koto_memory, which is separated from the rest, koto_derive for the derive macros, koto_format for the formatter, koto_serde for serialisation support, koto_test_utils for the test helpers, and koto itself, the main crate, with koto_bytecode, koto_derive, koto_format, koto_lexer, koto_memory, koto_parser, koto_runtime and koto_serde all marked as default-features false in the workspace, which is what lets a host pick exactly the parts it needs.

That default-features false is the mechanism behind the embeddability claim. A Rust application that only wants to evaluate a script does not have to pull in the formatter, the derive macros or the serialisation support, and the memory crate is separate so that its implementation can be swapped.

The libraries that ship with the language are in the same style, one crate each: koto_color, koto_geometry, koto_json, koto_random, koto_regex, koto_tempfile, koto_toml and koto_yaml. A language that ships its own TOML and YAML parsers is making a statement about not wanting a host dependency for common formats, and the geometry and color crates show the same instinct for the things a script tends to reach for.

The workspace itself is set to resolver 2 and edition 2024, with members covering crates/*, the example crates under crates/koto/examples/*, and libs/*.

Installing the CLI and the development tooling

There are two installations, and they are for different things.

The first is the language itself, installed from the CLI crate in the repository:

bash
install:
  cargo install --path crates/cli

The second is the development tooling, which the documentation tells you to install after you have just available:

bash
setup:
  cargo install cargo-watch mlc wasm-pack

Those three tools each have a job in the workflow. cargo-watch is for rebuilding on change, mlc is the link checker that the check_links recipe runs over the README, the contributing guide and the docs, and wasm-pack is what builds the WebAssembly target that the checks recipe includes.

The link checker is worth a second look, because it is a maintenance practice rather than a convenience. Running mlc over the documentation catches the dead links that accumulate in a project with a large documentation set, and the documentation here is a distributed thing: a language guide, a CLI reference, an about page, a core library reference, an online playground, and a separate example application.

The whole workflow is driven by just, and the top-level justfile contains the commands for working with the repository, including just checks, which runs all available checks and tests. The documentation also notes that after installing just you can run just setup to install the additional dependencies for working with the justfile commands.

The check matrix, and why a second feature configuration is tested

The checks recipe is a single line, and it is a good description of how the project is verified:

bash
checks: fmt test test_arc test_examples clippy clippy_arc check_links doc wasm

Each part tells you something. fmt runs the formatter in check mode over the whole workspace. test runs the ordinary test suite. test_arc runs a second configuration of the same tests, and clippy_arc does the same for the linter, with the memory crate built in that configuration:

bash
clippy_arc:
  cargo clippy -p koto_memory --no-default-features --features arc -- -D warnings

So the project carries a feature named arc, builds the memory crate with it in place of the default configuration, and runs the test suite against that build as well. Whatever the feature is for, the discipline is the interesting part: a second configuration of the lowest level crate is not left to be exercised occasionally, it is in the default check run and it has its own lint pass.

The linting is strict. Clippy runs over all targets with warnings denied, and the documentation is built with RUSTDOCFLAGS set to treat warnings as errors, so a broken intra-doc link fails the check rather than shipping.

The documentation tests are per library. The test_docs recipe runs the docs examples test plus one test file per library, for color, geometry, json, random, regex, tempfile, toml and yaml. That is a direct statement that every shipped library's documentation examples are executed, which for a language whose libraries are the reason people adopt it is a meaningful guarantee.

The examples, including one that runs a script from disk

The examples recipe runs every example in the crate directory as an executable, and then does something more specific:

bash
cargo run --example poetry -- -s crates/koto/examples/poetry/scripts/readme.koto

That line is the most interesting command in the repository, because the poetry example is the one the project description points at: an example Rust application with Koto bindings. The -s flag hands a Koto script file to the application, so the test is not just that the binding compiles, it is that an application built on Koto actually loads and runs a script from disk.

The examples directory also holds a set of Rust example programs, and the recipe loops over them with cargo run --example, passing any extra arguments through, which means every example is executed as part of the default checks rather than being documentation that drifts.

The poetry example is also the clearest illustration of the two ways to use Koto. The same language that you would run as a standalone script in that directory is being driven from inside a Rust program, and the repository treats the script as an input to the binary.

For a reader, the practical entry points are the online playground at koto.dev/play, the language guide, the CLI documentation, and the about page, all of which live in the crates/cli/docs directory of the repository, and the API reference for the core library at koto.dev/docs/next/core.

Licence, development status and where Koto is the wrong tool

The licence is MIT, stated in the workspace manifest and carried by the LICENSE file at the root, so the language and its libraries can be used in a commercial host without any obligation to publish your own code.

The status is worth reading carefully. The project says that Koto is under active development, and tested against the latest stable release of Rust. The heading above that statement is MSRV, which is the conventional name for the minimum supported Rust version, and the sentence under it describes a policy of testing against the newest stable release rather than pinning an older floor. In practice that means a Koto host is likely to require a recent Rust toolchain, and it means the project is not promising compatibility with a spread of compiler versions.

The version line is still in the zero series, with v0.16.1 the most recent release in January 2026 and the last push in August 2026, so there is active work beyond the last tag. The changelog is in the repository at CHANGELOG.md, and the governance files are CODE_OF_CONDUCT.md and CONTRIBUTING.md alongside a Discord community.

Where Koto is the wrong tool is a short list. If you need a language with a large package ecosystem, Koto has eight libraries and a core library, and that is not a replacement for a mature registry. If you are embedding a language into a product and your users need to find answers online, a language with a small community and a young version line is a support burden you have to plan for rather than adopt casually. And if your host application is not written in Rust, the embedding advantage disappears and you are left with a general purpose scripting language competing against more established ones.

What it is genuinely good at is the case the project names: a small, expressive language you can embed, with a source tree you can read in an afternoon, a compiler pipeline split into stages you can understand individually, and a check matrix that treats the least obvious configuration as a first class citizen.

Editorial conclusion

Adopt Koto if you want to give users of a Rust application a scripting layer, or if you want a small scripting language for your own tooling, and if you are willing to track a language that is still under active development. Do not adopt it if you need a language with a large package ecosystem or a long track record of compatibility, since the version line is still in the zero series and the project is tested against the latest stable Rust rather than a pinned minimum. Before you commit, run just checks once to see the whole matrix pass on your machine, and read the language guide rather than the about page, because the language is small enough that the guide is the fastest route to understanding it.

Frequently asked questions

What is Koto and how is it used?

Koto is a simple and expressive programming language, usable as an extension language for Rust applications, or as a standalone scripting language. The implementation is Rust, the crate is published on crates.io as koto, and the language home is koto.dev with an online playground and API documentation on docs.rs.

How do I install the Koto CLI and the development tooling?

The CLI is installed from the repository with cargo install --path crates/cli. The development tooling is installed with just setup, which runs cargo install cargo-watch mlc wasm-pack for rebuilding on change, link checking and the WebAssembly target.

What does just checks run in the Koto repository?

The checks recipe runs fmt, test, test_arc, test_examples, clippy, clippy_arc, check_links, doc and wasm. It covers the formatter, the test suite in both the default and the arc feature configurations, the example programs, Clippy with warnings denied, a link check over the documentation, a documentation build with warnings as errors, and the WebAssembly target.

Which libraries ship with Koto?

The workspace includes separate crates for color, geometry, json, random, regex, tempfile, toml and yaml, alongside the compiler crates for the lexer, parser, bytecode and runtime, plus memory, derive, format, serde and test utilities.

What licence is Koto released under, and what is its development status?

MIT, recorded in the workspace manifest with the LICENSE file at the root of the repository. The project states that Koto is under active development and is tested against the latest stable release of Rust, and the most recent release is v0.16.1 from 2026-01-05.

Official sources

  1. koto-lang/koto on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/koto-lang-koto.svg)](https://hysenlabs.com/projects/koto-lang-koto)

Was this useful?