small pixel drawing of a pufferfish j3s.sh

thought/my-website-is-one-binary.html

                        my website is one binary
                               2022-04-06
                      ----------------------------

     a.k.a. this one weird trick that inspires me to program creatively

i have struggled for years to figure out a website framework that feels good
to me. i tried all of the classics, including but limited to:
- ghost
- hugo
- jekyll
- sr.ht + tarball
- manual html editing

i have very high and unusual standards, and none of the above felt correct to me.
more importantly, none of the above excited me.

i have uncovered the secret. i have discovered my path. a website that feels good.

but first, the search.


                              mY vALuES
                            -------------               

i place an extremely high value on systems that i am capable of understanding
and trivially maintaining front-to-back as a single individual. i like human-
friendly code that is optimized for readability, and i like extremely fast
feedback loops. i like fun and cleverness and being cute too.

the first recommendation people always get is "hugo." for those who aren't in
the know, hugo is a "static website generator" - aka, it is a program that takes
templates & markdown as input and compiles HTML that you may deploy wherever you'd
like.

people normally couple a static site generator (SSG) framework with some hosting
platform for an ez-pz pretty reliable & fast blog. or so they say.

one of my core values is maintainability. this is true of most everything that
i own. from my framework laptop to my bicycle, i like to be able to get my hands
dirty when things break down, and i will always prefer tools and platforms that
treat users as capable and curious. i make a lot of unconventional sacrifices
and people think it's weird - but the truth is that i _hate_ maintaining things.
i'm extremely bad at it. but when something of mine breaks, i _need_ to be able
to dig in myself, because god knows i'm not responsible enough to go through the
painfully long feedback loop of having someone else help me. (i am so averse to
this in my personal life that i will simply let my broken things stay broken if
i cannot trivially fix them myself)

hence another core value of mine - reliability. i need the thing to work today,
and i need the thing to work in ten years. i spend a lot of time choosing my
things, and i refuse to depend on anyone else to ensure that they continue to
work. i don't care if your company went under, my car will keep working. i don't
care if you end-of-life'd the product, my laptop takes generic components that i
can insert myself. you get the point.

so, when people say "just build your blog with hugo and host it on github pages
bruh!" i am naturally very skeptical. here are some of the dependencies that
hugo + github pages come with:

- github pages, the service
  (it must remain up)
- github pages, the product
  (it must remain viable)
- hugo, the project
  (it has 1,200 dependencies that require constant updates)
- hugo, the community
  (they must document the code)
  (i cannot read it all myself)
  (i have limited time and interest)
- hugo, the plugin ecosystem
  (if you rely on any of their plugins)
- hugo, the binary
  (it must compile your HTML in roughly the same way over time)
  (it must not break your website between releases)
- github pages, the deployment mechanism
  (the ability for github to actually deploy the hugo code)
