The WebRacket language is a subset of Racket that compiles to WebAssembly
Recorded: Jan. 22, 2026, 11:03 a.m.
| Original | Summarized |
GitHub - soegaard/webracket: The WebRacket language is a subset of Racket that compiles to WebAssembly Skip to content Navigation Menu Toggle navigation
Sign in
Appearance settings PlatformAI CODE CREATIONGitHub CopilotWrite better code with AIGitHub SparkBuild and deploy intelligent appsGitHub ModelsManage and compare promptsMCP RegistryNewIntegrate external toolsDEVELOPER WORKFLOWSActionsAutomate any workflowCodespacesInstant dev environmentsIssuesPlan and track workCode ReviewManage code changesAPPLICATION SECURITYGitHub Advanced SecurityFind and fix vulnerabilitiesCode securitySecure your code as you buildSecret protectionStop leaks before they startEXPLOREWhy GitHubDocumentationBlogChangelogMarketplaceView all featuresSolutionsBY COMPANY SIZEEnterprisesSmall and medium teamsStartupsNonprofitsBY USE CASEApp ModernizationDevSecOpsDevOpsCI/CDView all use casesBY INDUSTRYHealthcareFinancial servicesManufacturingGovernmentView all industriesView all solutionsResourcesEXPLORE BY TOPICAISoftware DevelopmentDevOpsSecurityView all topicsEXPLORE BY TYPECustomer storiesEvents & webinarsEbooks & reportsBusiness insightsGitHub SkillsSUPPORT & SERVICESDocumentationCustomer supportCommunity forumTrust centerPartnersOpen SourceCOMMUNITYGitHub SponsorsFund open source developersPROGRAMSSecurity LabMaintainer CommunityAcceleratorArchive ProgramREPOSITORIESTopicsTrendingCollectionsEnterpriseENTERPRISE SOLUTIONSEnterprise platformAI-powered developer platformAVAILABLE ADD-ONSGitHub Advanced SecurityEnterprise-grade security featuresCopilot for BusinessEnterprise-grade AI featuresPremium SupportEnterprise-grade 24/7 supportPricing Search or jump to... Search code, repositories, users, issues, pull requests...
Search Clear
Search syntax tips Provide feedback Include my email address so I can be contacted Cancel Submit feedback Saved searches
Name Query To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up
Appearance settings Resetting focus You signed in with another tab or window. Reload to refresh your session. Dismiss alert soegaard webracket Public
Notifications
Fork
Star The WebRacket language is a subset of Racket that compiles to WebAssembly 70 1 Branches Tags Activity
Star
Notifications Code Issues Pull requests Actions Projects Security Uh oh! There was an error while loading. Please reload this page. Insights
Additional navigation options
Code Issues Pull requests Actions Projects Security Insights
soegaard/webracket
mainBranchesTagsGo to fileCodeOpen more actions menuFolders and filesNameNameLast commit messageLast commit dateLatest commit History1,610 Commitsassets/screenshots/examplesassets/screenshots/examples docsdocs examplesexamples extrasextras ffiffi langlang stdlibstdlib testtest toolstools webifywebify .gitignore.gitignore AGENTS.mdAGENTS.md README.mdREADME.md assembler.rktassembler.rkt bool.rktbool.rkt compiler.rktcompiler.rkt core.rktcore.rkt define-foreign.rktdefine-foreign.rkt driver.rktdriver.rkt expander.rktexpander.rkt fasl-note.mdfasl-note.md fasl.rktfasl.rkt fully.rktfully.rkt get-env-path.rktget-env-path.rkt immediates.rktimmediates.rkt jsxgraph.mdjsxgraph.md main.rktmain.rkt meta-linklet.rktmeta-linklet.rkt parameters.rktparameters.rkt pretty.rktpretty.rkt priminfo.rktpriminfo.rkt primitives.rktprimitives.rkt runtime-wasm.rktruntime-wasm.rkt structs.rktstructs.rkt wasm-data.rktwasm-data.rkt wasm-utils.rktwasm-utils.rkt webracket.rktwebracket.rkt View all filesRepository files navigationREADMEWebRacket wasm-tools from the Bytecode Alliance (version 1.243.0 or newer) Installation Download the latest release from: Unpack the tar-ball: Open README.md in the browser to see further instructions. Make sure to place wasm-tools in somewhere in your PATH. Test that wasm-tools works: Depending on security settings, you might get a dialog on macOS. Go to https://nodejs.org/en/download and follow the instructions. Test that node works in the terminal (and that it is in you path). WebRacket needs support for exnref so your Node version needs Racket Install the web-server using raco. Test it works. Go to a folder that holds an html file. Follow the printing instructions. Short Compiler Overview See the comments in "compiler.rkt" for an explanation of each pass. MathJax 4 two-pane editor/preview Running the examples Go to the examples/ folder Start a local web-server Open http://localhost:8000/ in your favorite browser. Click on a folder and then click the html file. examples/mathjax4 examples/matrix-rain The effect shows constantly falling characters, mostly green, Improvements to this example are welcome. examples/pict examples/space-invaders examples/xtermjs-demo
About The WebRacket language is a subset of Racket that compiles to WebAssembly Readme Uh oh! There was an error while loading. Please reload this page. Activity 70 1 1 Report repository Releases Packages No packages published Languages HTML Racket Footer © 2026 GitHub, Inc. Footer navigation Terms Privacy Security Status Community Docs Contact Manage cookies Do not share my personal information You can’t perform that action at this time. |
The WebRacket language is a subset of Racket that compiles to WebAssembly (wasm). The long-term goal is to support full Racket. However, to quote Piet Hein, “Things take time.” The subset supported by the WebRacket compiler is large enough to enable programmers to build practical programs for the web. The generated WebAssembly can be run either in the terminal (via Node) or in the browser. The browser is the main focus. WebAssembly is somewhat of a moving target. The compiler only uses widely supported features of WebAssembly. Expect the generated code to work in Chrome, Firefox and Safari. A JavaScript FFI makes it possible to use standard JavaScript functions as well as browser specific APIs. Included are bindings for the DOM, Canvas, MathJax, XTermJS and JSXGraph. The hope is that this project allows the Racket community to experiment with WebAssembly. The ideal outcome is that the experience can be used to extend the normal Racket compiler with a WebAssembly backend. In the meantime, we can have fun writing Racket programs that run in the browser. Is WebRacket for you? If you want to develop Racket programs that run in the browser and want to avoid JavaScript, then WebRacket is for you. The FFI allows you to use WebRacket functions as event callbacks on the JavaScript side. See examples/ for a few WebRacket projects. Overview of the supported language subset The WebRacket compiler accepts a file containing a top-level form as input. The module form is not supported. However, include is available. For supported data types most functions in racket/base and racket are available as primitives. Most are implemented directly in WebAssembly, some are reimplemented in WebRacket. Datatypes Most basic data types are implemented, some have restrictions. Numbers The numerical tower contains only flonums and fixnums. Complex numbers and bignums are missing. Hash Tables Mutable hash tables of all four varieties (eq? eqv? equal? always?) are supported. The values of all mutable hash tables are strongly held, even for tables created by the weak construtors. Immutable hash tables are not yet supported. Regular Expressions No direct support for regular expressions at the moment. These will materialize once support for linklets and modules improves. Ports Since the main target is the browser, only string (and byte string) ports are supported. If there is interest for file ports (for the terminal), let me know. Structures Most structure related bells and whistles are implemented including super structures, structure properties and applicable structures. The most notable missing feature is prefab structures. Syntactic Forms The WebRacket compiler uses the standard Racket expander, so a large number of syntactic forms are supported. This includes for and match. Most notable omissions are the forms module, module* and with-continuation-mark. Control Flow Tail calls are supported. Multiple values are supported. Upward flowing exceptions are supported. Continuations and continuation marks are not supported. In particular, there is no support for call/cc (sorry Shriram). Other omissions: promises, breaks, exit and black box. Concurrency and Parallelism Single threaded for now. Foreign Function Interface The JavaScript foreign function interface is used to access browser functionality. The hope is that the community will help write bindings for commonly used libraries. To some degree the generation of foreign function interfaces can be automated with the help of an LLM. Included bindings currently cover the Math, DOM, Canvas, MathJax, XTermJS, and JSXGraph. The Road Ahead After the initial release, the focus is to fix bugs found by early adopters. Then the top priority is to support modules. Work on implementing linklets (needed to support modules) have already started. Due to my personal interests, complex numbers and bignums are likely to appear sooner rather than later. Impersonators and chaperones are needed to support contracts. Unlocking modules (and linklets) will also unlock the full implementation of regular expressions present in the source of the Racket expander. Support for continuations and continuation marks, although high on the wish list, is something that is trickier to implement given the nature of the target. Last resort is to add a CPS pass to the compiler. Installation - short version You need: wasm-tools from the Bytecode Alliance (version 1.243.0 or newer) Installation The WebRacket compiler depends on two external programs: wasm-tools and node. The wasm-tools project by Bytecode Alliance consists of a suite of WebAssembly tools. WebRacket uses the wasm-tools to compile WebAssembly source files (.wat) (in S-expression format) to bytecode (.wasm). Node (or Node.js) is a JavaScript runtime environment used to run JavaScript programs in the terminal. WebRacket uses Node to run programs directly in the terminal. This is useful for testing programs that do not depend on browser functionality. A relatively new version is needed. When the target is the browser, the WebRacket compiler can optionally produce an html file that loads the generated WebAssembly program. In order to test locally, the package raco-static-web by Sam Philips is very convenient. wasm-tools Download the latest release from: https://github.com/bytecodealliance/wasm-tools/releases Unpack the tar-ball: tar -xvf wasm-tools-1.243.0-aarch64-macos.tar.gz Make sure to place wasm-tools in somewhere in your PATH. On macOS, you can do it with: sudo mv wasm-tools /usr/local/bin/ Test that wasm-tools works: wasm-tools Depending on security settings, you might get a dialog on macOS. If so, open the system preferences and find the "Privacy and Security" tab. Then allow wasm-tools to run. Node.js Go to https://nodejs.org/en/download and follow the instructions. Test that node works in the terminal (and that it is in you path). node WebRacket needs support for exnref so your Node version needs to accept the --experimental-wasm-exnref flag. Here is what I see, when Node is started: % node --experimental-wasm-exnref --expose-gc Welcome to Node.js v24.9.0. Type ".help" for more information. Racket The compiler needs Racket 9.0 or newer. Short Compiler Overview The WebRacket compiler is a direct-style compiler. This choice has made it easier to relate the generated code to the source program. In the future we will probably need to add a CPS-pass in order to support continuations and continuation marks. The frontend of the WebRacket compiler uses read-syntax to read a WebRacket program from a file. The resulting syntax object is fed into the normal Racket expander to produce a program in fully expanded form. The middle end of the compiler consists of several passes implemented using the NanoPass framework. The passes are as follows: unexpand, parse, flatten-topbegin, infer-names, convert-quotations, explicit-begin, explicit-case-lambda, α-rename, assignment-conversion, categorize-applications, anormalize, closure-conversion, flatten-begin, (classify-variables) generate-code See the comments in "compiler.rkt" for an explanation of each pass. The code generator generates WebAssembly in the form of S-expressions in the "folded" format. This code generator is inspired by "Destination-driven Code Generation" by Dybvig, Hieb and Butler. There are some differences, however. The code generator in the paper generates "flat" code (assembler) whereas we generate nested WebAssembly instructions. Finally, the external tool wasm-tools parse converts the S-expression representation into bytecode format. The main part of the compiler is in "compiler.rkt". The WebAssembly runtime is in "runtime-wasm.rkt". The standard library (implemented in WebRacket) is found in stdlib/. FFI bindings for popular libraries are in ffi/. It has been a design goal to avoid relying on functionality provided by the WebAssembly host if possible. Who knows - maybe someone needs a non-JavaScript host at some point? For browser functionality there is no way around interfacing with the JavaScript host. The JavaScript part of the runtime support is in assembler.rkt. Examples The folder examples/ contains a few examples that show different aspects of WebRacket. Examples include: MathJax 4 two-pane editor/preview Matrix digital rain MiniScheme REPL pict port Space Invaders xtermjs demo |