SkillAgentSearch skills...

Janet

A dynamic language and bytecode vm

Install / Use

/learn @janet-lang/Janet
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Join the chat   builds.sr.ht status builds.sr.ht status Actions Status

<img src="https://raw.githubusercontent.com/janet-lang/janet/master/assets/janet-w200.png" alt="Janet logo" width=200 align="left">

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.

<br>

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

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 requires GNU-flavored make.

cd somewhere/my/projects/janet
make
make test
make repl
make install
make install-spork-git # optional
make install-jpm-git # optional

Find out more about the available make targets by running make help.

Alpine Linux

To build a statically-linked build of Janet, Alpine Linux + MUSL is a good combination. Janet can also be built inside a docker container or similar in this manner. This is a great way to try Janet without committing to a full install or needing to customize the default install.

docker run -it --rm alpine /bin/ash
$ apk add make gcc musl-dev git
$ git clone https://github.com/janet-lang/janet.git
$ cd janet
$ make -j10
$ make test
$ make install
$ make install-spork-git # optional
$ make install-jpm-git # optional

Note that for a true statically-linked binary with MUSL, one needs to add -static to the Makefile flags. This will also disable runtime loading of native modules (plugins) as well as the FFI.

32-bit Haiku

32-bit Haiku build instructions are the same as the UNIX-like build instructions, but you need to specify an alternative compiler, such as gcc-x86.

cd somewhere/my/projects/janet
make CC=gcc-x86
make test
make repl
make install
make install-spork-git # optional
make install-jpm-git # optional

FreeBSD

FreeBSD build instructions are the same as the UNIX-like build instructions, but you need gmake to compile. Alternatively, install the package directly with pkg install lang/janet.

cd somewhere/my/projects/janet
gmake
gmake test
gmake repl
gmake install
gmake install-spork-git # optional
gmake install-jpm-git # optional

NetBSD

NetBSD build instructions are the same as the FreeBSD build instructions. Alternatively, install the package directly with pkgin install janet.

illumos

Building on illumos is exactly the same as building on FreeBSD.

Windows

  1. Install Visual Studio or Visual Studio Build Tools.
  2. Run a Visual Studio Command Prompt (cl.exe and link.exe need to be on your PATH) and cd to the directory with Janet.
  3. Run build_win to compile Janet.
  4. Run build_win test to make sure everything is working.

To build an .msi installer executable, in addition to the above steps, you will have to:

  1. Install, or otherwise add to your PATH the WiX 3.14 Toolset.
  2. Run build_win dist.

Now you should have an .msi. You can run build_win install to install the .msi, or execute the file itself.

Meson

Janet also has a build file for Meson, a cross-platform build system. Although Meson has a Python dependency, Meson is a very complete build system that is maybe mor

Related Skills

View on GitHub
GitHub Stars4.2k
CategoryDevelopment
Updated2h ago
Forks257

Languages

C

Security Score

100/100

Audited on Apr 3, 2026

No findings