Why pree?

TLDR:

🛠️ for building websites, we spend too much time wrestling with tools.

we can go no build with modern web features (ESM, Web Components, etc.).

🚧 there are a few fundamental gaps though (e.g. web components render on client). 🧩

pree fills these gaps as leanly as possible.


A ton of modern web development is wrestling with build tools. A package has a new module format, your transpiler doesn't like that. The work-around pisses off the bundler. You fix that with a weird trick, but that messes up your test-runner, now your coverage reports are screwed up. You spend hours on getting your build tools to work, without having built anything.

There is a chance that you don't need many of these tools anyways. Bundlers were designed to handle dependencies and optimize asset delivery. Nowadays we can handle dependencies perfectly with ESM and import maps, and with HTTP/2 multiplexing, in a lot of cases bundling doesn't optimise anything, sometimes even lowering the performance. Modern CSS with its nested styles, CSS variables, CSS layers, etc. has filled the gaps that likes of Sass and Less were designed to fill. We got React, Angular, and others, to break our websites into isolated, reusable nuggets of logic, style and layout (i.e. components), but Web Components do provide all of that, alongside the possibility of server-side rendering, in an interoperable standard manner (e.g. you can use any web component anywhere without having to care about the framework it was built with).

So can't we just shed all that weight and build websites using no build tools at all? Well ...


As great as that sounds, in practice, there are still gaps. Even for smaller projects like documentation sites or blogs, which have fewer moving parts and require less logic on the client, there are few, but fundamental, shortcomings:

🧬 Web components render on client by default. This makes user experience janky and slow. You can pre-render them, but that would require a build step.
🏗️ Websites typically have multiple pages, sharing layout and tons of metadata, differing in a few. Without a build step, managing these shared and differing parts would be a headache.
👻 Many components are static: they don't do anything on the client. Removing their code, you wouldn't just be cutting down on downloaded assets, but also on unnecessary work the client has to do. But then again, that wouldn't be possible without a build step.

This is where pree comes in. It is a little tiny tool that meerly fills those gaps, as simply as it can, without changing much. It is specifically designed for building static websites (websites with fixed pages), as conveniently as possible, while being as "no build" as possible:

pree basically opens each HTML page as a client would, fetches necessary scripts and components and lets them populate the page, then saves the resulting HTML. Now when the clients get these pages, they are spared this initial wait time, as they get prebuilt HTML with pre-rendered components, and are also spared scripts, components and computation that were only needed for that initial rendering.


Q: Isn't this just another build tool?

A: It is, but a really thin and invisible one. With the exception of layouting, what you write is standard HTML/CSS/JS that browsers could execute without any build step, pree just makes them faster. Even after building, the client receives the exact same JavaScript, CSS and almost the same HTML that you wrote*.

* Except, again, for a bit of layouting, and some pre-rendered web components.
Q: What if I want to write Markdown?

A: You can. Just use a web component like zero-md. Load it build-only so that your users get prebuilt HTML and dont have to download a markdown parser.

<script build-only type="module" src="https://esm.sh/zero-md"></script>
<zero-md src="my-markdown.md"></zero-md>

In fact, these docs are written in markdown (with a custom component) and built with pree:

<m-d>
## Why `pree`?

TLDR:

- for building websites, we spend too much time wrestling with toolchains
- we can go _no build_ with modern web features (ESM, Web Components, etc.)
...
</m-d>
Q: What if I want to split HTML files into parts?

A: Web components can do that too. Web components are pretty powerful, becoming more powerful with pree as they can do magical stuff on build time without affecting client-side performance and user experience.

For example, this is how splitting is handled in these docs:

<script build-only type="module" src="./assets/components/use-html.js"></script>
<!-- 👇 this is the code for the side menu -->
<aside>
  <use-html src="./_toc.html"></use-html>
</aside>
Q: What sort of websites can be built with pree?

A: Static websites, like blogs, documentations, landing pages, etc. For dynamic pages (e.g. e-commerce), use another tool. Note that static doesn't mean non-interactive, just that you have fixed pages.

pree can be used for more complex use-cases as well. However, its main responsibility is to wait for an initial page load so users don't have too, which puts a cap on how fast can it prebuild a single page. With a bunch of fixed pages, you can speed this up with parallelisation (which pree does), but that might not be feasible in other contexts.

Q: What kind of components work with pree?

A: ALL web components work with pree. Static ones that are loaded build-only will be faster, as will interactive ones supporting SSR through declarative shadow DOM.

Q: Writing web components is hard though, right?

A: With proper tools, its a breeze. I use minicomp, and combine it with rehtm for more interactive components. They support SSR and are quite simple.

import { define, currentNode } from 'https://esm.sh/minicomp'

define('use-html', ({ src }) => {
  const host = currentNode()

  fetch(src)
    .then(res => res.text())
    .then(html => {
      host.innerHTML = html
    })

  return '<slot></slot>'
})
Q: Can you really build cool stuff without a build tool?

A: Judge for yourself. These docs are built with pree and no other tooling: check the source code.

Q: Whats with the front matter? Why not pure HTML?

A: I'm salty about this, but I couldn't come close to the developer experience of layouting with front matter using web components. As powerful as they are, web components are about isolation, which isn't what you want with layouting.



pree logo