Building a zero runtime dependency blog without a framework
Building a zero-dependency blog with Typescript, Markdown, and CSS
Faced with the prospect of creating a new blog, I decided to build one from scratch.
I hacked around for a day and this is what I came up with.
For context, I've spent a lot of time with React, Next.js, and Gatsby. I wanted the ergonomics of a modern JAMStack framework (dev server, markdown content, SSG), but without shipping a whole copy of React to the client.
Here are the different approaches I've used in the past:
- Custom CMS in PHP: Great for control, but over-engineered and a pain to maintain.
- Gatsby: Great for SSG from markdown, but a lot of JS to ship to the client.
- Next.js: In many ways the framework I wished Gatsby was. But still a lot of JS to ship.
For fun, and a challenge, I decided to build a zero-dependency blog using Typescript, Markdown, and plain-ole HTML & CSS. Orchestrating builds with a simple Node script, and using Remark/Rehype to pre-process the Markdown. It ended up being a nostalgic throwback to the days of task runners like Gulp and Grunt.
And in the end: look ma — no JS. 😎
That's not to say that there's no JS involved at all, I ended up cobbling together a few NPM packages to help with the Markdown processing and the dev server. At the time of writing, the stack is:
Package(s) | Description |
---|---|
node tsx | The build process is run from a single ~150 line NodeJS script, mainly making use of thfs and path modules to pipe files from src to dist with light modifications, and to transform markdown into HTML. I use tsx to run node scripts written in TS, with transpilation done on-the-fly. |
handlebars | I use handlebars as a templating engine to inject re-usable partials into the HTML, e.g. nav bar, document head. |
unified remark rehype highlight.js | The build script uses a unified pipeline for parsing markdown with remark and transforming it into HTML with rehype , with some plugins to inject additional html (e.g. nav bar) and do syntax highlighting with highlight.js , which is then inserted as a handlebars partial. |
nodemon http-server concurrently | Roll-your-own dev server. nodemon watches for file changes and re-runs the build process. http-server serves the html during local development, and this is all orchestrated with concurrently to wrap running multiple processes. |
And that's it! Thanks for reading.