
Svelte
Site officiel : https://svelte.dev/
Site web que j'adore pour suivre les changelog de Svelte et SvelteKit : https://svelte-changelog.dev
Svelte couplé avec SvelteKit est le framework de développement web que j'apprécie le plus depuis 2023.
Je l'utilise par défaut dans tous mes side project.
Ressources :
Liste des principaux hackers de la core team de Svelte et SvelteKit :
- Rich Harris
- Ben McCann (créateur de SvelteKit)
- Simon H
- Elliott Johnson
- Dani Sandoval
Journaux liées à cette note :
Je fais mon retour dans l'écosystème React, j'ai découvert Jotai et Zustand
Dans le code source de mon projet professionnel, #JaiDécouvert la librairie ReactJS nommée Jotai (https://jotai.org).
Les atom
de Jotai ressemblent aux fonctionnalités Svelte Store. Jotai permet entre autres d'éviter de faire du props drilling.
Pour en savoir plus sur l'intérêt de Jotai versus "React context (useContext + useState)", je vous conseille la lecture d'introduction de la page Comparison de la documentation Jotai. J'ai trouvé la section "Usage difference" très simple à comprendre.
Cette découverte est une bonne surprise pour moi, car les atom
de Jotai reproduisent l'élégance syntaxique des Store de Svelte, ce qui améliore mon confort de développement en ReactJS. #JaiLu ce thread Hacker News en lien avec le sujet : "I like Svelte more than React (it's store management)".
Je tiens toutefois à préciser que si Jotai améliore significativement mon expérience de développeur (DX) avec ReactJS, cela reste une solution de gestion d'état au sein du runtime ReactJS. En comparaison, le compilateur Svelte génère du code optimisé natif qui reste intrinsèquement plus performant à l'exécution.
Exemple Svelte :
import { writable, derived } from 'svelte/store';
const count = writable(0);
const doubled = derived(count, $count => $count * 2);
// Usage dans component
$count // auto-subscription
Exemple ReactJS basé sur Jotai :
import { atom } from 'jotai';
const countAtom = atom(0);
const doubledAtom = atom(get => get(countAtom) * 2);
// Usage dans component
const [count] = useAtom(countAtom);
J'ai lu la page "Comparison" de Jotai pour mieux comprendre la place qu'a Jotai dans l'écosystème ReactJS.
#JaiDécouvert deux autres librairies développées par la même personne, Daishi Kato : Zustand et Valtio. D'après ce que j'ai compris, Daishi a développé ces librairies dans cet ordre :
- Zustand en juin 2019 - voir "How Zustand Was Born"
- La première version de Jotai en septembre 2020 - voir "How Jotai Was Born"
- La première version de Valtio en mars 2021 - voir "How Valtio Was Born"
J'ai aussi découvert Recoil développé par Facebook, mais d'après son entête GitHub celle-ci semble abandonnée. Une migration de Recoil vers Jotai semble être conseillée.
J'aime beaucoup comment Daishi Kato choisit le nom de ses librairies, la méthode est plutôt simple 🙂 :
Comme mentionné plus haut, Jotai ressemble à Recoil alors que Zustand ressemble à Redux :
Analogy
Jotai is like Recoil. Zustand is like Redux.
...
How to structure state
Jotai state consists of atoms (i.e. bottom-up). Zustand state is one object (i.e. top-down).
Même en lisant la documentation Comparison, j'ai eu de grandes difficulté à comprendre quand préférer Zustand à Jotai.
En lisant la documentation, Jotai me semble toujours plus simple à utiliser que Zustand.
Avec l'aide de Claude Sonnet 4.5, je pense avoir compris quand préférer Zustand à Jotai.
Exemple Zustand
Dans l'exemple Zustand suivant, la fonction addToCart
modifie plusieurs parties du state useCartStore
en une seule transaction :
import { create } from 'zustand'
const useCartStore = create((set) => ({
user: null,
cart: [],
notifications: [],
addToCart: (product) => set((state) => {
return {
cart: [...state.cart, product],
notifications: (
state.user
? [...state.notifications, { type: 'cart_updated' }]
: state.notifications
)
};
};
}));
Et voici un exemple d'utilisation de addToCart
dans un composant :
function ProductCard({ product }) {
// Sélectionner uniquement l'action addToCart
const addToCart = useCartStore((state) => state.addToCart);
return (
<div>
<h3>{product.name}</h3>
<p>{product.price}€</p>
<button onClick={() => addToCart(product)}>
Ajouter au panier
</button>
</div>
);
}
Exemple Jotai
Voici une implémentation équivalente basée sur Jotai :
import { atom } from 'jotai';
const userAtom = atom(null);
const cartAtom = atom([]);
const notificationsAtom = atom([]);
export const addToCartAtom = atom(
null,
(get, set, product) => {
const user = get(userAtom);
const cart = get(cartAtom);
const notifications = get(notificationsAtom);
set(cartAtom, [...cart, product]);
if (user) {
set(notificationsAtom, [...notifications, { type: 'cart_updated' }]);
}
}
);
Et voici un exemple d'utilisation de useToCartAtom
dans un composant :
import { useSetAtom } from 'jotai';
import { addToCartAtom } from 'addToCartAtom';
function ProductCard({ product }) {
// Récupérer uniquement l'action (pas la valeur)
const addToCart = useSetAtom(addToCartAtom);
return (
<div>
<h3>{product.name}</h3>
<p>{product.price}€</p>
<button onClick={() => addToCart(product)}>
Ajouter au panier
</button>
</div>
);
}
Ces deux exemples montrent que Zustand est plus élégant et probablement plus performant que Jotai pour gérer des actions qui conditionnent ou modifient plusieurs parties du state simultanément.
#JaiLu le thread SubReddit ReactJS "What do you use for global state management? " et j'ai remarqué que Zustand semble plutôt populaire.
En rédigeant cette note, j'ai découvert Valtio qui semble être une alternative à MobX. Je prévois d'étudier ces deux librairies dans une future note.
Journal du samedi 11 octobre 2025 à 10:27
À la position 24min20 de la vidéo This Week in Svelte, Ep. 119 , #JaiDécouvert la nouvelle section "Packages" du site officiel de Svelte. Cette initiative me semble utile : elle offre une liste de packages considérés comme "standard" par la communauté Svelte.
J'ai consulté la Merge Request qui ajoute la section "Packages" en pensant y trouver des explications sur le process et les critères d'inclusion d'un package dans cette liste, mais je n'ai rien trouvé 🤷♂️.
Idée d'application de réécriture de texte assistée par IA
En travaillant sur mon prompt de reformulation de paragraphes pour mon notes.sklein.xyz, j'ai réalisé que l'expérience utilisateur des chat IA ne semble pas optimale pour ce type d'activité.
Voici quelques idées #idée pour une application dédiée à cet usage :
- Utilisation de deux niveaux de prompt :
- Un niveau général sur le style personnel
- Un niveau spécifique à l'objectif particulier
- Interface à deux zones texte :
- Une zone repliée par défaut contenant le ou les prompts
- Une seconde zone pour le texte à modifier
- Sélection de mots alternatifs comme dans DeepL : une fois qu'un mot de remplacement est choisi, le reste de la phrase s'adapte automatiquement en conservant au maximum la structure originale.
- Sélection flexible : permettre de sélectionner non seulement un mot isolé, mais aussi plusieurs mots consécutifs ou des paragraphes entiers.
- Support parfait du markdown.
À ce jour, je n'ai pas croisé d'application de ce type, #JaimeraisUnJour investir plus de temps pour approfondir cette recherche.
Quelques idées pour implémenter cette application :
- Connecté à OpenRouter
- Utilisation de Svelte, SvelteKit, ProseMirror, PostgreSQL, bits-ui
- Utilisation de la fonctionnalité Structured Outputs with LLM (https://platform.openai.com/docs/guides/structured-outputs)
Journal du jeudi 29 mai 2025 à 00:04
Dans ma note Bilan de poc-sveltekit-custom-server je finis par ceci :
La suite...
Je souhaite rédiger cette note en anglais et la publier sur https://github.com/sveltejs/kit/discussions et https://old.reddit.com/r/sveltejs/ afin :
- d'avoir des retours d'expérience
- de découvrir des méthodes alternatives
- et partager la méthode que j'ai utilisée, qui sera peut-être utile à d'autres développeurs Svelte 🙂
Voici ce que je viens de publier :
- https://github.com/sveltejs/kit/discussions/13841
- https://old.reddit.com/r/sveltejs/comments/1kxtz1u/custom_sveltekit_server_dev_production_with/
2025-05-29 : voir J'ai découvert la fonctionnalité SvelteKit Shared hooks init
Bilan de poc-sveltekit-custom-server
Contexte et objectifs
Dans le projet gibbon-replay, j'ai besoin d'exécuter une tâche une fois par jour pour supprimer des anciennes sessions.
gibbon-replay utilise une base de données SQLite qui ne dispose pas nativement de fonctionnalité de type Time To Live, comme on peut trouver dans Clickhouse.
SQLite ne propose pas non plus d'équivalent à pg_cron — ce qui est tout à fait normal étant donnée que SQLite est une librairie et non pas un service à part entière.
Le projet gibbon-replay est un monolith (j'aime les monoliths !) et je souhaite conserver ce choix.
Face à ces contraintes, une solution consiste à intégrer une solution comme Cron for Node.js directement dans l'application gibbon-replay.
Je pense que je dois implémenter cela dans un SvelteKit Custom Server, ce qui me permettrait d'exécuter cette tâche de purge à intervalles réguliers tout en conservant l'architecture monolithique.
Il y a quelques jours, j'ai décidé de tester cette idée dans un POC nommé : poc-sveltekit-custom-server
.
J'ai aussi décidé d'expérimenter un objectif supplémentaire dans ce POC : lancer la migration du modèle de données dès le lancement du monolith et non plus lors de la première requête HTTP reçue par le service.
Enfin, je souhaitais ne pas dégrader l'expérience développeur (DX), c'est à dire, je souhaitais pouvoir continuer à simplement utiliser :
$ pnpm run dev
ou
$ pnpm run build
$ pnpm run preview
sans différence avec un projet SvelteKit "vanilla".
Résultats du POC et enseignements
Tout d'abord, le POC fonctionne parfaitement 🙂, sans dégrader l'expérience développeur (DX), qui ressemble à ceci :
$ mise install
$ pnpm install
$ pnpm run load-seed-data
Start data model migration…
Data model migration completed
Start load seed data...
seed data loaded
Lancement du projet en mode développement :
$ pnpm run dev
Start data model migration…
Data model migration completed
Server started on http://localhost:5173 in development mode
Lancement du projet "buildé" :
$ pnpm run build
$ pnpm run preview
Start data model migration…
Data model migration completed
Server started on http://localhost:3000 in production mode
Les migrations et les données "seed.sql" se trouvent dans le dossier /sqls/
.
Le SvelteKit Custom Server est implémenté dans le fichier src/server.js
et il ressemble à ceci :
import express from 'express';
import cron from 'node-cron';
import db, { migrate } from '@lib/server/db.js';
const isDev = process.env.ENV !== 'production';
migrate(); // Lancement de la migration du modèle de donnée dès de lancement du serveur
// Configuration d'une tâche exécuté toutes les heures
cron.schedule(
'0 * * * *',
async () => {
console.log('Start task...');
console.log(db().query('SELECT * FROM posts'));
console.log('Task executed');
}
);
async function createServer() {
const app = express();
...
Personnellement, je trouve cela simple et minimaliste.
Point de difficulté
SvelteKit utilise des "module alias", comme par exemple $lib
.
Problème, par défaut, ces "module alias" ne sont pas configurés lors de l'exécution de node src/server.js
.
Pour me permettre d'importer dans src/server.js
des modules de src/lib/server/*
comme :
import db, { migrate } from '@lib/server/db.js';
j'ai utilisé la librairie esm-module-alias
.
Ceci complexifie un peu le projet, j'ai dû configurer ceci dans /package.json
:
{
"scripts": {
"dev": "ENV=development node --loader esm-module-alias/loader --no-warnings src/server.js",
"preview": "ENV=production node --loader esm-module-alias/loader --no-warnings build/server.js",
...
"aliases": {
"@lib": "src/lib/"
}
}
- ajout de
--loader esm-module-alias/loader --no-warnings
- et la section
aliases
Et dans /vite.config.js
:
export default defineConfig({
plugins: [sveltekit()],
resolve: {
alias: {
'@lib': path.resolve('./src/lib')
}
}
});
- ajout de
alias
Le fichier src/server.js
contient du code spécifique en fonction de son contexte d'exécution ("dev" ou "buildé") :
if (isDev) {
const { createServer: createViteServer } = await import('vite');
const vite = await createViteServer({
server: { middlewareMode: true },
appType: 'custom'
});
app.use(vite.middlewares);
} else {
const { handler } = await import('./handler.js');
app.use(handler);
}
En mode "dev" il utilise Vite et en "buildé" il utilise le fichier build/handler.js
généré par SvelteKit build en mode SSR.
Le fichier src/server.js
est copié vers le dossier /build/
lors de l'exécution de pnpm run build
.
J'ai testé le bon fonctionnement du POC dans un container Docker.
J'ai intégré au projet un deployment-playground : https://github.com/stephane-klein/poc-sveltekit-custom-server/tree/main/deployment-playground.
La suite...
Je souhaite rédiger cette note en anglais et la publier sur https://github.com/sveltejs/kit/discussions et https://old.reddit.com/r/sveltejs/ afin :
- d'avoir des retours d'expérience
- de découvrir des méthodes alternatives
- et partager la méthode que j'ai utilisée, qui sera peut-être utile à d'autres développeurs Svelte 🙂
Update du 2025-05-29 à 00:07 - Je viens de publier ceci :
- https://github.com/sveltejs/kit/discussions/13841
- https://old.reddit.com/r/sveltejs/comments/1kxtz1u/custom_sveltekit_server_dev_production_with/?
2025-05-29 : voir J'ai découvert la fonctionnalité SvelteKit Shared hooks init
Journal du lundi 10 mars 2025 à 18:02
Après ruff il y a 1 mois, on m'a encore partagé un nouveau formatter, bien entendu en Rust : Biome (https://github.com/biomejs/biome).
Biome is a performant toolchain for web projects, it aims to provide developer tools to maintain the health of said projects.
Biome is a fast formatter for JavaScript, TypeScript, JSX, JSON, CSS and GraphQL that scores 97% compatibility with Prettier.
Biome is a performant linter for JavaScript, TypeScript, JSX, CSS and GraphQL that features more than 270 rules from ESLint, typescript-eslint, and other sources. It outputs detailed and contextualized diagnostics that help you to improve your code and become a better programmer!
Le projet Biome a commencé en été 2023, mais en réalité, le projet est plus ancien. Biome est un fork du projet Rome de Meta, qui a commencé en 2020.
Ce billet explique la raison du fork, pour faire simple, un problème de propriété du nom.
Thread Hacker News de l'annonce du fork : Biome.
J'ai lu le billet Biome v1.7 qui explique comment migrer d'eslint ou Prettier en une commande :
biome migrate eslint
- ou
biome migrate prettier
Je pense que je vais attendre encore un peu avant de migrer parce que le support Svelte est partiel :
#JeMeDemande quelles sont les différences entre le linter de Oxc https://oxc.rs/docs/guide/usage/linter et Biome 🤔.
Je viens de vérifier, le projet Oxc est toujours très actif : https://github.com/oxc-project/oxc/graphs/contributors.
Journal du mercredi 11 décembre 2024 à 11:03
Je viens de croiser pour la première fois la propriété windom.customElements
(from).
Elle fait partie de l'ensemble des technologies qui composent ce que l'on appelle les Web Components.
Je connais depuis longtemps les Web Components, mais je n'ai jamais essayé de mettre en œuvre cette technologie. Je me suis contenté de lire et d'écouter des retours d'expérience et de suivre l'évolution des spécifications.
#JaiDécouvert que je peux facilement créer des Web Components en Svelte : https://svelte.dev/docs/svelte/custom-elements.
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as most frameworks.
#JaiDécouvert le site Custom Elements Everywhere (https://custom-elements-everywhere.com/). Je lis que les Web Components sont maintenant parfaitement supportés par les frameworks majeurs : ReactJS, VueJS, Angular, Svelte, Solid… Ce qui est une très bonne nouvelle 🙂.
Je vais essayer de garder cette information à l'esprit, les Web Components me seront sans doute utile à l'avenir.
Avec Svelte, j'apprécie une sorte de "retour aux sources", c'est-à-dire, vers un web un peu plus "vannila", celui que j'ai connu au début des années 2000.
Je pense que Web Components vont encore renforcer cette sensation, comme par exemple le fait que si j'utilise la fonctionnalité développeur "inspection" du navigateur sur un Web Component, je vais voir, par exemple, la balise <button>....</button>
du Web Component et non sa "soupe" HTML, comme c'est le cas avec un composant ReactJS ou Svelte (je sais qu'il existe des extensions navigateur pour éviter cela).
#JaimeraisUnJour prendre le temps d'étudier les performances des Web Components versus les composants de ReactJS, Svelte et Solid.
#JaiLu le thread du Subreddit ReactJS : Is it worth learning Web Components?. Voici quelques extraits :
Not worth it to be quite honest. I expect to get some hate for this.
I worked on a design system for three years that was written in Stencil (web component framework) that was used by multiple teams all using React, Angular, Vue. I regret everything, it should have all been react but the dumb decision to allow different teams to use different frameworks in order to do "micro frontend architecture" was the reason web components were picked shortly before I joined and took the lead.
Web components are also impossible to version and whichever one loads first is going to be the one that is globally used. This means production breaking changes without teams even knowing their breaking changes were going to fuck over another team.
Un peu plus loin du même auteur :
No, I view “micro frontend architecture” as a total disaster and it usually is implemented badly. When each application is a different framework too it’s quite honestly so difficult as to not even be worth entertaining.
Web components can be a great way to add functionality to legacy web apps. I don't know if I'd set out to use them in any other scenario though. I suppose you could, but I don't know many people writing vanilla HTML/JS apps these days.
J'ai effectué une recherche GitHub sur le topic "web-components" et j'ai trouvé des choses intéressantes :
- wired-elements - j'adore ! ( Voir note la 2024-12-11_1708)
- Open UI (https://open-ui.org) - cela semble être intéressant
- https://github.com/github/github-elements
- https://github.com/nolanlawson/emoji-picker-element
- https://atomicojs.dev
Journal du lundi 18 novembre 2024 à 22:51
#JaiDécouvert Introducing the new Svelte CLI.
We’ve just released sv, a new Command Line Interface (CLI) for creating, enhancing, and upgrading Svelte projects.
...
This package merges the previous create-svelte and community-led svelte-add tools into a single package.
Journal du dimanche 20 octobre 2024 à 10:04
La version 5 de Svelte vient de sortir : 5.0.0.
Il y a un an, j'avais lu le billet Introducing runes. Depuis, j'ai suivi ce sujet de loin.
J'aimerais tester et apprendre à utiliser la fonctionnalité rune.
#JeMeDemande dans quel projet 🤔. Est-ce que je préfère refactorer vers rune le projet sklein-pkm-engine ou gibbon-replay 🤔. Je pense que ces deux projets utilisent trop peu de "reactive state".
Je souhaite prochainement débuter le projet que j'ai présenté dans 2023-10-28_2008. Je pense que ça serait une bonne occasion pour créer mon premier projet 100% TypeScript avec Svelte 5 avec Rune.
Journal du mardi 15 octobre 2024 à 16:02
En étudiant l'annonce de Brief.me j'ai un peu étudié Capacitor :
Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️ .
Le projet Capacitor a commencé fin 2017 et d'après ce que j'ai lu, ce projet est la "suite" d' Apache Cordova anciennement nommé PhoneGap.
Je me souviens d'avoir utilisé PhoneGap vers 2010.
Je découvre que je peux utiliser Svelte avec Capacitor : Svelte & Capacitor - Build native mobile apps with web technology and Svelte.
Il est même possible d'utiliser SvelteKit en mode SSG (@sveltejs/adapter-static
) : https://ionic.io/blog/cross-platform-sveltekit-capacitor-application-yes-its-possible.
J'ai parcouru ce retour d'expérience : How I published a gratitude journaling app for iOS and Android using SvelteKit and Capacitor.
#JaiDécouvert ce template svelte-capacitor.
#JaiDécouvert whatpwacando.today.
#JaiLu SvelteKit + Capacitor Performance Example
J'ai souvent entendu parler d'Ionic par le passé, mais je n'avais jamais pris le temps de m'y pencher sérieusement. Je pensais que Ionic était un équivalent de React Native, mais j'avais tort. En réalité, Ionic est un UI Toolkit.