cd ~

I Built This Website Using Racket. Here's What I Can Do Now.

It looks like there’s not much to see here. Isn’t it great? Barring exceptional cases, every page on this website takes up fewer than 20 kibibytes on disk and runs no JavaScript. Throttle your connection and hit refresh a few times. It loads in milliseconds. No one does that anymore.

It’s funny. I spent years learning the ins and outs of front-end web development, only to feel happy making a tiny, 90s-looking page that loads in a blink of an eye with nothing to do but make a point. Is that ironic? I haven’t decided yet.

But I did not just write vanilla HTML and give up my shiny toys. I use Racket to shape content using any language I want. What better tool for starting with a blank slate?

A Website With Superpowers

Racket is a programming language programming language. Racket allows you to write your own languages in terms of itself, and it is a joy to use. I released unlike-assets—an open source build tool that functions as an alternative to Webpack for my purposes—to say thank you and to show off what it can do.

I built a specific configuration for unlike-assets called polyglot that lets me write web content with arbitrary DSLs.

This snippet computes a Sierpinsky Triangle when building this page. A cool part about that is that I expressed the code only once. My system knows to display the code for you to read, and then run it.

#lang racket
(require "tri.rkt" polyglot)
(provide replace-page)
(define (replace-page page-tx)
  (tx-replace-me
    page-tx
    (λ _ `((div ((style ,(string-join 
                       '("margin: 0 auto")
                       ";")))
             ,(sierpinsky-triangle 4 "#800" "tri"))))))

Here I use rash—a shell dialect by William Hatch—to compute the download size of Bootstrap. Honestly, I did it just because I can. I’d have to configure Webpack for countless hours to get this kind of flexibility.

#lang rash
(require polyglot)
(provide replace-page)
(define size-box (box "Unknown"))

curl -so /dev/null -w '"%{size_download}" \
  https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css \
  |>> set-box! size-box

(define (replace-page page-tx)
 (tx-replace-me page-tx
   (λ _ `((span ((style "color: rebeccapurple"))
        "The total download size of Bootstrap v4.3.1 is "
        ,(unbox size-box) " bytes")))))
The total download size of Bootstrap v4.3.1 is 155758 bytes

This page starts as a Markdown file. Since Markdown supports use of HTML tags, I use <script> elements to express Racket modules that are available only within a page.

I parse the Markdown, process the Racket code in a sensible order, and then scan for dependencies in href and src attributes (such as other pages) to automagically build the rest of the website until all dependencies are fulfilled.

Things get fun when I can “drop down” from prose at any time to prepare a deeply integrated application that sits snug in any surrounding context. So if you are interested in using this kind of engine for your code, give polyglot a try. If you want to start from a lower level, then use unlike-assets.