A manifesto for small, static, web apps

I’m having a lot of fun building small, static web apps. And there are certain principles I’m trying to stick to as I do it. Let’s see what they are…

What is a manifesto anyway?

As I started writing this, I asked myself: “Is this actually a manifesto? What is a manifesto?”

But the definition is actually helpful: “a written declaration of the intentions, motives, or views of the issuer

And what I want to make clear is that these are my intentions. Sure, you may find them helpful. Or you may disagree with them entirely. That’s fine. They aren’t yours.

I’m writing them down because I think they are an interesting way to look at software for the web. And a useful set of constraints for what I am trying to do. You may want to adopt some or all of them for your own projects. But I’m not demanding anyone does. You can take or leave them.

The Manifesto

Here is a summary of the articles, I shall talk more about each below:

  • Static first/only
  • No login
  • Don’t store user data
  • Use the smallest JS library possible
  • Use web standards as much as possible
  • Use simple build steps that won’t break
  • “Done” is a goal
  • Zero-maintenance (and easy maintenance) is a goal
  • Don’t minify
  • Be accessible

1. Static first/only

My goal when building these web apps is to see what I can do with static files only. I’m very curious about how far you can take static-only apps. It makes hosting trivial and mostly free. It makes apps fast. And it’s a really interesting constraint to work within.

In some cases there will be a large benefit in having a database or something else that is more dynamic. In these cases I will try to build “static first”. My notes app is a good example of this: it works fine writing to local files. But there is a large benefit in having notes available across multiple browsers. So I’m thinking about ways to achieve that.

In these cases I’m hoping that the app will be “static first”. It will work without some additional “cloud” stuff as an optional enhancement. But first it will be a static app.

2. No login

I mentioned this in my last post, but the first time I came across an app that worked using the browser’s local storage (Gaya Kessler’s time tracker, “Thyme“) and had no login it was so surprising and delightful. I can just use this tool, without registering and handing over an email address? I just click a button and works?

I want my helpful little apps to be like this.

3. Don’t store user data

By this I mean, don’t store data on behalf of the user. Find ways to let the user store their own data.

This frees you from privacy policies and rules. It helps with the “No login” goal. It helps with the “Static first” goal. And yes, it’s a constraint/limitation. But it’s part of the challenge: how can you implement your tool in a way that doesn’t need you to store data?

Again, my previous post explores this.

4. Use the smallest JS library possible

I actually fail at this as I normally use AlpineJS, which I realised recently has steadily grown to about 43kB. I almost certainly don’t need 40+kB of JS to do most of what I want to do. It’s super helpful as a reactive JS library. But Petite Vue clocks in at 6kB. Preact is 3kB. And Alpine v2 was 24kB. So it’s feeling a little bloated (sorry, Caleb!).

However, I want to reduce this, so having this as a goal will encourage me to look around.

5. Use web standards as much as possible

Web browsers have so much built-in stuff now. And these web apps should assume up-to-date browsers with modern features. This helps achieve simple build steps and fewer dependencies.

6. Use simple build steps that won’t break

In order to make maintenance easy, build steps should be simple and robust.

I do currently use TailwindCSS, but I consider that robust and it has few dependencies. Its not breaking every year and as the output is static I consider it acceptable as a tool.

Currently, my other build steps are:

  • build.sh – a project-specific shell script that performs whatever other steps are needed to build the site. It’s a shell script, so it runs everywhere and should have a long lifespan
  • while true; do ./build.sh; sleep 5; done; – this is fine as a “watch” script. It doesn’t hot-reload, it doesn’t auto-refresh. But that’s fine. I accept needing to manually reload a page as acceptable. It’s zero-dependency and is unlikely to break. That’s more important.

I’m sure there are better ways. But these work and meet my needs without compromising the other goals.

7. “Done” is a goal

I hear so much about software never being finished. But I think, these little apps can and should be finished. They should reach a state where they are complete.

The pattern of startups is so familiar. Build something simple; gain excited users; realise you need to compete and grow; add more features; pivot to different features; add more features; either a) run out of money and shut down or b) get acquired, monetise and become crap.

The whole idea of my little apps is that they can be built quickly to do a simple job, and shared easily and cheaply on the internet for everyone to use. They don’t need to grow or be sold. They don’t even need to make money – I put a ko-fi link on some of mine, or link to something else I make or sell, but that’s 100% optional. The joy is in the making and sharing.

So I think these tools can be complete. By being static, not having logins, using web standards and minimal libraries, they should be good for a long time!

8. Zero-maintenance (and easy maintenance) is a goal

Related to “Done” being a goal is that zero-maintenance is also a goal. It won’t actually be zero. But in making things be “done”, in referencing minimal libraries and in not storing user logins and data, it should be able to be close to zero. Using simple build steps ensures that returning to a project to do maintenance is also easy.

9. Don’t minify

I want these tools to be educational. If nothing else I want others to see I want people to be able to inspect the source. They will use minimal JavaScript, and that will be compressed in transit by the CDN. So I’m not concerned about performance. Readability is more important.

So, while I know about source maps, I think “don’t minify” is a good goal.

10. Be accessible

I’ve been bad at this but it needs to be a part.

Web apps are harder to do accessibility for than web sites as they are more interactive. I need to learn more in this area and these little projects are an excuse to do that.

But I confess, I have neglected it, and I really want the things I make to be accessible.

Other goals, such as using web standards, should make accessibility easier.

This should not be neglected. It should be a priority, both for my own learning, and it’s the right thing to do for my little tools.

Summary thoughts

As I wrote this all out and explained it, it was amazing how all of these goals interlink with each other. This is why I’m excited about the approach. Joining all these things up enables a whole new way of thinking about building stuff.

Being able to build and publish a finished thing that works and does something useful but that requires no (or very little) future involvement from me is really exciting. It’s freeing. It opens up my geeky creativity.

In many ways this manifesto is massively constraining. But in other ways it makes doing fun web-stuff possible again.

Arguably this is my own “Jamstack“, and I’m about twelve years later than everyone else to it. I’m fine with that. Jamstack also had APIs at its core and this frequently meant having a node.js back-end, which is, well, just not my jam (yes pun intended).

I hope this inspires you in some way.