Static sites with Dart
For most of my projects, I use hugo as a static site generator. It's fast, it's mature, it's great and I'm pretty happy with it.
However, I really like the Dart programming language and wanted to see how much of my personal website I could write in Dart. I can't really invoke Dart compilers from hugo, so I started to look for other options. There are static site generators written in Dart, but I couldn't find one that allows me to compile Dart without much hassle.
After stumbling across "Why I Built My Own Shitty Static Site Generator", I decided to give it a go myself and see what I could come up with. I have better things to do than coming up with a fast system with support for incremental builds and everything else I expect from a site generator, so I decided to offload as much work as possible to Dart's standard build system, simply called
build. With that system, you write a set of deterministic functions transforming inputs into outputs, called builders.
In my case, the inputs are a bunch of
.md files and html templates, and the output is the generated website you're seeing. I tried to write a set of builders for this transformation. After some days of experimenting, I'm very happy with the result - the
build package turned out to be an excellent fit. I'll compare it to hugo in the aspects I care about:
Thanks to incremental rebuilds, editing and rebuilding the site feels super quick. Subjectively, it rebuilds just as as fast and reliable as hugo. Dart's build system also cares about deterministic builds a lot, so the output of any incremental build is just what I'd get in a full build. With hugo, I sometimes ran into situations where editing some files (e.g. parts of the config) would just be ignored. I don't have those problems with Dart's build system at all.
Running a full build for deployment is noticably slower, but I don't really care about that. I deploy like twice a week and firebase deployments are slow anyway.
For my Dart website, I run
dart run webdev serve --auto reload to start a local server that reloads pages as they change. In my opinion, that comes close to the
hugo serve from Hugo.
I care a lot about having a single system to run all build steps for me, I don't want to run a chain of commands to build my website. Both hugo and my build setup work great here.
I don't really know CSS so I stole most of my website's design, but at least I could simplify it a bit by using Sass. As you might know, the reference implementation of Sass is written in Dart, and of course there are builders to transpile Sass to CSS. Very awesome - integrating Sass only requires one
dev_dependency in my pubspec.
Since I'll probably need to highlight a lot of Dart code around here, I wrote a custom syntax highlighter using the
analyzer package which gives me better results than highlight.js.
Overall, I really like how well Dart's build system can handle this task that it hasn't been really designed for. It's plenty fast and integrates with all the tools I like, so I'm going to use it to build websites now.
I was also pleasantly suprised to see that Dart's ecosystem has grown a lot, there were a lot of cool packages I could use:
front_matterpackage to parse a block of yaml containing metadata for a page.
markdownpackage to parse and render markdown.
- For Dart, I use my own syntax highlighter based on the
analyzerpackage. For other languages, I use the
- I like Shopify's Liquid template system and wanted to use that for my website. Easy to do thanks to the