skip to content
dz

Daniel Zenzes

1 min read

Eleventy: Markup statt Shortcode

Seit Juni 2022 nutze ich @11ty/eleventy-img für diesen Blog und habe es bisher immer nur brav aktualisiert, aber nie in die Doku geblickt. Mein Shortcode von damals, grob aus der damaligen Doku kopiert, hatte acht Argumente: Quelle, Alt, Klassen, Breiten, Formate, sizes.

async function imageshortcode(
	src,
	alt,
	className = undefined,
	imgClassName = undefined,
	widths = [400, 800, 1280],
	formats = ['webp', 'jpeg'],
	sizes = '100vw',
	includeOriginal = true
) {

Und baute daraus von Hand das passende <picture>/<source>-HTML zusammen:

const picture = `<picture ${pictureAttributes}>
	${sourceHtmlString}
	${imgHtmlString}
</picture>`;

Im Template sah der Aufruf dann so aus:

{% image "src/blog/bild.png", "Beschreibung", "", "" %}

Das aktuelle Plugin macht das überflüssig. Ein addPlugin, mehr ist nicht notwendig:

eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
	widths: [400, 800, 1280],
	formats: ['webp', 'jpeg', 'svg'],
	svgShortCircuit: true
});

Beim Build transformiert das Plugin jedes <img> im Output automatisch, inklusive loading="lazy" und decoding="async". Meine Blog-Bilder wurden zu normalem Markdown, mit normalen relativen Pfaden:

![Prototype Chain](prototype-1.svg)

Den Shortcode samt Helfer habe ich gelöscht. Artikel zu schreiben oder mal ein Bild einzubauen wird wesentlich einfacher.

Beim Umstieg ist mir bei ein paar Bildern aufgefallen, was der alte Shortcode nebenbei falsch gemacht hat. Er rasterisierte auch SVGs. Aus drei Diagramm-SVGs in meinem Post zu Prototypen in JavaScript und TypeScript wurden zwölf PNG/WebP-Versionen. Mit svgShortCircuit: true werden SVGs jetzt unverändert durchgereicht, und bei diesen Bildern macht das den Unterschied zwischen 2,8 MB und 236 KB. Kein Effekt über die ganze Seite, aber weniger Daten, die Besucher laden müssen.

Wer nur alle <img>-Elemente im bestehenden Code automatisch optimieren will: Der Code oben reicht schon, ganz ohne Shortcode oder Umschreiben bestehender Templates. Details zu weiteren Optionen findet ihr in der Doku.

brennan.day

Normalisierter Faschismus in Open Source

Brennan Kenneth Brown zieht die Linie, die ich gestern bewusst eng gezogen habe, konsequent weiter - von DHH über Ladybird bis Brave. Sein Kernpunkt, in einem Satz:

"Apolitical" has never meant a lack of politics. It's meant politics that current power doesn't have to defend.

Zwölf Millionäre, die genau wissen, wofür DHH öffentlich steht, haben trotzdem eine Million Dollar pro Kopf unterschrieben. Lest den ganzen Text. Er ist unbequemer als meiner. Das ist Absicht.

pnpm.io

pnpm 12 setzt auf Rust

Für mich bleibt pnpm die Paketverwaltung der Wahl im JavaScript-Ökosystem. Schon vorher war es deutlich schneller als die Konkurrenz, und dieser Umbau unter der Haube kann sicher nicht schaden.

Ich bin selbst ganz frisch auf der neuen Version unterwegs. Der Wechsel erfordert momentan auch noch einen manuellen Schritt. Gefühlt ist pnpm aber nochmal schneller geworden.

Das Turborepo-Projekt misst eine Verbesserung der Installationszeiten von 64 bis 90 Prozent unter Linux im Vergleich zu pnpm 10.28 - heise hat die Zahlen zusammengefasst.

Ich komme aus der 11er-Linie und habe deshalb selbst nachgemessen, auf einem MacBook Air mit M1: Eine Installation mit gelöschtem node_modules und gefülltem Store dauert unter pnpm 11.25.0 2,37 Sekunden und unter 12.1.0 nur noch 0,79 - rund dreimal so schnell. Ein Lauf, bei dem es nichts zu tun gibt, braucht statt 0,41 nur 0,06 Sekunden. Median aus je fünf Durchläufen mit --frozen-lockfile, beide Versionen auf demselben Store.

blog.stephaniestimac.com

