176 comments

[ 2.7 ms ] story [ 235 ms ] thread
Nice, but I feel like to be qualified as a blog it needs two little additional things:

1- Make sure to order post by date (most recent first) and to display that date somewhere. The date can simply be taken from the post file meta data (e.g. creation time) to keep things minimal.

2- An RSS feed of course! It should be quite easy to generate a minimal one with only links and titles based on the existing script and a minimal RSS template.

That's fair!

1- I'm leaning towards an automatically generated file containing metadata, TOML or such

2- RSS is definitely coming, but is dependent on point 1 :-)

In the spirit of being minimally viable you could just have that in the filename and sort it before generating.
while rss is nice, it really shouldn't be required to be considered a blog.

being "followed" isn't always a good thing, it can create pressure to pander to your audience, the same thing that makes social media bad.

> while rss is nice, it really shouldn't be required to be considered a blog.

I agree. A blog is literally a web log. A chronological sequence of posts published on the web. RSS is certainly helpful for syndication and distribution but I wouldn't consider it to be a defining part of what a web log is.

Good point. My idealistic (realistic?) view of a web log is just a person typing out something unique that concerns that person and their view, life, or experiences.

As soon as you start catering to and fishing for views you lose that angle. Not a drama, but it’s already 99.5% of the internet.

Edit : I really like Marginalia search, for prioritizing non commercial content.

https://marginalia-search.com/

I don’t think RSS is required for soldering to be a blog, but I do think it’s required for it to be a viable one.
I agree but I could also imagine a world where a minimally viable blog is just an RSS feed.
> it can create pressure to pander to your audience

RSS creates no such pressure, as you needn't be aware of who/what is following you. It's a convenience function simply for the convenience, rather than as a form and measure of external validation.

the pressure is intrinsic from the knowledge that what you publish will now be displayed to a bunch of people, unfiltered by algorithms. do you really want to put out a post that you yourself might find useful, but might be considered shallow, low effort, repetitive, non unique by your readers, and a waste of their time?

the fact that people want to read every new thing being posted is external validation, rather than letting each piece stand alone by its merit.

RSS is very liberating. Quality of content is something very subjective and the audience can choose what to engage with. Nothing called perfect and not every post has to be a masterpiece.
For a similar reason, blog posts should have no words as these can become SOE and the purpose of blogging become intrinsic SEO.

Personally, I blog in my head but am concerned still it could lead to bias in my other activities which are mainly related to sitting under a tree by a lake in the middle of nowhere.

I’ve had a Wordpress blog since 2012, and many years of a Livejournal before that (when timeline filters were pretty much nonexistent) and I don’t think I ever felt this fear. Sometimes I had art to share. Sometimes a serious post about something that was on my mind. Sometimes just the results of a “which Teenage Mutant Ninja Turtle are you” quiz that half my friends had already posted.

Worrying about this “pressure” is a great way to be that guy with three posts about their new static site generator and nothing else.

My general experience with RSS users is that they understand not every post is for them. I've got some feeds that I read once or twice a year when I'm in the mood to learn what's going on in that corner of the world. I've got feeds where I skip 90% of the posts, because they're not the topic(s) I subscribed for. And I've got feeds I read daily, of course.

I tend to expect most useful sources of high-quality information to have a fair amount of off-topic content, since it's hard to reach critical mass on a single narrow niche. I read Hacker News, but click maybe 10% of the links

> do you really want to put out a post that you yourself might find useful, but might be considered shallow, low effort, repetitive, non unique by your readers, and a waste of their time?

Yes. If some of my readers don’t like that I do that too often (or even once), they can unsubscribe.

Meanwhile, _as_ a reader, feeds like RSS and Atom are super useful. They let a computer check my favorite sites so I don’t have to.

Honestly, my blog's RSS feed subscribers are the best. They tell me when the feed breaks and demand literally nothing else. Once in a while, they will email if they like a post. That's it.
Doing it easy for yourself and get quicker to the content is the way to go.
Thanks for sharing, I like your approach.

As easy as wordpress, square space or whatever claim to be, in my mind this is even easier, the solution is more elegant, and you expose yourself to a whole lot less crap along the way.

