News for hackers. Stuff that matters.

Show HN: Shite: The little hot-reloadin' static site maker from shell

https://github.com/adityaathalye/shite

Or more precisely, my little site maker... It is a personal tool that I thoroughly enjoyed making, and enjoy using to write my website <https://evalapply.org>.

A caveat before any more; nobody was supposed to promote this insanity.

Like, terrible things have been done involving inotify and xdotool. But. It showed up on HN some months ago. That too while it was still, shall we say, fermenting. It got "done" some time thence, and of course one could not let the half-past just be. So here we are, for better or worse.

Thank you HN mods for helping me repost! _\\//

The README explains all, animated GIFs and whatnot. Some assorted highlights:

  - shite's, ah, "business logic" (except templates) is about 300 lines of Bash, written in Functional Programming style [^]. Pipeline all the things!
  - The innards won't surprise Perl/PHP/Shell gentleperson hackers from the last century.
  - The local hot reloading workflow is surprisingly nice, and occasionally hilarious! No JavaScript needed.
  - Full rebuilds are low performance and that's fine :)
  - Pandoc is great.
  - Sometimes sed and regex is exactly the HTML parser you need. *Very* sometimes.
  - stdio buffering can mess you up
  - jq -Rr @html # escapes HTML; what?!
... and all sorts of other stuff noted in the README and inline docs.

[^] because shell ain't a bad place to FP... https://www.evalapply.org/posts/shell-aint-a-bad-place-to-fp...

---

P.S.The commit history stops at 3-odd months ago, because I've been using a private fork for day-to-day content drafting, publishing, and layout tweaks. The "business logic" is by and large the same as the public version linked here.

( 59 comments | on HN )
Re:Show HN: Shite: The little hot-reloadin' static site make... by 082349872349872 on Monday January 23, 2023 @06:46AM (#34487737)
One thing I enjoy about shell pipelines is that intermediate processes may terminate them.

