An excerpt from the repository, fetched Nov 13, 2026.
Read the project’s introduction
Janet is a programming language for system scripting, expressive automation, and
extending programs written in C or C++ with user scripting capabilities.
Janet makes a good system scripting language, or a language to embed in other programs.
It's like Lua and GNU Guile in that regard. It has more built-in functionality and a richer core language than
Lua, but smaller than GNU Guile or Python. However, it is much easier to embed and port than Python or Guile.
There is a REPL for trying out the language, as well as the ability
to run script files. This client program is separate from the core runtime, so
Janet can be embedded in other programs. Try Janet in your browser at
https://janet-lang.org.
Examples
See the examples directory for all provided example programs.
Game of Life
# John Conway's Game of Life
(def- window
(seq [x :range [-1 2]
y :range [-1 2]
:when (not (and (zero? x) (zero? y)))]
[x y]))
(defn- neighbors
[[x y]]
(map (fn [[x1 y1]] [(+ x x1) (+ y y1)]) window))
(defn tick
"Get the next state in the Game Of Life."
[state]
(def cell-set (frequencies state))
(def neighbor-set (frequencies (mapcat neighbors state)))
(seq [coord :keys neighbor-set
:let [count (get neighbor-set coord)]
:when (or (= count 3) (and (get cell-set coord) (= count 2)))]
coord))
(defn draw
"Draw cells in the game of life from (x1, y1) to (x2, y2)"
[state x1 y1 x2 y2]
(def cellset @{})
(each cell state (put cellset cell true))
(loop [x :range [x1 (+ 1 x2)]
:after (print)
y :range [y1 (+ 1 y2)]]
(file/write stdout (if (get cellset [x y]) "X " ". ")))
(print))
# Print the first 20 generations of a glider
(var *state* '[(0 0) (-1 0) (1 0) (1 1) (0 2)])
(for i 0 20
(print "generation " i)
(draw *state* -7 -7 7 7)
(set *state* (tick *state*)))
TCP Echo Server
# A simple TCP echo server using the built-in socket networking and event loop.
(defn handler
"Simple handler for connections."
[stream]
(defer (:close stream)
(def id (gensym))
(def b @"")
(print "Connection " id "!")
(while (:read stream 1024 b)
(printf " %v -> %v" id b)
(:write stream b)
(buffer/clear b))
(printf "Done %v!" id)
(ev/sleep 0.5)))
(net/server "127.0.0.1" "8000" handler)
Windows FFI Hello, World!
# Use the FFI to popup a Windows message box - no C required
(ffi/context "user32.dll")
(ffi/defbind MessageBoxA :int
[w :ptr text :string cap :string typ :int])
(MessageBoxA nil "Hello, World!" "Test" 0)
Language Features
600+ functions and macros in the core library
Built-in socket networking, threading, subprocesses, and file system functions.
Parsing Expression Grammars (PEG) engine as a more robust Regex alternative
Macros and compile-time computation
Per-thread event loop for efficient IO (epoll/IOCP/kqueue)
First-class green threads (continuations) as well as OS threads
Erlang-style supervision trees that integrate with the event loop
First-class closures
Garbage collection
Distributed as janet.c and janet.h for embedding into a larger program.
Python-style generators (implemented as a plain macro)
Mutable and immutable arrays (array/tuple)
Mutable and immutable hashtables (table/struct)
Mutable and immutable strings (buffer/string)
Tail recursion
Interface with C functions and dynamically load plugins ("natives").
Built-in C FFI for when the native bindings are too much work
REPL development with debugger and inspectable runtime
Documentation
For a quick tutorial, see the introduction for more details.
For the full API for all functions in the core library, see the core API doc.
Documentation is also available locally in the REPL.
Use the (doc symbol-name) macro to get API
documentation for symbols in the core library. For example,
(doc apply)
shows documentation for the apply function.
To get a list of all bindings in the default
environment, use the (all-bindings) function. You
can also use the (doc) macro with no arguments if you are in the REPL
to show bound symbols.
Source
You can get the source on GitHub or
SourceHut. While the GitHub repo is the official repo,
the SourceHut mirror is actively maintained.
Spork and JPM
Spork and JPM are two companion projects to Janet. They are optional, especially in an embedding use case.
Spork is a collection of common utility modules, and several packaged scripts
like janet-format for code formatting, janet-netrepl for a socket-based
REPL, and janet-pm for a comprehensive Janet project manager tool. The
modules in spork are less stable than the interfaces in core Janet, although
we try to prevent breaking changes to existing modules, with a preference to
add new modules and functions. Spork requires a C compiler to build and install
various extenstion components such as miniz and JSON utilities. Many spork
sub-modules, for example spork/path, are independent and can be manually
vendored in programmer projects without fully installing spork.
When install Spork, scripts will be installed to $JANET_PATH/bin/ on POSIX systems by default.
This likely needs to be added to the path to use these scripts.
JPM is the older, more opinionated, project manager tool, which has it's pros
and cons. It does not require a C compiler to build and install, but is less
flexible and is not receiving many changes and improvements going forward. It
may also be harder to configure correctly on new systems. In that sense, it may
be more stable.
JPM will install to /usr/local/bin/ on posix systems by default, which may or
may not be on your PATH.
Building
When building from source, for stability, please use the latest tagged release. For
example, run git checkout $(git describe --tags --abbrev=0) after cloning but
before building. For the latest development, build directly on the master
branch. The master branch is not-necessarily stable as most Janet development
happens directly on the master branch.
macOS and Unix-like
The Makefile is non-portable and
Read the full README on GitHub