- golang
  (it's pretty clear that golang is here to stay)

it could be argued that you could use a single version of hugo forever - but in
my experience that rarely works out. (i quickly run into a bug, and am forced to
upgrade).

nah, i won't - i tried it, i don't like it. people think that it's simple and
effortless, but it's riddled with dependencies (on people, software, and companies)
and winds up making me feel helpless, like my values are being violated.

it took me a long time to figure out why hugo made me feel uneasy.

(to be clear, i am not attacking hugo _specifically_, this is a problem that i
have with most software)

so, clearly, i needed a system that fit my values


                           plain old html
                         ------------------

i decided that i would host a website on a machine that i controlled, and
program in plain old HTML, and edit everything by hand using vim.

     ~ * ~ and so i gave birth to the worst workflow ever used ~ * ~

the first draft of https://j3s.sh was built like this - it is where a lot of my
ideas for the layout came from. the website still looks largely the same -
writing HTML by hand felt a lot like doing intensive labor by hand - like
dishwashing with a hand pump instead of a sink. it forced me into an insane level
of minimalism in order to avoid the pain of having to use the workflow.  i
embedded styling directly into the HTML, made cross-site functions as minimal
as possible, and shied away from much styling.

in a lot of ways, this experience was exactly what i had hoped for. it was
simple, reliable, and maintainable - the HTML i wrote could be reused without
modification, and i felt pretty confident that my site would be around for
awhile. i had no dependencies. but i grew very tired of the workflow.

i wanted to handle "templating" of common functionality more efficiently.
i didn't want to use a pre-existing framework. i wanted to have fun. and i
wanted to leave myself a lot of room for adjustment in case i changed my
mind about this-or-that.


                       single binary website
                    --------------------------

one afternoon, i was browsing the internet neurotically - this is typical of me.
i had a sudden idea: if i wrote my website entirely in one language, i could
contain and deploy it within a single binary.

i have been using linux & programming for a long time, and golang is by far my
favorite language to develop in, for a few reasons:

- it is easily maintainable by a single person
- it emphasizes few dependencies
- it is a relatively simple language
- there is a backwards compatability guarantee
- it produces statically compiled binaries trivially
- compilation speed is fast (less than 10s most of the time)
- most of the standard library is very well developed (but not overdeveloped)

and so i gave birth to my personal website project for j3s.sh. a single binary that
serves my website. it has many amazing properties.


    >>> it  is  d y n a m i c <<<

statically generated websites may seem "simple" (even though i think that most
SSG frameworks are not), but dynamically generated websites are simpler. the
reason i think they're simpler is because you don't need to think about arcane
workarounds to generate content - you can just generate it easily, on the fly.

for example, say you want to print the visiting users IP address - how would you
do this on a statically generated website? to be honest i'm not sure. typically,
you would scrape a header and display it. on my website, i do this:

    func ipHandler(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Content-Type", "text/plain")
    	fmt.Fprintf(w, r.Header.Get("X-Forwarded-For")+"\n")
    }

four lines of code - and then i just call it with a handler:

    http.HandleFunc("/ip", ipHandler)

simple. i could call this function wherever i need it.

all i needed to research was the best way to scrape user IP addresses, and
implement only that functionality. it answers "what do i want" in a very
straightforward way.

with a static site, i imagine you'd need to wind up with external dependencies,
since you'd likely need to rely on javascript. this means adding the dep, making
sure it loads, and executing it. you need to integrate the javascript on any
page, and think about handling cases where javascript isn't available (some of
my readership refuses to execute javascript - i don't blame them!)

honestly, that sounds like a lot of toil to me, and discourages me. the dynamic
solution excites me, because the website viewer simply receives HTML that has the
IP address in it already. this has another nifty benefit: you can request the HTML
from non-browser tools & receive a correct response (otherwise, the tool would
have to understand javascript!)

another example - i generate all of my RSS feeds on my homepage when my website
starts up. this ensures that i get a fresh copy of my friends' latest posts.
this is another dynamic thing that would be nontrivial to do statically - it
would be so nontrivial that i'd probably just give up tbh.

instead, i've programmed my own rss feed fetcher that will work for years and
years with no maintenance.  additionally, i understand exactly how it functions.
i can't wait to make more little fun dynamic things just like it.

      >>> deployment is simple <<<

i use a shell script to deploy my website. it looks like this:

    #!/bin/sh -eu
    #
    # deploy my website

    cd /home/j3s/code/j3s.sh
    git fetch origin
    if git status | grep -q behind; then
      git merge origin/main
      go build
      mv j3s.sh /usr/local/bin/j3s.sh
      service j3s.sh restart
    fi

this script runs every minute on a cronjob, and rebuilds my site if the git repo
has been updated. in this sense the deployment is automatic - i just test my
code locally, upload it, and it's reflected in my public website within a
minute. good enough for me. and simple enough that it'll probably just work
forever. again, very few dependencies. you can read it and understand it in
ten seconds if you know a little shell. beauty.


                      you should do this too!
                    ---------------------------

i find that personal websites have a very _distinct_ feel on the web nowadays.
nobody really makes personal sites anymore, so when we stumble across them they
seem fun and quirky - and they can deeply reflect what the author cares about.

if statically generated sites suit you, please use them! but they don't suit me.
if you have values similar to mine, i strongly suggest trying a dynamic website.
it's a ton of fun, you can start small, and it enables you to iterate through all
manner of fun ideas! you can also write your code like shit and hardcode everything,
because hey - it's yours and yours alone. that's part of the fun. make it in your
favorite language! rust? perl? python? that's part of the fun too. do it because
it's exciting.


                           start small
                         ---------------

i know you're all excited now, but let's do a quick reality check.

we get it, you have big ideas. you want to use the big rust framework, you want to
learn elixer and implement wokesockets. google dot gov said that phoenix is the next
big web framework! isn't nasa using wordpress 6.9??

stop. consider how much time you actually have. consider how much motivation you have.

if you're like anyone else with a fulltime job, probably not much of either.

do you think that you can keep up with any project that's continuously developed
and makes breaking changes constantly? i hate to break it to you, but most
people who work with those projects _full time_ can't keep up. you definitely
can't in your personal time. your website will outdate itself in .2 seconds.

start small. make an index.html and focus on getting your language to serve it.
don't worry about RSS. don't worry about markdown. write HTML and serve it.
then, as your needs increase, extend the scope using the simplest, most
maintainable tools you can find - normally this means the standard library.  in
ruby, it might mean using Sinatra instead of Rails. in python, maybe use Gin
instead of Flask. i suggest going even further - can you just do it yourself
with 0 libraries? you should try - if you run into horrible blockers, you should
consider using something larger at that point. but there's no reason to start
with someone elses project.

start with your own project. just write python. just write ruby. just write erlang.
or WHATEVER! but if you start big, you'll burn out fast. that's a fact bruh.

the beauty is that you'll be sitting on a plane and will have a marvelous idea for
a feature - and then, you'll realize that you can pretty easily incorperate it into
your personal website project. it's liberating. and so. much. fun.


                 closing arguments
               ---------------------

the web needs more weirdness. and more excitement. and more personality.

     SO GET OUT THERE AND MAKE A FUCKING DYNAMIC WEBSITE.

         THERE'S NOTHING STOPPING YOU.

            YOU WILL BE GLAD YOU DID.

                10/10 WOULD RECOMMEND

                      WITH MUCH LOVE.


                            JES

~2022-04-01