GeistHaus
log in · sign up

https://zachleat.com/web/feed

atom
40 posts
Polling state
Status active
Last polled May 19, 2026 10:49 UTC
Next poll May 20, 2026 07:42 UTC
Poll interval 86400s
ETag "f63c9ef52f3be5845dabbeedebca7de7-ssl"

Posts

State of the Browser (2026) It’s 10PM: Do You Know Where Your JavaScript Is?
Show full content

This talk was given at State of the Browser (2026). Check out the event talk page (which includes a talk transcript, too).

We’ll talk about best practices to either reduce (or increase!) the JavaScript footprint on your web site to a sweet and very practical spot for best results. It’s far more common to have too much JavaScript on your web site, but can you go too far? Is zero JavaScript a worthwhile goal? Let’s talk about it!

Video lite-youtube { max-width: 100% !important; background-size: cover; } /* Plugin bug: clicking the red youtube play icon in the center would navigate to youtube.com */ lite-youtube:defined .lty-playbtn { pointer-events: none; } Watch on YouTube: State of the Browser (2026) It’s 10PM: Do You Know Where Your JavaScript Is? Links
https://www.zachleat.com/web/its-10pm/
AMA about Build Awesome, an Open Town Hall at the 11ty Meetup
Show full content

Here I field any and all community questions about the Eleventy rebrand to Build Awesome.

Watch on YouTube or below:

lite-youtube { max-width: 100% !important; background-size: cover; } /* Plugin bug: clicking the red youtube play icon in the center would navigate to youtube.com */ lite-youtube:defined .lty-playbtn { pointer-events: none; } Watch on YouTube: AMA about Build Awesome, an Open Town Hall at the 11ty Meetup Related:
https://www.zachleat.com/web/ama-build-awesome-town-hall/
An Official* Logo for HTML
Show full content

*Not official.

I was working on my slide deck for the upcoming State of the Browser conference and ran into what I would classify as a recurring issue: HTML needs a logo. There isn’t a broadly accepted official logo for (version-independent) HTML. There is a logo for HTML 5, but that versioned marketing term has long fallen out of regular use (and was introduced 18 years ago).

This is a community solved problem in both the CSS and JavaScript spaces!

I wish the classic orange badge hadn’t included a version number, but alas.

Anyway, I very quickly threw my hat into the ring and immediately recognized a much better option from Sam Stephenson sls.name that I’ll be considering canon moving forward (and hopefully this blog post puts some weight behind it for others too).

Here’s what it looks like rendered in your web browser:

HTML

I love the nod to the classic unvisited link color and the heavy outset border that doubles as angle brackets with the right head tilt.

If you’re interested in the source code, the HTML-only (copy-paste friendly) source code is included below (and also on Codepen):

<a href="https://indieweb.social/@sstephenson/116098428280403793" style="all:initial;cursor:pointer;font-size:2rem;width:4em;height:4em;color:blue;text-decoration:underline;display:flex;align-items:center;justify-content:center;background:#ccc;border:.5em outset #aaa;font-weight:900;">HTML</a>
https://www.zachleat.com/web/html-logo/
How Eleventy Survived: Funding, Growth, and Open Source Reality
Show full content

Eleventy started as a side project. Now it’s a critical infrastructure for thousands of websites.

TL;DR: Open source isn’t broken. But the way we fund it often is. Let’s talk about what actually works.

In this episode, we sit down with Zach Leatherman, creator of Eleventy (11ty), to talk honestly about what happens after open source succeeds. From nap-time coding and nights-and-weekends maintenance to venture capital pressure, burnout risk, and the reality of funding long-lived developer tools, this conversation digs into the cultural and financial tradeoffs behind modern open source.

We cover sustainability, community expectations, funding models that don’t rely on hockey-stick growth, and why “free forever” only works if the people behind the project can stay whole humans.

Listen in: How Eleventy Survived: Funding, Growth, and Open Source Reality

Also on:

https://www.zachleat.com/web/podcast-awesome-eleventy-open-source/
Eleventy, 2025 in Review
Show full content

A look back at the 2025 highlights for the 11ty org and the Eleventy project!