eg https://www.99-bottles-of-beer.net/language-bourne-shell-108...

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @10:01AM (#34489546)
In fact, I rely on that sort of early termination / circuit breaking as a feature!

That is a big reason why I use functions. They help me define sane fallbacks, and/or enforce API contracts. Those, in turn, are points where I can enforce "fail and die" behaviour.

Design notes: https://www.evalapply.org/posts/shell-aint-a-bad-place-to-fp...

Example from shite: Hard stop if mandatory front matter for posts is absent: https://github.com/adityaathalye/shite/blob/master/bin/templ...

edit: clarity

Re:Show HN: Shite: The little hot-reloadin' static site make... by 082349872349872 on Monday January 23, 2023 @10:10AM (#34489685)
nice ... and the Heredocs are a nice way to template!
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @12:16PM (#34491795)
Right?!

It was a bit of a lightbulb moment. I wanted a way to just write HTML templates. What really sealed the deal was the ability to punch content from stdin anywhere within a heredoc's scope using `$(cat -)`: https://github.com/adityaathalye/shite#templating-system

Re:Show HN: Shite: The little hot-reloadin' static site make... by datpiff on Monday January 23, 2023 @09:26AM (#34489085)
A+ name, no notes
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @09:46AM (#34489337)
Heh, thank you. It almost wrote itself.

I was trying to cook up a clever tagline, and fell upon "static sites from shell" and my brain looped about and found the tongue twister, sort of like "She sells sea shells on the sea shore", and well all esh shounds shtarted shounding like thish.

These days I like that name more because it (hopefully) alerts the Dear Reader about the quality of software they are about to visit, should they take it upon themselves to do so.

Re:Show HN: Shite: The little hot-reloadin' static site make... by jrm4 on Monday January 23, 2023 @10:51AM (#34490264)
Lol, funny, I dig it.

Right here in real life I just do http://zim-wiki.org + a custom CSS Template + a few shell scripts.

http://jrm4.com

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @12:02PM (#34491579)
Thanks :)

Likewise, I'm basically locked into "life in plaintext", as a die-hard orgmode user.

With what I have on disk, a big positive is any "system" of organisation is opt-in, post-hoc, and fungible.

Like, today, shite can be seen as merely one lens into a subset of my org files, to compile that subset into a website. Tomorrow I could bring back hugo.

That choice has no bearing on how any other method of organisation might use those same files (e.g. I can pull up index views using orgmode's own query feature set).

And further, a single blog posts's org file can power live demos in Emacs (org-babel), and gets exported as a blog post, and as a PDF slide deck, like this: https://www.evalapply.org/posts/why-and-how-i-use-org-mode/i...

Re:Show HN: Shite: The little hot-reloadin' static site make... by masukomi on Monday January 23, 2023 @12:16PM (#34491789)
This is amazing and i love it.

As much as I've been enjoying hugo, I've been craving something that's much closer to this.

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @12:20PM (#34491856)
Haha thank you.

I confess, I take childlike delight in every hotreload on save. Had it not worked well enough, I'd have stuck with hugo at the cost of a jankier authoring + build pipeline (org --ox-hugo--> markdown --hugo--> html).

Re:Show HN: Shite: The little hot-reloadin' static site make... by yakshaving_jgt on Monday January 23, 2023 @12:46PM (#34492236)
I'm assuming just about everyone is aware of the meaning of the word.

https://www.urbandictionary.com/define.php?term=Shite

Kind of depressing that people find this amusing.

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @01:12PM (#34492615)
This remark prompted me to go rewatch (make sure you have headphones on)...

this bit of fry and laurie https://www.youtube.com/watch?v=cVe3fTL1cPM

this bit by atkinson and cleese https://www.youtube.com/watch?v=OGFz9gt0-Fc

and this bit by atkinson alone https://www.youtube.com/watch?v=R7OxTxAvvLw

made my day :)

Re:Show HN: Shite: The little hot-reloadin' static site make... by badcppdev on Monday January 23, 2023 @02:12PM (#34493478)
It's sad because it's not hard to pick a name for a project that isn't a swear word.
Re:Show HN: Shite: The little hot-reloadin' static site make... by 082349872349872 on Monday January 23, 2023 @03:35PM (#34494604)
I once had a gig someplace where the tradition was to name Hamming Distance 1 away from swear words. Best of both worlds?
Re:Show HN: Shite: The little hot-reloadin' static site make... by mrlonglong on Monday January 23, 2023 @02:17PM (#34493543)
Oh do one mate quit griping and get with it!
Re:Show HN: Shite: The little hot-reloadin' static site make... by nmeofthestate on Monday January 23, 2023 @04:04PM (#34495004)
I suggest a SFW rename to "connery"
Re:Show HN: Shite: The little hot-reloadin' static site make... by talideon on Monday January 23, 2023 @05:11PM (#34495851)
You might want to look that up in French, but replace the 'y' with 'ie'...
Re:Show HN: Shite: The little hot-reloadin' static site make... by pragmatic8 on Monday January 23, 2023 @08:41PM (#34497947)
Could you please expound on why you believe that to be depressing?
Re:Show HN: Shite: The little hot-reloadin' static site make... by yakshaving_jgt on Tuesday January 24, 2023 @12:04AM (#34499530)
Sure. It's not the coarse language that I object to — it's the lazy, juvenile humour. It's similar to penisJS[0] — a software analogue to children defacing the chairs in their school classrooms with drawings of genitalia.

I think it's a pretty bad look for the industry.

Not to say there shouldn't be humour — there should be more humour. Personally, my most popular software projects are purely comedic, and they're also a little more coarse than this.

To put it another way: I'd prefer the software humour to be a little more Sean Lock and a little less Beavis and Butt-Head.

[0]: https://github.com/edankwan/penis.js/

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @05:29AM (#34501911)
I hear you. Thank you for sharing your thinking. All I will say is, from where I stand, it is all working as intended; the code and the phraseology :)
Re:Show HN: Shite: The little hot-reloadin' static site make... by jamal-kumar on Monday January 23, 2023 @01:08PM (#34492566)
This is really impressive, I tried making my own SSG in shell scripts after looking at all these bloated ways to do it and realizing "this is something I could literally do in ten minutes of bash". It works for my use case but you went WAY further with the concept, good stuff
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @01:29PM (#34492903)
Thank you! It most assuredly was not "ten minutes of Bash".

You see, there comes a time in every self-respecting Yak-shaving programmer’s life when one is driven to render large-scale follicle trimmage unto a sizeable Yak. In my case, ‘twas and ‘tis the deceptively diminutive but in fact mighty Site-Maker-Yak that renders World Wide Web Sites publishable unto the Internet.

I wager, engaging oneself in the glorious enterprise of Yak-shaving is at least as therapeutic for the trimmer as it must be to the trimmee. I wholeheartedly recommend it :)

Re:Show HN: Shite: The little hot-reloadin' static site make... by jamal-kumar on Monday January 23, 2023 @02:48PM (#34493969)
Yeah the live reload is especially impressive, I was literally just slapping content in between a header and footer and getting away with easy clean results hahaha
Re:Show HN: Shite: The little hot-reloadin' static site make... by dboreham on Monday January 23, 2023 @01:31PM (#34492926)
Y'all know that's a word in Scottish English, right?
Re:Show HN: Shite: The little hot-reloadin' static site make... by satvikpendem on Monday January 23, 2023 @01:39PM (#34493030)
I'm pretty sure that's the joke.
Re:Show HN: Shite: The little hot-reloadin' static site make... by jwdunne on Monday January 23, 2023 @01:32PM (#34492945)
Northern English dialect too…
Re:Show HN: Shite: The little hot-reloadin' static site make... by raffraffraff on Monday January 23, 2023 @01:34PM (#34492974)
And Irish
Re:Show HN: Shite: The little hot-reloadin' static site make... by walthamstow on Monday January 23, 2023 @01:36PM (#34492993)
London too
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @01:43PM (#34493070)
A Bit of Fry and Laurie, Concerning Language https://www.youtube.com/watch?v=3MWpHQQ-wQg
Re:Show HN: Shite: The little hot-reloadin' static site make... by mrlonglong on Monday January 23, 2023 @02:15PM (#34493524)
And southern too. All shite.
Re:Show HN: Shite: The little hot-reloadin' static site make... by christophilus on Monday January 23, 2023 @06:29PM (#34496638)
> Before you get too exshited, may I warn you that the MIT license means I don't have to give a shite if this little shite maker fails to make your shite work.

I don’t think they knew that.

Re:Show HN: Shite: The little hot-reloadin' static site make... by n8henrie on Tuesday January 24, 2023 @11:34AM (#34505929)
What else would it be referring to? Glancing at the top of the readme I don't see eg an acronym spelled out.
Re:Show HN: Shite: The little hot-reloadin' static site make... by andrewmcwatters on Monday January 23, 2023 @01:41PM (#34493050)
Hey Aditya, you can make your command a little more unix-y if you feel so compelled by just renaming `shite.sh' to `shite' and run the shell script as a utility since it's already `chmod +x`'d.

Then you can `shite(1)` anywhere you want after you put the command in your PATH and feel like a proper `git(1)`.

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @01:48PM (#34493150)
Thank you for the review! If only you knew of all the glorious plans :,)

Apropos your note, may I direct you to "Unrealised Ambitions" in the README https://github.com/adityaathalye/shite#unrealised-ambitions

Re:Show HN: Shite: The little hot-reloadin' static site make... by appletrotter on Monday January 23, 2023 @04:28PM (#34495333)
> Apropos your note, may I direct you to "Unrealised Ambitions" in the README https://github.com/adityaathalye/shite#unrealised-ambitions

It doesn't have to be an unrealized ambition with a simple `mv` command ;)

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Monday January 23, 2023 @02:12PM (#34493479)
Sidelight: I tend to use functions as Unix tools a lot more than scripts as Unix tools. No need for PATH twiddling, file ownership/permission setting, among other things. I wrote about it here: https://www.evalapply.org/posts/shell-aint-a-bad-place-to-fp...
Re:Show HN: Shite: The little hot-reloadin' static site make... by freedomben on Tuesday January 24, 2023 @11:33AM (#34505917)
I do this too! Bash functions are incredible. They have to be the most awesome under-used function (pun intended) I know of
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @01:21PM (#34507670)
Ah a fellow person of culture :D

Maybe you will enjoy my "bash-toolkit" repo: https://github.com/adityaathalye/bash-toolkit which I've dubbed my "Swiss Army Toolkit" of functions-as-cmd-line-tools and useful-to-me patterns.

Which reminds me, I've collected more and should update the repo!

Re:Show HN: Shite: The little hot-reloadin' static site make... by TechBro8615 on Tuesday January 24, 2023 @12:54PM (#34507267)
I like this as a user but it always throws me off when I see it in a Git repo, where I'd prefer the .sh extension to hint at what's inside the file.
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @01:36PM (#34507925)
Indeed, this is why I retained the `.sh`.

If it were designed as a proper userspace tool (it is not, and may never be), I might have dropped the file extension. But I might also have chosen to keep the `.sh`, and create an alias instead, during install. That way I get to have both micro-conveniences.

Re:Show HN: Shite: The little hot-reloadin' static site make... by andrewmcwatters on Tuesday January 24, 2023 @03:23PM (#34509725)
For reference, I think npm does this too, and IIRC, they just symlink the utility name.
Re:Show HN: Shite: The little hot-reloadin' static site make... by alexchantavy on Monday January 23, 2023 @02:32PM (#34493743)
I really like the dreams and desires section and how it explains the philosophy and how you view the project
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @01:47PM (#34508100)
Thank you :)

I started writing a "Goals" and "Anti-Goals" section, as I almost always do for sizeable projects [^]. But then I thought two things, "that's boring", and "waitaminute... when people say 'goals', what do they really want to achieve or fulfill? Dreams and desires.". And so it came to be.

[^] e.g. https://github.com/adityaathalye/clojure-by-example#workshop...

Re:Show HN: Shite: The little hot-reloadin' static site make... by alexchantavy on Saturday January 28, 2023 @12:55AM (#34555562)
Yeah, and part of defining what tool is is defining what it is not :)
Re:Show HN: Shite: The little hot-reloadin' static site make... by maw on Monday January 23, 2023 @04:36PM (#34495428)
Serious(-ish) question: does "And last but not least, I hereby decree that all texsht herein be read in Sean Connery voish." mean that this technically isn't FOSS?
Re:Show HN: Shite: The little hot-reloadin' static site make... by m_mueller on Monday January 23, 2023 @04:42PM (#34495496)
*FOSSH
Re:Show HN: Shite: The little hot-reloadin' static site make... by chubot on Monday January 23, 2023 @05:00PM (#34495722)
Nice! I also use inotifywait for hot reload when writing https://www.oilshell.org/

I never heard of the xdotool method ... although it sounds like it has some drawbacks? https://github.com/adityaathalye/shite/blob/master/bin/hotre...

I do it with a crappy Python web server that dynamically inserts some JavaScript. This also has bugs and drawbacks, though I don't think any fundamental ones ... At some point I would like to "make it nice", but it has been working well in practice for years

I think the method is reasonable, and doesn't depend on your local desktop environment as much.

I also have a Makefile for incremental rebuilds, but I would really like to replace that with Ninja. Ninja goes pretty well with shell (although it also has the issue of needing to escape $ as $$)

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @04:43AM (#34501607)
Lovely to hear from you, Andy! Thank you for sharing. It's good to know this work is in fine company :)

> although it sounds like it has some drawbacks?

Oh yes. The Xdotool Reload Method emulates keystrokes, so it has... drawbacks... as you put it mildly :)

For my use-case, it literally does F5, or it fills out a url and hits Enter. cf. this `case` statement: https://github.com/adityaathalye/shite/blob/master/bin/hotre...

I wanted to keep /mandatory/ moving parts to a minimum in a hand-rolled setup. So I sort of went hardline about avoiding prerequisites like a server process, and especially a JS client. The xdotool trick worked surprisingly well (for the most part), and so I stuck with it!

> it has been working well in practice for years

This is the holy grail. I really hope I get years-long stability out of it. Based on my experience so far, I feel good about the long-term odds.

> I also have a Makefile for incremental rebuilds, but I would really like to replace that with Ninja.

I was going to write a Makefile at some point. I'll have a look at Ninja. Thanks for the tip!

Re:Show HN: Shite: The little hot-reloadin' static site make... by rlt on Monday January 23, 2023 @05:55PM (#34496290)
Nitpick: Generally “hot reloading” refers to reloading a single module or component in the system, while retaining the rest of the page state.

But maybe this counts because it’s a static site.

Re:Show HN: Shite: The little hot-reloadin' static site make... by andrewflnr on Monday January 23, 2023 @06:15PM (#34496473)
I was curious how the hot-reloading works on the browser side. It looks like it starts its own Firefox window, keeps a reference to it, and somehow directly sends an F5 keypress to it? I don't quite follow how that part works.
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @05:16AM (#34501823)
xdotool emulates user actions under the X Window System (e.g. typing, mouse around, click etc.).

I'm using it to send keypresses to the browser, as you rightly observe.

So if I want to just reload a page, the browser gets F5.

To GOTO some page, it gets a stream of keystrokes for the URL characters and then Enter.

It's really that simple-minded, and it works!

This case statement covers my usage: https://github.com/adityaathalye/shite/blob/master/bin/hotre...

Re:Show HN: Shite: The little hot-reloadin' static site make... by andrewflnr on Tuesday January 24, 2023 @11:41AM (#34506038)
Thanks for the explanation!
Re:Show HN: Shite: The little hot-reloadin' static site make... by rcarr on Monday January 23, 2023 @08:04PM (#34497625)
This guy also made a bash ssg, no hot reloading though as far as I’m aware:

https://github.com/karlb/karl.berlin

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @05:23AM (#34501874)
Ooh, I like what they're doing. Thanks for the pointer!
Re:Show HN: Shite: The little hot-reloadin' static site make... by ramrunner0xff on Monday January 23, 2023 @11:46PM (#34499404)
amazing mind-link. i have also built a similar program (also called shite) only centered around plan9's rc shell and ndb, to manage my shite ;) (my use case is building a gemini+html output page with date/tag navigation from mostly plain text + minimal markdown in the form of tags and links).

https://git.2f30.org/shite/files.html

Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Tuesday January 24, 2023 @05:09AM (#34501779)
plan9! Some day I'll try it out. Such a nicely integrated system. As an emacs user, I cracked up at the manpage for Emacs in plan9. Hilarious!

> https://git.2f30.org/shite/files.html

So I looked at the templating code. Have you considered here documents for templating? Being able to declare complete HTML fragments is a big advantage for debugging parts, and keeping overall HTML valid. I author HTML fragments in an HTML-mode buffer and get linting etc. to make sure my markup is OK. Then I can just copy-paste it back into the heredoc.

Another thing I did was to use functions as wrappers for each HTML fragment, so that I could define guarantees in the scope of the HTML (any variable / field that must be present or must be of a certain type).

Re:Show HN: Shite: The little hot-reloadin' static site make... by ramrunner0xff on Tuesday January 24, 2023 @04:39PM (#34510842)
I haven't really, because the only place where i needed valid html generated mostly by the program is on the navbar , the taglist etc. the main docu is kinda plaintext on a div when rendering html. But i will go back and investigate your idea since it would be elegant and rc supports normal here documents. for example

  ed $3 <<EOF
  g/$1/s//$2/g
  w
  EOF
changes all occurrences of $1 to $2 in file $3. :)
Re:Show HN: Shite: The little hot-reloadin' static site make... by adityaathalye on Wednesday January 25, 2023 @02:56AM (#34515627)
Yeah, I noticed that `ed` invocation in the rc manual. I'm tempted to find use-cases for it. That way I can lay claim to having used the one true editor :)

In general, I like making programs out of declarative constructs and/or literal data, because it's so much easier to do "local reasoning" with those things, as compared to imperative procedures, or heaven forefend, live objects.

Re:Show HN: Shite: The little hot-reloadin' static site make... by dickholesalad on Tuesday January 24, 2023 @03:09PM (#34509497)
The name is just… thank you.