On AI in coding

"But is the code correct?" He asked. And this, dear reader, is where the hard truth hit me. Jhey looked at the ChatGPT output. It had gifted me 5 lines of completely unnecessary code, and another bit was "fine" but not the most efficient way to write JavaScript. He made a few edits for me and left me to continue on with my CSS overhaul. -- The Web Witch's Blog

A few weeks ago, it took my colleague and me hours to find all the bugs that AI introduced into an application simply because someone had written code in a language and framework they were unfamiliar with.

I often use AI for development tasks, and it can be very useful - for example, when you need to apply similar changes to multiple files or when you want to improve your code style ("Tell me how this code can be written in a more readable way..."). However, AI can also produce a mess when you use it for something with which you have no experience. It's like working with a a new colleague who can be brilliant at times but would rather say something than admit that they can’t solve a problem. If AI only supports you on a topic you are familiar with, it will improve your speed and perhaps even the quality of your work. Maybe you can even learn how to improve the structure of your code or write that one specific test. If you have no experience with the topic you're working on, it can produce bugs and poor code; in the end, just copying and pasting code you don't understand won't make you a better programmer.

via Stephanie Stimac

1 min read

TIL: One file to rule them all: PEP-723 and uv

It's impressive what’s possible with Python nowadays! PEP-723 introduces a way to define metadata directly inside a Python file — including dependencies.

"This PEP specifies a metadata format that can be embedded in single-file Python scripts to assist launchers, IDEs and other external tools which may need to interact with such scripts."
PEP 723 – Inline script metadata

uv takes this a step further by handling virtual environments and dependencies seamlessly when executing such scripts.

For example, if you want to spin up a Flask server in one file, it looks like this:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#   "flask",
# ]
# ///
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello, World! 🚀"

if __name__ == "__main__":
    app.run(debug=True)

Save this file as server.py and run it with:

uv run server.py

Within seconds, the server is up and running. This makes it easy to execute Python scripts with external dependencies — without worrying about setting up a virtual environment manually.

Even better, you can make it a standalone executable script by adding this shebang at the top:

#!/usr/bin/env -S uv run --script