Edit: I recognise this doesn't cover hosting, domain registration etc.

Thanks! Yeah, I find this a lot easier. And yes, hosting is an exercise left to the reader :-) I might write about my hosting setup in an upcoming blog post.
Starts getting messy once you add sorting, pagination, categories/tags.
True! Luckily, I don't have a need for those features :-)
Definitely one of those things to design with the expectation that it will grow.
I'm more of a WordPress guy. Click "install wordpress". When I need something I add a plugin. No code required.
I would be genuinely interested to know how well the average wordpress blog handles a hug from the HN frontpage! :-)
(comment deleted)
There are cache plugins that effectively turn it into a static site. You could also run CF atop of it.

WordPress is used at scale by many companies.

Cache plugins still go through the PHP interpreter. I'm under the impression there still isn't anything faster than serving HTML files.

Better is use a static site plugin, then you don't have to bother with configuring any caching or external services.

Best is also use the SQLite Database Integration plugin, so the server doesn't even have to run MySQL/MariaDB (other than initial installation), and on an otherwise light server, the filesystem will effectively keep the site in page cache while using less memory, if I understand that correctly.

The WordPress interface can be kept behind HTTP auth or client cert.

> Cache plugins still go through the PHP interpreter. I'm under the impression there still isn't anything faster than serving HTML files.