It was another huge year for 11ty. We shipped 177 releases (73% more than 2024) across the full 11ty/* suite. We closed 804 issues (15% more than 2024). We reduced core’s dependency count by 28% and weight by 22%. More folks are building with Eleventy than ever: our year-over-year npm downloads (for only core) are up by 51%!

https://www.zachleat.com/web/eleventy-2025-review/
No more tokens! Locking down npm Publish Workflows
Show full content

With the recent spate of high profile npm security incidents involving compromised deployment workflows, I decided that it would be prudent to do a full inventory of my npm security footprint (especially for 11ty).

Just in the last few months:

  • November 2025: Shai Halud v2 (PostHog) (and PostHog post-mortem): Worm infected ×834 packages. Propagated via preinstall npm script.
  • September 2025
    1. Shai Halud (@ctrl/tinycolor, CrowdStrike): Worm infected ×526 packages. Propagated via postinstall npm script.
    2. DuckDB: targeted phishing email (with 2FA) pointed to fake domain npmjs.help. Compromised packages were published with token created by attacker.
    3. debug and chalk: same as above: targeted phishing email (with 2FA).
  • August 2025: S1ngularity (Nx) (and Nx post-mortem): well-meaning but insecure code (from approved authors) was merged which allowed arbitrary commands to be executed via content in Pull Requests to the repo. Compromised packages were published via a stolen NPM token.
Expand to see the insecure YAML from the S1ngularity attack
# Some content omitted for brevity
on:
  pull_request:
    types: [opened, edited, synchronize, reopened]
  # …
jobs:
  validate-pr-title:
    # …
    steps:
      # …
      - name: Create PR message file
        run: |
          mkdir -p /tmp
          cat > /tmp/pr-message.txt << 'EOF'
          ${{ github.event.pull_request.title }}

          ${{ github.event.pull_request.body }}
          EOF

      - name: Validate PR title
        run: |
          echo "Validating PR title: ${{ github.event.pull_request.title }}"
          node ./scripts/commit-lint.js /tmp/pr-message.txt

Given the attack vectors of recent incidents, any packages using GitHub Actions (or other CI) to publish should be considered to have an elevated risk (and this was very common across 11ty’s numerous packages).

I’ve been pretty cautious about npm tokens. I have each repository set up (painstakingly) to use extremely granular tokens (access to publish one package and one package only). This limits the blast radius of any compromise to a single package and has helped manage my blood pressure (I accidentally leaked a token earlier this year).

Security Checklist

I’ve completed my review and made a bunch of changes to improve my security footprint on GitHub and npm, noted below. The suggestions below avoid introducing additional third-party tooling that may decrease your footprint short-term (while actually increasing it long-term).

Caveat: my current workflow uses GitHub Releases to trigger a GitHub Action workflow to publish packages to npm (and this advice may vary a bit if you’re using different tools like GitLab or pnpm or yarn, sorry).

  1. Use Two-Factor Authentication (2FA) for both GitHub AND npm, for every person that has access to publish. This is table-stakes. No compromises. Require 2FA everywhere.
    • On GitHub, go to your organization’s Settings page and navigate to Authentication Security. Check the Require Two-factor authentication for everyone and Only allow secure two-factor methods checkboxes.
    • npm requires you to specify this on a per-package basis that I describe in the Restrict Publishing Access section below.
  2. When logging into npm and GitHub, use your password manager exclusively! Never type in a password or a 2FA code manually. Your password manager will help ensure that you don’t put in your credentials on a compromised (but realistic looking) domain.
    • Would you know that npmjs.help was a spoofed domain? Maybe on your average day, but on your worst day? When you didn’t sleep well the night before? 😴
  3. Review GitHub users that have the Write role in your repositories (Write can create releases).
  4. Find any repositories using NPM tokens and delete the tokens in the settings for both GitHub and npm. We’re moving to a post-token world.
  5. Switch to use Trusted Publishers (OIDC) in the Settings tab for each npm package. This will also setup the release to include provenance as well (which is great).
    • This scopes your credentials to one specific GitHub Action (you specify which file to point to in .github/workflows/) and allows you to remove any references to tokens in the GitHub Actions YAML configuration file.
    • The big goal here for me was to completely separate my publish workflow and credentials and disallow any access to those credentials from other workflows in the repository (usually unit tests that run on every commit to the repo). You could also use GitHub Environments to achieve this. This limits the blast radius from worm propagation (via postinstall or preinstall) to publish events only (not every commit), which is far more infrequent.
  6. Restrict npm Publishing Access in the Settings tab for each npm package. Use the Require two-factor authentication and disallow tokens (recommended) option. Death to tokens!
  7. Check in your lock file (e.g. package-lock.json for npm). This is especially important when using a release script that uses npm packages to generate release artifacts. Use npm ci instead of npm install in your release script.
  8. GitHub Actions configuration files should pin the full SHA for uses dependencies (e.g. eleventy-plugin-vite). I learned that Dependabot can update and manage these too!
Other good ideas

Given the above changes, I would consider the following items to not to be of immediate urgency (though still recommended).

  • GitHub: Enable Immutable Releases preferably at the organization level. This will ensure no one can change tags and release contents after a release has been shipped.
  • Use a package manager cooldown.
  • Reduce dependencies! Every third party dependency has some risk associated with it, as you’re inheriting a bit of those developers’ security footprint too. It’s worth noting that the work being done by the folks at e18e to reduce dependency counts is making great headway to improve the ecosystem at large. You can do this in your own projects! I’m proud of the work we’ve done on @11ty/eleventy over the years (source: v3.1.0 release notes): Version Production Dep Count Production Size v3.1.0 ×142 21.4 MB v3.0.0 ×187 27.4 MB v2.0.1 ×215 36.4 MB v1.0.2 ×356 73.3 MB
  • Some folks recommend disabling scripts when installing (via npm config set ignore-scripts true or via stock use of pnpm). This might be marginally useful in some cases but in my opinion is just a short term solution in response to common attack patterns that we’ve already seen. Importing (or requiring) a compromised or malicious package can execute arbitrary commands without using a preinstall or postinstall script just fine. If you really need to lock down your environment, you might consider running a Virtual Machine, Dev Container, and/or using Node.js’ Permissions model or stock Deno.

Stay safe out there, y’all!

Additional Reading
https://www.zachleat.com/web/npm-security/