Now, the script will be executed using uv whenever it’s run (just ensure it's executable with chmod +x).

This approach offers a useful way to define and run Python scripts while handling dependencies — all within a single file.

Thanks to Rob Allen for writing about PEP-723 and how to use uv as a shebang line.

1 min read

Angular Migrations

In my current Angular projects, I strive to keep our growing application up-to-date with the latest stable features that Angular offers. The official migrations have been instrumental in achieving this. While some manual adjustments were necessary post-migration, the majority of my code transitioned smoothly.

Some migrations I highly recommend include:

  • inject() Functions: Migrates your application to use inject() for dependency injection.

  • Signal Inputs Migration: Converts existing @Input fields to the new signal-based input() API.

  • Signal Outputs Migration: Converts existing @Output fields to the new signal-based output() API.

  • Lazy-loaded Routes Migration: Converts eagerly loaded component routes to lazy-loaded ones.

I believe that offering migrations like these is incredibly helpful. Slowly but surely, Angular and I are becoming friends after all.

2 min read

New Hardware and Software in January

In January, I began adjusting some of my long-standing software and hardware habits.

🖥️ From iTerm2 to Ghostty

I had been using iTerm2 for years, and it consistently met my needs. Although they introduced some AI features, these were quickly made optional, and overall, I can still recommend the tool. Recently, I started exploring Ghostty, a terminal emulator developed by Mitchell Hashimoto. While it's still under development—e.g., settings must be edited in a file, though this is expected to change—it operates efficiently and integrates well with macOS. After configuring it, I decided to make it my new default terminal.

🤖 Monarch as a Spotlight Alternativ

For system searches and launching applications, I relied on Spotlight and never felt the need for more advanced tools like Alfred. However, after reading a recent post by Alexander Olma mentioning Monarch, I decided to give it a try. While I'm still evaluating it as my default launcher, I appreciate its enhanced capabilities, particularly the seamless initiation of web searches and integration with applications like Reminders. This experience has prompted me to explore alternatives beyond Spotlight.

🔎 Switching from Google to Kagi

Last year, I transitioned most of my email communication from Google to Fastmail, using iCloud for personal correspondence. The next step was to find an alternative search engine, leading me to Kagi. Although it requires a subscription fee, similar to Fastmail, I value my privacy and prefer not to exchange my data for free services. Kagi's integration with Safari is functional, and the search results have been satisfactory, making it a viable option for the foreseeable future.

⌨️ Adopting Logitech's MX Keys Mini

At my desk, I've decided to change my keyboard setup. While I still appreciate my NuPhy mechanical keyboard, its noise level isn't suitable for the office environment. I previously used Apple's Magic Keyboard but found myself favoring Logitech's MX Keys Mini, which I also use with my gaming PC. Seeking a quiet keyboard with a US layout, I chose Logitech's model as my new office standard.

🖱️ Experimenting with the MX Master Mouse

Having used a touchpad for years, I decided to experiment with a mouse to assess any potential benefits. Last week, I connected my MX Master to my Mac. While I'm not entirely certain about replacing my Magic Trackpad, I appreciate the touchpad's gestures for tasks like switching between screens or windows. I plan to spend more time adapting to the alternatives offered by the MX Master before making a final decision.

simonwillison.net

htmx offers stability as a feature

At the moment, I'm waiting to upgrade applications to the latest Angular version because breaking changes in the update are slowing down the development of one of the libraries we use. In this context, stability as a feature sounds very appealing.

People shouldn’t feel pressure to upgrade htmx over time unless there are specific bugs that they want fixed, and they should feel comfortable that the htmx that they write in 2025 will look very similar to htmx they write in 2035 and beyond. -- htmx blog

In my perception, things have gone very quiet around htmx in the last few months after an initial wave of hype. I'm curious to see if it will become a serious option for future projects.

via Simon Willison

github.com

Basic NextDNS Configuration

And here’s another useful tip if you’re using NextDNS (which, along with Wipr 2, is the reason I see no ads and get tracked less): This " Hitchhiker’s NextDNS Guide" pretty much covers all the key information you need for configuration.

I personally use NextDNS through the app, but Alex’s approach has its advantages:

Instead of directly applying the profile (on the router), I install the native apps for DNS relay and the firewall so I can quickly disable them (on individual devices). It's inevitable that you’ll occasionally need to load websites “without a content blocker” and without the DNS redirection — even if you’ve explicitly added domains to the general “allowlist.” -- iPhoneBlog.de

via iPhoneBlog.de

passfotogenerator.com

Creating Biometric Passport Photos

More of a note to myself than actual news: You can create passport photos using your smartphone and then adjust them on passfotogenerator.com. This can be particularly useful when dealing with small children. For instance, taking a passport photo of my one-year-old daughter was quite challenging with a professional photographer. Doing it in a familiar environment with more time would likely have been much easier.

To create a biometric passport photo, the following requirements must be met:

  • Biometric passport photos must measure 3.5 x 4.5 cm
  • The face height should occupy about 70–80% of the image
  • The photo must be sharp, high-contrast, and evenly lit
  • The image quality should be high with natural skin tones
  • The background must be plain, light-colored, and pattern-free
  • The head should be centered and positioned straight
  • Eyes must be open and looking directly into the camera
  • A neutral facial expression and closed mouth are mandatory
  • Head coverings are only allowed for religious reasons
  • Special rules apply for children and infants

via Volker Weber

1 min read

2024 Wrapped: My Default Tools

As 2024 draws to a close, it’s time to reflect on the apps, tools, and platforms that shaped my daily life this year. Here’s a comprehensive look at my go-to choices for productivity, creativity, and beyond. Anything that has changed has a strike-through the previous tool:

That’s my 2024 wrapped! What were your favorite tools this year? Let me know!

3 min read

Python Rediscovered: uv – The Swiss Army Knife for Tooling

As a developer who works extensively with JavaScript and Java, exploring Python anew has been an exciting journey. Back in university, I had already worked with Python, but at that time, I didn’t give much thought to tooling — it just worked, or so it seemed. Today, I understand that tools for dependency management and virtual environments are fundamental for modern software development.

However, much like in the JavaScript ecosystem, I encountered a vast array of options in Python: pip, poetry, virtualenv, and many more. The sheer variety, combined with tutorials often relying on different tools, can feel overwhelming when starting out.

To find a clear entry point, I reached out to my friend Oliver for advice. His response was concise:

Yes. Only uv. It replaces pip, venv, poetry, twine, setuptools, pdm, hatch, and everything else out there.

This recommendation felt like a practical solution to what could otherwise have been a daunting setup process.