Several WordPress caching plugins, like W3TC (https://wordpress.org/plugins/w3-total-cache/), actually add rules to your Apache/Nginx server so that the cached HTML pages are served statically without touching PHP.

That seems like a great stack, if you're looking for one!
Wordpress is of course overkill for a personal blog like yours, but implying wordpress cant handle a HN hug is a bit naive.

Millions of sites use WP and there are configurations to mitigate this. Some caching and easy server config will be enough to survive the “hug”

It's pretty easy to proxy your WordPress with cloudflare's cdn. Then your WordPress isn't hit very often.

WordPress handles volume just fine. Nothing a HN hug would disrupt.

> html_content = html_content.replace('Minimum viable blog', title)

So every time your post contains the string 'Minimum viable blog', it will be replaced by the title of the current post? That’s a bug, right?

Oh yes, good catch! The code in the post is the first draft from O1 and this string has been replaced with {{ title }}.
So every time you post snippets how of code from your template/blog engine, it will be replaced by current blog post title? /s
Kind of not /s, there’s currently no way to escape the template tags to make them appear in the output (except adding invisible Unicode characters or so).
Wow, yes.. that's actually exactly what happened here :-)
Also you don't need to separate :root from html in your code, they're always the same here, so you can save a couple lines by joining them.
And if talking of such optimisations—

• Trailing slashes in HTML content (apart from SVG/MathML) are completely useless, unless you’re serving the document in XML syntax (which you can’t do by accident). I personally think they’re harmful, because they encourage an incorrect belief, and are seldom even applied consistently.

• <html>, <head>, </head>, <body>, </body> and <html> are all optional. In practice, you should have an <html lang> attribute so that you can’t omit that tag, but the others can normally all be omitted.

• In case-insensitive things, lowercase will normally compress better. But Brotli messes things up because it’s a popularity contest of the HTML that people actually write, so that <!DOCTYPE html> compresses better than <!doctype html>, and even <meta charset="utf-8"> compresses better than <meta charset=utf-8>. Anyway, <meta charset="UTF-8" /> would be better as <meta charset="utf-8">.

• In <meta name="viewport" content="width=device-width, initial-scale=1.0" />, the space after the comma, and the .0 in initial-scale, are unnecessary. (In fact, in theory the .0 might not even be parsed: the badly-incomplete-and-extremely-dodgy spec says to use strtod, which is locale-dependent, so a French machine might parse initial-scale=1.5 as only one, ignoring the .5 because it’s not ,5. In practice I’d be mildly surprised if browsers used the real locale-dependent strtod, though I haven’t checked. If some spec somewhere says “assume LC_ALL=C in such cases”, which would also largely resolve the problem, I’d like to know.)

All up (and with title fixed to be a proper placeholder, as discussed):

  <!DOCTYPE html>
  <html lang="en">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>{{ title }}</title>
  <style>
      html {
          color-scheme: light dark;
          font-family: system-ui, sans-serif;
          max-width: 70ch;
          padding: 3em 1em;
          margin: auto;
          line-height: 1.5;
          font-size: 1.25em;
      }
  </style>

  <a href="/" id="head-link">Carl Öst Wilkens' Blog</a>
  {{ content }}
The hardest part is the DevOps part where you need to find out reliable host, how to deploy, CI/CD and all the server-related stuff if you want maximum customization.
This is basically how my blog works, except I use mistune as the markdown renderer, which has allowed me to extend it over time, including adding syntax-highlighted code blocks and latex math syntax: https://www.da.vidbuchanan.co.uk/blog/mathml-blogging.html

I also generate an index page and an RSS feed.

One thing that's been bugging me more recently (now that I have tens of articles written) is that I need to implement incremental rebuilds. Right now every page needs to get regenerated at once, which takes triple-digit-milliseconds. Unacceptable!

Thats an awesome setup and very similar to the one I have. But damn triple-digit-ms does actually sound shockingly slow for what is effectively just heavy text processing. Is there a huge amount of text?
One of my more dubious design decisions (7 years ago...) was to inline all my images as base64 (I was originally planning on having only simple diagrams that would compress well, but this is less true now). I like that every page load generates just a single request, and that you can ctrl+s the page without any breakage.

I haven't profiled anything though, it could also be the syntax highlighting being slow (it generates quite a soup of HTML tags).

A trick I used to use is to check during my custom build step whether the image is under 1k, and inline it if so, otherwise add its hash to the url and add a preload to the html header. I'm trying to get back to that in my latest custom build tool, but it's a gradual process to evolve it to that point properly.
Looks nice and minimal as well. Love the look of your blog!

The markdown2 package includes an option for syntax highlighting. You need to bring your own css though.

Dear god the bugs in that Python…
Nice post. Thanks for sharing! I've always been fond of independent websites like this. My own website began in a similar fashion about 25 years ago - minimal, straightforward, and entirely built with ASP (now known as Classic ASP), simply because that was the only suitable technology I knew at the time. Of course, that's not the case anymore. These days, it runs as a statically generated site using Common Lisp [1], and I expect this to be my long-term setup.

Starting with a simple collection of pages was a great way to get started and set up a minimum viable website. But as time passed, I found myself needing a few more features. In order of priority, these included:

1. RSS feeds.

2. A blog listing page with posts ordered by date.

3. The ability to tag posts by topic and generate tag-based index pages.

4. Support for non-blog content, like tools, games, demos, etc. that can also be tagged and included in the RSS feed.

5. Support for comments without relying on third-party services.

With each new requirement, the source code gradually grew. What started as a few hundred lines has now expanded to around 1300 lines of Common Lisp. Not too big in the grand scheme of things but not exactly tiny either. Still, I try to resist the temptation to keep adding every shiny new idea that comes to mind. This remains a solo passion project. I want the entire source code to be something I can hold in my head at once. If I encounter a bug, I want it to be something I can reason about and fix in under 10 minutes, and so far, fortunately, that has been the case.

That said, new ideas are always tempting. Lately, I've been enticed by the idea of adding a blogroll that provides a list of posts from my favourite bloggers. This could replace my usual feed reader. I haven't had the time to implement it yet, but if a quiet weekend comes along, that might just be the next feature I work on. Of course, I remind myself not to let this project spiral out of control. I certainly don't want this to grow into something that can read my email.

[1] https://github.com/susam/susam.net/blob/main/site.lisp

Thank you for the kind words. RSS and dates will definitely be needed! I can also see myself wanting to embed shaders and web games in the future... hopefully without increasing the complexity too much. I think your blog is perfect!
I have built Lamb with a Flock feature where you syndicate feeds into your blog. Mainly as an alternative to multi-user. https://github.com/svandragt/lamb

Might be useful as a high level reference

Exactly this. The ability to say, "I want to make this gadget" and then code it beats any wysiwyg.

I've done derived pages like post sets, indexes, and slideshows. Tag flavors for people and video games. Then just total control over how normal widgets like thumbnail galleries and pull quotes look and feel.

I don't know if a minimum viable blog needs to pre-render html... For this a PHP script is lightning fast and the source markdown file is the only source of truth -- if you correct a typo then it's immediately live, no need to think about rendering.
You can edit the typo directly in the already published document.

The pre-rendering is just there to provide the surrounding page content when you create a new page.

If I was going to do a blog today, I'd dump hand written HTML into an S3 bucket and call it a day.

The static site generators are nice, but it's really not a huge deal to spin up a few common css classes and maintain a little bit of mental discipline.

I think using a blog to communicate your ideas and skills is great. I think making the blog tech stack itself representative of those things seems distracting. Not everything has to be a smartass ego implementation. As long as you spend 5 minutes testing on mobile, your audience probably won't notice a damn thing the next time it touches the front page of HN or wherever.

I was handwriting HTML for a while but found that I write a lot more with an actual CMS. At the end of the day it doesn’t matter what your setup is as long as it helps you write as much as possible.
Static HTML will also hold up a lot better if a post gets popular than a heavyweight dynamic site framework will.
It is easy using standard static blogging framework like Hugo/Zola + Cloudflare Pages. I have a minimal blog (<100kb) and it meets all the criteria that OP has listed.

This is what I did:

- Use Hugo Blog Awesome theme

- Followed the 512kb guidelines and verified the page size.

- Stripped down any images and unwanted JS, but there weren't many.

1: https://512kb.club

2. https://radar.cloudflare.com/scan

(comment deleted)
The post is skipping the hosting side. Guess it doesn't matter too much these days? What's the best besides Netlify's or Cloudflare's free tiers?
Three lines in a Caddyfile would be sufficient
Imo oracle cloud free tier vm with a simple caddy or traefik setup.
I was thinking, another thing you could probably easily add is optimizing the images for web delivery, in your first article there are quite large jpgs.
I've been experimenting with minimal blogs for about 15 years. Some tricks I learned:

* You can get away with const title = lines.match(/# (.+)/)[1] and avoid frontmatter.

* My blogs never have so many posts they need pagination or tags, or categories, or sorting.

* JSX turns out to be a great vanilla server side string builder if you use a questionable hack like https://immaculata.dev/guides/enabling-jsx.html

* GH Pages with arbitrary build steps instead of (sigh) Jekyll is really easy now with things like https://immaculata.dev/guides/using-gh-pages.html

* highlight.js is still basically the king of super easy code syntax highlight by adding literally three lines to your HTML (shiki is cool but slooooow)

I've been wondering what is the benefit of putting up your own web server or scripts to serve your static content when you could put it in a Github repo or serve from something like S3?

The nice thing about latter is that the bandwidth, DDoS or other load-related issues aren't that much of a problem. Server maintenance also isn't a problem as you don't have any.

Usually a web server is a real simple add-on to an already established home network/lab.

It's not necessary. Just a fun thing to do.

> I've been wondering what is the benefit of putting up your own web server or scripts to serve your static content when you could put it in a Github repo or serve from something like S3?

I think you're overestimating the work required to put together a web server. For example, you mention dumping files in a S3 bucket, but that doesn't require much more work than whipping out a nginx instance and dropping said files in a folder.

Also, some people already run their own servers or deploy their services in some cloud procider. The work required to put together a blog is minimal.

One key benefit of putting up an own server is that there are no limitations on file types and much fewer restrictions on what kind of content you can create.

For serving static files, I can (and have) lived a long time with one of the "free hoster" sites -- from times before Github Pages or S3 were a thing I guess, today I'd go for Github Pages.

A key advantage of moving to an own server was that I can enable the odd feature or technology any time. E.g. most recently I wanted to have some "private" subspace with fancy authentication and it was easy to add with proper access to the server config.

(comment deleted)
I personally use a combination of quarto to statically render markdown files and hosting on GitHub pages because I don't want to bother with the self hosting for now. In the past I used a combination of R-markdown with a nginx server but decided to move to a simpler solution
Auto-index with header.html and some js for me
Nice solution, and congrats on winning HN for the moment. And thanks for 46elks. (Happy customer here.)
That was unexpected! My friend Calle wrote this article and he has made some really cool projects with 46elks (and demos with voice recognition).

Ping me on my work email and I’ll send you some fun links! :)