in a toot: how to deploy as static website via (complete example).

The code from the two attached images, as written, runs on
draketo.de/software/hoot.html

Try it out!

It’s two pages from Naming & Logic: Programming Essentials with Wisp.

printed: epubli.com/shop/naming-and-log
website: draketo.de/software/programmin

This adds parallel fetches (do you see where?). If you adopt it, make sure your server compresses application/wasm.

*Browser again: clientside wasm.* @@html:<a id="deploy-hoot-wasm" name="deploy-hoot-wasm"></a>@@
To run clientside, you can package your project with [[https://spritely.institute/hoot/][Hoot]]: build an interface and compile to wasm:

#+begin_src wisp :results output :tangle hoot.w
;; file: hoot.w
use-modules : hoot ffi ;; guile specific import

;; the interface
define-foreign document-body "document" "body"
  . -> (ref null extern)
define-foreign make-text-node "document" "createTextNode"
  . (ref string) -> (ref null extern)
define-foreign append-child! "element" "appendChild"
  . (ref null extern) (ref null extern) 
  . -> (ref null extern)

;; your code
append-child! : document-body
  make-text-node "Hello, world!"
#+end_src

Transpile with =wisp2lisp= and =guild compile-wasm=. If you run Guix:

#+begin_src bash
guix shell guile guile-wisp -- \
  wisp2lisp hoot.w > hoot.scm && \
    guix shell guile-hoot guile-next -- \
      guild compile-wasm -o hoot.wasm hoot.scm
#+end_src

Get reflection tools from Guile Hoot (licensed Apache 2.0) with Guix:
#+latex: \ThisLLCornerWallPaper{0.26}{programming-scheme-hoot}%

#+begin_src bash
guix shell guile-hoot guile-next --  bash -c \
 'cp $GUIX_ENVIRONMENT/share/*hoot/*/re*/{*.js,*.wasm} ./'
#+end_src
Load your interface (includes startup time optimizations):
#+begin_src js :tangle hoot.js
/* file: hoot.js */
var f = window.fetch; window.fetch = (inp, ini) => f(inp, 
  {credentials: 'include', mode: 'no-cors', ...ini});
window.addEventListener("load", () =>
  fetch("hoot.wasm")
    .then(r => r.arrayBuffer())
    .then(bytes => Scheme.load_main(bytes, {
      user_imports: { // mapped via define-foreign
        document: {
          body() { return document.body; },
          createTextNode: Document.prototype
            .createTextNode.bind(document)
        }, 
        element: {
          appendChild(parent, child) { 
            return parent.appendChild(child);}}}})));
#+end_src

Include =reflect.js= and =hoot.js= from a HTML page:

#+begin_src html :tangle hoot.html
<!DOCTYPE html> <!-- file: hoot.html -->
<html><head><title>Hello Hoot</title>
<script type="text/javascript" src="reflect.js"></script>
<script type="text/javascript" src="hoot.js"></script>
<link rel="preload" as="fetch" href="hoot.wasm"></link>
<link rel="preload" as="fetch" href="wtf8.wasm"></link>
<link rel="preload" as="fetch" href="reflect.wasm"></link>
</head><body><h1>Hoot Test</h1></body></html>
#+end_src

For local testing, hoot provides a minimal webserver:

#+begin_src bash
guix shell guile-hoot guile-next -- \
  guile -c '((@ (hoot web-server) serve))'
#+end_src
0

If you have a fediverse account, you can quote this note from your own instance. Search https://rollenspiel.social/users/ArneBab/statuses/115571892921956503 on your instance and quote it. (Note that quoting is not supported in Mastodon.)

\\n\\n\\n\\n\\n

Hoot Test

\\n#+end_src\\n\\nFor local testing, hoot provides a minimal webserver:\\n\\n#+begin_src bash\\nguix shell guile-hoot guile-next -- \\\\\\n guile -c '((@ (hoot web-server) serve))'\\n#+end_src\\n\",726,1005,{\"slots\":52,\"props\":53},[],{\"class\":54,\"language\":30,\"post\":55,\"active\":125,\"signedAccount\":-1},\"mt-4 ml-14\",{\"id\":35,\"iri\":56,\"type\":57,\"visibility\":58,\"actorId\":59,\"articleSourceId\":-2,\"noteSourceId\":-2,\"sharedPostId\":-2,\"replyTargetId\":-2,\"quotedPostId\":-2,\"name\":-2,\"summary\":-2,\"contentHtml\":60,\"language\":30,\"tags\":61,\"emojis\":71,\"sensitive\":41,\"repliesCount\":10,\"sharesCount\":72,\"quotesCount\":10,\"reactionsCounts\":73,\"reactionsCount\":10,\"linkId\":74,\"linkUrl\":75,\"url\":20,\"updated\":76,\"published\":29,\"actor\":77,\"link\":117,\"sharedPost\":-2,\"replyTarget\":-2,\"mentions\":121,\"media\":122,\"shares\":123,\"reactions\":124},\"https://rollenspiel.social/users/ArneBab/statuses/115571892921956503\",\"Note\",\"public\",\"019734f3-476d-795d-99f5-96086b993ae3\",\"

#spritely #hoot in a toot: how to deploy #Guile #Scheme as static website via #webassembly (complete #Wisp example).

The code from the two attached images, as written, runs on
https://www.draketo.de/software/hoot.html

Try it out!

It’s two pages from Naming & Logic: Programming Essentials with Wisp.

printed: https://www.epubli.com/shop/naming-and-logic-programming-essentials-with-wisp-9783565093199
website: https://www.draketo.de/software/programming-basics-wisp

This adds parallel fetches (do you see where?). If you adopt it, make sure your server compresses application/wasm.

#wasm #webdev #programming

\",{\"hoot\":62,\"wasm\":63,\"wisp\":64,\"guile\":65,\"scheme\":66,\"webdev\":67,\"spritely\":68,\"programming\":69,\"webassembly\":70},\"https://rollenspiel.social/tags/hoot\",\"https://rollenspiel.social/tags/wasm\",\"https://rollenspiel.social/tags/Wisp\",\"https://rollenspiel.social/tags/guile\",\"https://rollenspiel.social/tags/scheme\",\"https://rollenspiel.social/tags/webdev\",\"https://rollenspiel.social/tags/spritely\",\"https://rollenspiel.social/tags/programming\",\"https://rollenspiel.social/tags/webassembly\",{},3,{},\"019a98bf-c87f-7ab9-88a6-0e59c7823087\",\"https://www.draketo.de/software/hoot.html\",[\"Date\",\"2025-11-18T17:53:30.000Z\"],{\"id\":59,\"iri\":78,\"type\":79,\"username\":80,\"instanceHost\":81,\"handleHost\":81,\"handle\":82,\"accountId\":-2,\"name\":83,\"bioHtml\":84,\"automaticallyApprovesFollowers\":85,\"avatarUrl\":86,\"headerUrl\":87,\"inboxUrl\":88,\"sharedInboxUrl\":89,\"followersUrl\":90,\"featuredUrl\":91,\"fieldHtmls\":92,\"emojis\":97,\"tags\":98,\"sensitive\":41,\"successorId\":-2,\"aliases\":103,\"followeesCount\":104,\"followersCount\":105,\"postsCount\":10,\"url\":4,\"updated\":106,\"published\":107,\"created\":108,\"instance\":109,\"followers\":114,\"blockees\":115,\"blockers\":116},\"https://rollenspiel.social/users/ArneBab\",\"Person\",\"ArneBab\",\"rollenspiel.social\",\"@ArneBab@rollenspiel.social\",\"Arne Babenhauserheide\",\"

#TTRPG, #Filk and #FreeSoftware. Physicist by training, PhD in climate science, software developer by trade. I write German and English, as #freeculture by idealism.

Maintains https://floss.social/@Freenet / Hyphanet

Profile: earthen dragon

Ich schreibe Rollenspiele auf http://www.1w6.org und Software u.a. auf http://www.draketo.de

Hier bin ich auf Infrastruktur, von Rollenspiele Spielenden für Rollenspiele Spielende gepflegt, mit der ich auch in Kontakt zu anderen bleiben kann. Danke!

\",true,\"https://rollenspiel.social/system/accounts/avatars/000/008/590/original/87acfe65b46eafb5.jpg\",\"https://rollenspiel.social/system/accounts/headers/000/008/590/original/15fcf9999c3ebae6.png\",\"https://rollenspiel.social/users/ArneBab/inbox\",\"https://rollenspiel.social/inbox\",\"https://rollenspiel.social/users/ArneBab/followers\",\"https://rollenspiel.social/users/ArneBab/collections/featured\",{\"Persönliche Webseite\":93,\"Profilbilder\":94,\"Rollenspiel-Webseite\":95,\"PGP\":96},\"https://www.draketo.de/ich\",\"Von Trudy Wenzel, cc by-sa\",\"https://www.1w6.org/uzanto/drak\",\"https://keyoxide.org/hkp/arne_bab%40web.de\",{},{\"#filk\":99,\"#ttrpg\":100,\"#freeculture\":101,\"#freesoftware\":102},\"https://rollenspiel.social/tags/Filk\",\"https://rollenspiel.social/tags/ttrpg\",\"https://rollenspiel.social/tags/freeculture\",\"https://rollenspiel.social/tags/freesoftware\",[],272,1174,[\"Date\",\"2025-06-03T08:40:47.701Z\"],[\"Date\",\"2020-06-07T00:00:00.000Z\"],[\"Date\",\"2025-06-03T08:40:47.701Z\"],{\"host\":81,\"software\":110,\"softwareVersion\":111,\"updated\":112,\"created\":113},\"mastodon\",\"4.5.1\",[\"Date\",\"2025-11-16T21:30:04.870Z\"],[\"Date\",\"2025-03-29T16:16:08.036Z\"],[],[],[],{\"id\":74,\"url\":75,\"title\":118,\"siteName\":-2,\"type\":-2,\"description\":-2,\"author\":-2,\"imageUrl\":-2,\"imageAlt\":-2,\"imageType\":-2,\"imageWidth\":-2,\"imageHeight\":-2,\"creatorId\":-2,\"created\":119,\"scraped\":120,\"creator\":-2},\"Hello Hoot\",[\"Date\",\"2025-11-18T20:54:56.895Z\"],[\"Date\",\"2025-11-18T20:54:56.895Z\"],[],[34,46],[],[],\"quote\"]");