Reading List
The most recent articles from a list of feeds I subscribe to.
Hooray for Hollywood
Feedback
Before I launched Svelte by Example, I called for early access testers in this newsletter. I don't ask for feedback often, I had to push myself to do this.
Sometimes I'm scared of receiving feedback that I'll agree with, but would push back the release when I want to get it out. Sometimes I'm scared of receiving feedback that could invalidate the entire idea. Sometimes I know there are problems but hope they'll magically go away if I ignore them, feedback might resurface them. Sometimes I'm overconfident and don't think it's worth getting another opinion.
No good excuse to be found. These are fears, and it's worth getting over them. Because if any of them are rooted in truth, they'll com back and haunt me rather sooner than later.
A few people responded to my request (thank you!), and it quickly became clear the ask was worth it. The first version of Svelte by Example became way better because of it. The examples became more consistent, the design improved, a bunch of typos were edited out. I didn't process all feedback. Sometimes it doesn't match what you have in mind, and that's fine.
I've learned my lesson: time to get over myself and ask for feedback whenever I can.
Use a Nix Flake without Adding it to Git
When I work in my own repositories these days, I always add a Nix flake to the repo so that I can spin up a working development environment on any system with a single command.
What do I do when I’m working in someone else’s repo and they don’t want to adopt Nix flakes?
Normally, I’d just add the file to my copy of the repo and gitignore it locally so I don’t commit my personally-specific files with the rest of my changes.
Svelte 5 preview review
The Svelte team set up a miniature documentation site highlighting the new features coming to Svelte 5. Here's a quick review of my three favorites: runes, events, and snippets.
Runes
The star of the release will be runes. Currently, Svelte uses existing language features like export and labels for its reactive features.
<script> // A prop export let name; // A reactive statement $: console.log(name);</script> <p>Hello, {{ name }}!</p>
Svelte 5 is a departure from this setup, and has more explicit "runes" instead. Runes are function calls that get transformed by the compiler, and can be recognized by their $ prefix.
<script> // A prop let { name } = $props(); // A reactive statement $effect(() => { console.log(name); });</script> <p>Hello, {{ name }}!</p>
I personally liked the (mis)use of existing JavaScript syntax for reactivity. However, it did come with weird edge cases which runes will iron out, and having one "system" for all reactivity features does make Svelte look more consistent. So all in all I understand why the team decided to pursue this direction, and I'm looking forward to trying it out.
Events
Event handles in Svelte have previously been prefixed with on:. This prefix has been removed and replaced with a syntax that mirrors props.
<!-- Svelte 4 --><button on:click={() => …}> …</button> <!-- Svelte 5 --><button onclick={() => …}> …</button>
This makes component events more straightforward too as events are handled by callback props.
<!-- Svelte 4 --><Todo on:complete={() => …} /> <!-- Svelte 5 --><Todo complete={() => …} /> <!-- Todo.svelte --><script> let { complete } = $props();</script> <input type="checkbox" oninput={complete} />
This opens up a world of possibilities, as you can now dynamically spread props and events on a component, which is something I sorely miss coming from React.
We often use form objects in projects that hold form state, and have methods to bind form values, handlers, and errors on a field component in a type-safe way. This is finally possible in Svelte.
<script> let form = createForm({ name: 'Sebastian' });</script> <TextField {...form.field('name')} />
Snippets
This is an interesting one I haven't seen in other frameworks yet, but solves a problem I've had in other templating languages. Snippets allow you to reuse an HTML snippet within the same component file.
Here's an example that would be relevant to my blog: I have a PostHeader component that's used on the index page and post page. On the index page, the title should be wrapped in an h2 tag, on the post page in an h1.
{#if onPostPage} <h1><a href="{{ permalink }}">{{ title }}</a><h1>{:else} <h2><a href="{{ permalink }}">{{ title }}</a><h2>{/if}
This is a small example, but grows increasibly difficult to maintain as the inner contents of the dynamic tag grows. In Svelte 5, you can extract the inner contents to a snippet.
{#snippet title()} <a href="{{ permalink }}">{{ title }}</a>{/snippet} {#if onPostPage} <h1>{@render title()}<h1>{:else} <h2>{@render title()}<h2>{/if}
Now there's no more repetition of the snippet contents.
There's more on the horizon for Svelte 5, read through the preview documentation for an introduction to all new features. Or if you're new to Svelte and want an introduction, check out Svelte by Example. (Which I'll update for Svelte 5 when it's released!)
Creating a writing assistant with ChatGPT Plus
There are many ways to use your own books in AI workflows. In this post I’m going through the most basic workflow that does not involve coding your own app, creating vector stores, or generating API keys. You can do this by just using ChatGPT (with a Plus subscription). Many (most?) writers are not programmers, so there is no coding required here.