Hoot is a Scheme to WebAssembly compiler and self-contained WebAssembly toolchain. https://spritely.institute/hoot/
  • Scheme 92.9%
  • WebAssembly 3.8%
  • JavaScript 2.2%
  • M4 0.7%
  • Makefile 0.4%
Find a file
Andy Wingo d91e623060
All checks were successful
/ check (push) Successful in 50m26s
/ distcheck (push) Successful in 52m40s
Canonicalization is kwarg of validate-wasm, req of make-wasm-info
The goal is to allow validate-wasm against an explicit canonicalization,
and to avoid accidental canonicalization into the main set.
2026-01-15 11:05:49 +01:00
.forgejo/workflows Replace GitLab CI with Codeberg actions. 2025-03-19 12:46:15 -04:00
bin Fix bin/call.scm 2024-08-12 17:15:54 +02:00
design Fix compilation of null? 2023-08-25 16:50:29 +02:00
doc Remove docs for obsolete --emit-names flag and document -g. 2025-11-11 08:14:01 -05:00
examples Fix REPL stack trimming 2025-03-03 16:05:51 +01:00
js-runner module: scripts: compile-wasm: Add support for user imports. 2024-10-15 13:25:10 -04:00
lib Improve min/max to only accept reals, handle NaNs, and normalize exact zeroes. 2025-11-22 08:14:21 -05:00
m4 Add guile.m4 from Guile, replacing acinclude.m4 2025-11-09 14:14:27 +01:00
module Canonicalization is kwarg of validate-wasm, req of make-wasm-info 2026-01-15 11:05:49 +01:00
reflect-js reflect.js: Reorganize instantiation code a bit. 2025-10-21 14:16:10 -04:00
reflect-wasm Add low-level support for syntax transformers 2024-10-18 14:50:15 +02:00
test Split validation out to its own module 2026-01-14 13:34:52 +01:00
.dir-locals.el vm: Refer to types by name, not value 2026-01-14 13:59:51 +01:00
.gitignore Add terminal REPL example. 2025-01-21 08:54:19 -05:00
bootstrap.sh Add autotools build system. 2023-06-05 10:21:15 -04:00
ci-manifest.scm Move manifest.scm to ci-manifest.scm. 2023-07-21 09:40:28 -04:00
configure.ac Add guile.m4 from Guile, replacing acinclude.m4 2025-11-09 14:14:27 +01:00
COPYING Add license file 2023-05-04 10:55:18 -04:00
COPYING.LESSERv3 Improve LGPLv3 handling 2025-11-02 15:12:41 +01:00
guile Use local Guile wrapper for Geiser. 2025-03-03 14:48:37 -05:00
guix.scm Add license header to guix.scm. 2025-11-03 13:53:56 -05:00
hoot.ase Update brightness a bit on logo 2023-02-16 12:17:27 -05:00
hoot.png Update brightness a bit on logo 2023-02-16 12:17:27 -05:00
LICENSE.txt Add license file 2023-05-04 10:55:18 -04:00
Makefile.am Add COPYING.LESSERv3 to EXTRA_DIST. 2025-11-03 13:47:58 -05:00
pre-inst-env.in Move Scheme standard library out to lib/ 2024-05-06 13:56:28 +02:00
README.md Improve LGPLv3 handling 2025-11-02 15:12:41 +01:00
size-metrics.scm ci: Gather binary size metrics. 2024-01-17 09:17:12 -05:00

Guile Hoot

Hoot logo

Hoot is an ahead-of-time, whole-program compiler for Guile Scheme to WebAssembly (aka Wasm) developed by the Spritely Institute. In addition to the compiler, Hoot contains a full WebAssembly toolchain with an assembler, a disassembler, a linker, an interpreter, etc. Hoot produces binaries that conform to the Wasm 3.0 specification which features tail calls and heap-allocated reference types with garbage collection.

Compatibility

Hoot is compatible with the following Wasm runtimes:

  • Firefox 121+
  • Chrome 119+
  • Safari 26+
  • NodeJS 22+

Hoot is currently unsupported on WASI runtimes.

Compilation and runtime

A whole-program compilation approach has been chosen in order to create smaller binaries at the expense of increased compilation time. As we implement more of Scheme, we hope to preserve this "small programs compile to small files" property, rather than having every compiled program include the whole of Guile's standard library.

Despite whole-program compilation, it's possible for multiple Hoot modules to be bound together and interoperate. Hoot makes a distinction between main and auxilary modules. Main modules include the full Scheme runtime and export their ABI whereas auxilary modules exclude the runtime and import their ABI from a main module.

To run Hoot binaries on web browsers there is an associated JavaScript module that handles booting the Wasm modules with the necessary host imports and translates Scheme values to/from JavaScript. Some non-web targets are hosted by JavaScript implementations (e.g. NodeJS) and those can make use of the same support module.

Project status

Hoot has not yet achieved maximum Guile compatibility, but R7RS-small Scheme is well supported. Despite gaps in compatibility, Guile libraries such as Spritely Goblins are known to compile and run on Hoot.

All Wasm features that Hoot relies upon are available in all major web browsers and NodeJS.

