Ryan Cao

Projects Blog

Why I use Eleventy

Web development today is a flurry of excitements. New frameworks, new RFCs, new major releases occur almost continuously, each one often hyped as the "next big thing" or some silver bullet for web developers.

I've personally considered many of these frameworks as potential candidates for use on my own website. As I wrote in the Redesign v5 article, I nearly switched to SvelteKit with server side rendering and a database to back it up. I had also considered using Astro or Lume, two very cool static site generators of the non-client-side-JS type, for a potential rewrite of my website.

In the end, I decided to stick with Eleventy. As you see it today. Here are a few reasons why Eleventy remains my framework of choice for this website.

Flexibility #

One of the most amazing things about Eleventy is that it leaves a lot of things up to the developer to do. Although that could be annoying sometimes, for beginners, perhaps, but if you are a full stack web developer who knows what you're doing, Eleventy can do wonders for you.

For instance, recently I added static tweet embeds to this website using an Eleventy shortcode. Eleventy shortcodes simply handle the templating for you, and you are free to do whatever Node.js stuff you want in the shortcode. This particular shortcode calls the Twitter API to fetch tweets and renders them out in static HTML. It includes image optimization with eleventy-img for avatars (there's no support for media yet) and a fully homemade tweet embed layout using Tailwind CSS, which I already use on my website.

The filesystem routing and ability to break out of it is a breath of fresh air. With permalink, you can disregard the file/folder structure and do what you want with routes and things rather than having to use hacky ways to work around the framework that is supposed to be helping you develop and iterate faster.

For instance, in my website's build process, I build a pages.json manifest that my open graph image generator reads to generate these images with Satori. Using

permalinkBypassOutputDir: true,
eleventyExcludeFromCollections: true,

I was able to bypass the set output directory and build the file outside of it, while retaining access to Eleventy supplied data (such as the collections) needed to create the JSON file.

This flexibility is in a way provided by 11ty.js files, which I also happen to use for building assets. Instead of using complicated npm script setups or bringing in yet another framework like Vite running in parallel, assets on my website are built directly in Eleventy via Node.js APIs for each of the build tools that I use. For CSS, the PostCSS API is used to build the file, get the string, and write it into _site/. For JavaScript, esbuild's Node API is similarly used. The thing worth noting here is all of this is encapsulated in the Eleventy build process - there's no other command running or anything.

Font optimizations are also an essential part of my website. With web fonts, the design system of my website becomes much more legible and unique. However, without the proper optimizations, there will inevitably be CLS and a plethora of other issues.

With Eleventy, I have full control of every single part of the markup and assets, so I have the freedom to do whatever I want: add <link rel="preload">s, inline JavaScript into the <head>... With various other frameworks, this would not have been possible. You make do with whatever the framework gives you.

I also have a {{ gitRev }} global data file on my website that simply contains the Git revision hash for the commit. It's implemented with a very simple global data file which runs a subprocess (just once for each build) using execa. It's used for asset revving, where I append it as a query string to the end of asset URLs to make assets update on each push, refreshing the Cloudflare CDN and local web browser disk cache.

No assumptions #

Eleventy doesn't try to make assumptions about what you are trying to do. It doesn't drop a heavy client-side JavaScript framework on you from the moment you start building your website; it doesn't assume you need internationalization or anything. It simply does what you tell it to do.

With plugins, you can extend the behavior of Eleventy however you like. It provides an incredibly large API surface for you to hook into various parts of the build process. For example, transforms allow you to run any Node.js function on Eleventy-built files, with the output path given to you so that you have some idea what the file is doing in the project.

A wide selection of template languages and plugins gives you full control and customization over what your build process is doing and what it's spitting out. If you fetch data during your build process, it's probably a good idea to use Eleventy Fetch to cache your data somewhere so that repetitive builds don't take forever; if you want optimized images, eleventy-img can speed up the job of resizing each image into various formats by a lot; if you want to implement islands architecture components into your website to give it interactivity (which is what I am planning on doing), <is-land> could be your best bet! These plugins aren't installed by default, but if you want them, they're always there. If there's nothing available, you could always just roll your own.

This "no assumptions" philosophy is also evident in these individual plugins, both official and community ones. eleventy-img has a built-in function to generate markup; but it doesn't force you to use it. In the end, it's you writing your own shortcode and it depends on you, the developer, whether you want to use this pre-generated markup or write your own. On this website, I use linkedom to generate the markup using DOM APIs, and it works fine!

Community #

Eleventy has a large, friendly, and enthusiastic community that is constantly spitting out new ideas, tips & tricks, plugins, and open source websites. And the Eleventy team is very welcoming towards these community projects: @eleven_ty Retweets a ton of them every day. Compare this to @nextjs and you see the difference immediately.

The fact that Eleventy is so simplistic in its design makes it perhaps seem unwelcoming for newcomers. In addition, it doesn't do as much advertising and promotional content as, for instance, Next.js does. This makes the community small, friendly, and progressive, becoming better and better every day.

When you see all these Eleventy sites with incredible performance, it's ultimately because Eleventy doesn't assume things about what you want to build and gives you the flexibility to do whatever you want with the build process so that you can optimize it to the best of your ability if you want to. You are not in a constant battle with the framework - the framework is helping you get things done.

I want ESM for Eleventy v2 though. CommonJS really sucks.