To build and run Hoot, a bleeding-edge Guile built from the main branch in Git is required, as several necessary changes that have been upstreamed to Guile have not made it into a stable release yet.

For a fuller picture of project status, including known limitations, see the "Status" section of our documentation..

But... why the name "Hoot"?

We thought this project deserved a cute project name and mascot, and everyone at the time agreed an owl was nice, and Christine Lemmer-Webber had recently just drawn up this owl pixel art, and so it became the mascot. The name naturally flowed from there.

Installing from a stable release

Note that at the time of writing, Hoot requires a development version of Guile. This may not be the case at your time of reading!

Below are system-specific instructions for installing Hoot.

On Guix

Hoot is already available in Guix:

guix shell --pure guile-next guile-hoot

(The --pure flag is to reduce the likelihood of failure due to system-specific configuration. You may not need this flag.)

On macOS (Homebrew)

Hoot is available in macOS thanks to to Alex Conchillo Flaqué and the Guile Homebrew repository.

Add the Guile Homebrew tap if you haven't already:

brew tap aconchillo/guile

If Guile is already installed with Homebrew, unlink it since we need a newer version:

brew unlink guile

Now, just install Hoot:

brew install guile-hoot

This will also install guile-next, a bleeding edge version of Guile, so it might take a while if there's no bottle available.

Building from source

Easy path: Use Guix

This is by far the easiest path because Guix does all the hard work for you.

First, clone the repository:

git clone https://codeberg.org/spritely/hoot
cd hoot
guix shell
./bootstrap.sh && ./configure && make

If everything went okay then you can now run make check:

make check

Did everything pass? Cool! That means Hoot works on your machine!

Advanced path: Build dependencies on your own

Maybe you want to understand better what Hoot is actually doing, or maybe you want to hack on the version of Guile used for Hoot, or etc! This section is for you.

First, you need to build Guile from the main branch.

Then you can clone and build this repo:

git clone https://codeberg.org/spritely/hoot
cd hoot
./bootstrap.sh && ./configure && make

To run the test suite against a production Wasm host, you will need a V8 distribution such as NodeJS 22+ or a standalone V8 build. NodeJS is recommended.

Building V8 is annoying, to say the least. You need to have depot_tools installed; see https://v8.dev/docs/source-code. Once you have that see https://v8.dev/docs/build to build. You will end up with a d8 binary in out/x64.release (if you are on an x86-64 platform). We discourage this route except in the very unlikely case that you are developing a Hoot feature that requires a fresher V8 than NodeJS provides.

If all that works you should be able to run the test suite:

make check

By default, the test suite runs against both V8 (either NodeJS or V8's d8 tool) and Hoot's Wasm interpreter. If you want to run the test suite with just one or the other, you can use the WASM_HOST environment variable:

make check WASM_HOST=hoot
# OR
make check WASM_HOST=node
# OR
make check WASM_HOST=d8

Try it out

Hoot is a self-contained system, so the easiest way to try it is from the Guile REPL:

./pre-inst-env guile

From the Guile prompt, enter the following to evaluate the program 42 in Hoot's built-in Wasm interpreter:

scheme@(guile-user)> ,use (hoot reflect)
scheme@(guile-user)> (compile-value 42)
$5 = 42

More interestingly, Scheme procedures that live within the Wasm guest module can be called from Scheme as if they were host procedures:

scheme@(guile-user)> (define hello (compile-value '(lambda (x) (list "hello" x))))
scheme@(guile-user)> hello
$6 = #<hoot #<procedure>>
scheme@(guile-user)> (hello "world")
$7 = #<hoot ("hello" "world")>

Hoot also extends Guile's build tool guild with the guild compile-wasm subcommand which can be used to compile and (optionally) run a Scheme file:

echo 42 > 42.scm
./pre-inst-env guild compile-wasm --run 42.scm

The above command compiles 42.scm to Wasm and runs the resulting binary in Hoot's Wasm interpreter. Here's how to run it with NodeJS instead:

./pre-inst-env guild compile-wasm --run=node 42.scm

The binaries can be saved to disk, too, of course:

./pre-inst-env guild compile-wasm -o 42.wasm 42.scm

To actually load 42.wasm you could use the Hoot VM as mentioned above or use a production Wasm implementation such as a web browser. See the manual for further instructions on production deployment and full API documentation.

Examples

For quickly getting started with a new project, see examples/project-template/README.md for an explanation of how to use our project template.

For more examples of using Hoot, check out a some of our other repos:

Contributing

Hoot's Git repository is hosted on Codeberg: https://codeberg.org/spritely/hoot

Bug reports and other issues can be filed here: https://codeberg.org/spritely/hoot/issues

Pull requests are very much welcome!

Licenses

Hoot's source code and documentation is licensed under Apache 2.0 unless otherwise noted in a source file. See COPYING for the full license text and see the license headers in each source file for individual copyright information.

Several files are licensed under the GNU Lesser General Public License version 3 or later, see COPYING.LESSERv3.

The owl mascot graphic (hoot.png, hoot.ase) is (C) 2023 Christine Lemmer-Webber and the Spritely Networked Communities Institute and released under the Creative Commons Attribution 4.0 International license