Tous les articles

2026-08-16

· Dylan Yu
Cloudflare D1SQLiteedgelocal-first

Gérer Cloudflare D1 depuis ton bureau (sans le dashboard)

Cloudflare D1, c'est du SQLite à l'edge, mais le dashboard web est lent au quotidien. Voici comment gérer tes bases de données D1 localement — requêtes, navigation et édition depuis une application de bureau, sans aucun aller-retour cloud.

J'utilise Cloudflare D1 pour quelques side-projects et une app en production depuis presque un an maintenant. Et à chaque fois que j'ai besoin de vraiment regarder mes données — pas juste lancer une requête ponctuelle et plisser les yeux sur le JSON — je finis frustré. Le dashboard web, ça va quand tu crées une base pour la première fois. C'est nettement moins bien quand tu débogues une migration de schéma à 23h et que tu veux juste parcourir 200 lignes sans attendre deux secondes à chaque page.

Le problème, c'est que D1, c'est du SQLite. Littéralement du SQLite. Tout le pitch, c'est que tes données vivent dans un fichier SQLite répliqué sur les edge locations de Cloudflare. Alors pourquoi je le traite comme une base de données cloud exotique qui nécessite un navigateur et une prière ?

Ce post, c'est le guide que j'aurais aimé avoir il y a six mois. Je vais t'expliquer ce qu'est vraiment D1, pourquoi le dashboard est à chier pour le travail quotidien, et les trois vraies méthodes pour gérer une base D1 localement — dont celle que j'utilise au quotidien.

Ce qu'est vraiment Cloudflare D1

Mettons l'architecture au clair, parce que ça a un impact sur la façon dont tu travailles avec D1.

D1, c'est la base de données SQLite serverless de Cloudflare. La couche de stockage, c'est du SQLite — le format de fichier, le moteur de requêtes, le stockage en B-tree, tout ça. Quand tu crées une base D1, Cloudflare provisionne un fichier SQLite et le réplique sur son réseau edge. Quand un Worker exécute une requête, elle tourne contre la réplica la plus proche de ce fichier SQLite.

La couche de calcul, ce sont les Workers. Tu ne te connectes pas à D1 comme tu te connecterais à Postgres avec une chaîne de connexion TCP. À la place, tu bindes la base D1 à ton Worker, et à l'intérieur du Worker tu appelles des méthodes comme env.DB.prepare("SELECT * FROM users").all(). Le Worker tourne à l'edge, près de l'utilisateur, et la réplica D1 est juste à côté.

Pour les requêtes ad-hoc en dehors des Workers, Cloudflare te donne deux options :

  1. Wrangler CLIwrangler d1 execute et wrangler d1 query lancent des requêtes depuis ton terminal via l'API D1.
  2. D1 REST API — un endpoint HTTP qui accepte du SQL et renvoie du JSON. Tu peux l'appeler depuis tout ce qui parle HTTP.

Les deux passent par l'API de Cloudflare, pas directement vers le fichier SQLite. Il n'y a aucun moyen d'obtenir une connexion SQLite brute à une base D1 en production — c'est le compromis du serverless. Mais la sémantique des requêtes, c'est de la sémantique SQLite. Si tu connais SQLite, tu connais D1.

C'est l'idée clé qui devrait guider tes choix d'outils : D1, c'est du SQLite accédé via HTTP. Ça veut dire que tout outil capable de parler à la REST API de D1 peut te donner une expérience proche de SQLite, et tout ce que tu sais de SQLite s'applique directement.

Le problème du dashboard web

Cloudflare a un dashboard web pour D1 dans le panneau d'administration Cloudflare. Tu te connectes, tu vas sur ta base, et tu as une zone de requête et une table de résultats. Ça marche. Je ne vais pas faire semblant que ça n'existe pas. Mais pour le travail quotidien sur une base — le genre de truc que tu fais quand tu construis ou maintiens une app — il y a de vrais problèmes.

Chaque requête, c'est un aller-retour réseau. Tu tapes une requête, tu lances, et tu attends que la requête atteigne l'API de Cloudflare, s'exécute, et revienne. Sur une bonne connexion, c'est 300-500ms. Sur le wifi d'un hôtel, c'est plus long. Quand tu explores tes données — tu lances une requête, tu regardes le résultat, tu ajustes, tu relances — la latence s'accumule vite. J'ai passé plus de temps à attendre que les requêtes du dashboard reviennent qu'à réfléchir sur mes données.

Pas de vraie expérience de navigation. La table de résultats, c'est une table HTML basique. Tu ne peux pas réordonner les colonnes à la souris. Tu ne peux pas redimensionner les colonnes. Tu ne peux pas figer la première colonne pendant que tu défiles horizontalement. Tu ne peux pas cliquer sur une ligne et la voir développée dans une vue détaillée. Tu ne peux pas trier en cliquant sur un en-tête de colonne sans écrire une nouvelle clause ORDER BY. Ça a l'air de détails, mais c'est la différence entre « j'explore mes données » et « je me bats avec mes outils ».

Aucune vue au-delà d'une table plate. Si ta base D1 a une table de tickets de support, tu voudrais peut-être les voir en kanban groupé par statut. Si elle a des données produit, tu voudrais une galerie avec des images. Si elle a des événements, tu voudrais un dashboard avec des graphiques. Le dashboard ne t'offre rien de tout ça. C'est une table, ou c'est rien.

Pas d'intégration AI. J'utilise des assistants AI — Claude, Cursor, Windsurf — pour m'aider à écrire et déboguer du SQL. Avec le dashboard web, il n'y a aucun moyen pour un outil AI de voir mon schéma ou d'interroger mes données. Je dois copier manuellement les définitions du schéma dans le chat, lancer les requêtes moi-même, copier les résultats en retour. C'est fastidieux.

Pas de hors ligne. Le dashboard, c'est une web app. Pas d'internet, pas de dashboard. J'ai pris assez de vols et de trains pour savoir que ça compte.

Changement de contexte. Le dashboard vit dans un onglet de navigateur parmi 47 autres. Quand je travaille sur mon app dans mon éditeur, je dois basculer vers le navigateur, trouver le bon onglet, revenir à ma base. C'est de la friction.

Le dashboard, c'est bien pour créer une base, configurer des bindings, et lancer une requête une fois par mois. Ce n'est pas un outil du quotidien. Et puisque D1, c'est du SQLite, tu ne devrais pas te contenter d'une interface web pire que tous les navigateurs SQLite de bureau sortis ces 15 dernières années.

Option 1 : Wrangler CLI

La méthode officielle pour interagir avec D1 en dehors des Workers, c'est Wrangler, l'outil CLI de Cloudflare. Si tu as déjà déployé des Workers, tu l'as déjà. Sinon, installe-le avec npm :

npm install -g wrangler

Authentifie-toi avec ton compte Cloudflare :

wrangler login

Ensuite tu peux lister tes bases D1 :

wrangler d1 list

Lancer une requête :

wrangler d1 execute my-database --command "SELECT * FROM users LIMIT 10"

Ou lancer un fichier SQL :

wrangler d1 execute my-database --file ./migration.sql

Il y a aussi un mode de requête interactif :

wrangler d1 query my-database

Ça te droppe dans un REPL où tu tapes des requêtes et tu vois les résultats.

Wrangler est bon pour ce à quoi il est bon : des scripts, des migrations, des pipelines CI/CD, des requêtes ponctuelles rapides. Je l'utilise pour lancer des migrations dans des scripts de déploiement. C'est fiable, scriptable, et il ne te gêne pas.

Là où Wrangler montre ses limites, c'est la navigation. Le résultat, c'est du texte formaté dans ton terminal. Ça passe pour SELECT COUNT(*) FROM users. C'est atroce pour SELECT * FROM users quand la table a 12 colonnes et que tu veux vraiment lire les valeurs. Pas moyen de parcourir les lignes visuellement, pas moyen de cliquer sur une ligne, pas moyen d'éditer une valeur en place. Tu es dans un terminal. Les terminaux, ce n'est pas terrible pour les données tabulaires.

Si ton workflow c'est « lancer une requête, regarder un chiffre, passer à autre chose », Wrangler est parfait. Si ton workflow c'est « explorer une table, comprendre la forme des données, trouver la ligne bizarre qui casse mon app », Wrangler va te rendre malheureux.

Option 2 : D1 REST API

C'est là que ça devient intéressant. D1 expose une REST API, ce qui veut dire que tu peux l'interroger depuis tout ce qui peut faire une requête HTTP. C'est bien plus important que ça n'en a l'air.

Le format de l'endpoint :

https://api.cloudflare.com/client/v4/accounts/{account_id}/d1/database/{database_id}/query

Tu t'authentifies avec un token API Cloudflare (crées-en un dans le dashboard sous My Profile > API Tokens, avec les permissions D1).

Un exemple avec curl :

curl -X POST \
  "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/d1/database/$DATABASE_ID/query" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT * FROM users LIMIT 10"}'

La réponse est en JSON :

{
  "result": [
    {
      "results": [
        { "id": 1, "email": "alice@example.com", "name": "Alice" },
        { "id": 2, "email": "bob@example.com", "name": "Bob" }
      ],
      "success": true,
      "meta": {
        "served_by": "d1-micro",
        "duration": 0.34,
        "changes": 0,
        "last_row_id": 0,
        "rows_read": 2,
        "rows_written": 0
      }
    }
  ],
  "success": true,
  "errors": [],
  "messages": []
}

C'est ça qui débloque tout. Parce que D1 a une REST API, n'importe quel client HTTP peut l'interroger. Une app de bureau peut l'interroger. Un script peut l'interroger. Un outil AI peut l'interroger. Tu n'es pas limité à Wrangler ou au dashboard web — tu peux construire ou utiliser n'importe quelle interface qui parle HTTP.

La REST API supporte tout ce que Wrangler supporte : SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, l'introspection de schéma via sqlite_master, tout. C'est du SQLite sur HTTP.

L'API brute n'est pas une super interface au quotidien — tu ne veux pas écrire des commandes curl pour parcourir une table. Mais c'est la fondation sur laquelle de meilleurs outils peuvent se construire. Et c'est exactement ce que je veux te montrer ensuite.

Option 3 : Un panneau d'administration de bureau local

C'est l'option que j'utilise vraiment au quotidien. Au lieu d'interroger D1 via un dashboard web, je connecte une application de bureau locale à la REST API de D1 et j'obtiens un vrai panneau d'administration — le genre de truc que SQLite a depuis des années avec des outils comme DB Browser, mais qui tourne contre ma base D1 via l'API.

L'outil que j'utilise, c'est BaseVolt. C'est une application de bureau local-first pour macOS et Windows qui donne à n'importe quelle base de données un panneau d'administration complet. Elle supporte SQLite, PostgreSQL, MySQL et Cloudflare D1. Je vais te détailler le workflow D1 parce que c'est le sujet de ce post, mais la même app gère les autres aussi.

Il y a d'autres options dans ce domaine — TablePlus supporte D1 si tu le configures bien, et tu peux toujours faire le tien avec la REST API et un client HTTP. J'utilise BaseVolt parce que c'est le seul qui me donne des vues (kanban, galerie, dashboards) et qui a le serveur MCP pour l'intégration AI, dont je parlerai plus loin. Mais l'approche générale — connecter une app de bureau à la REST API de D1 — c'est ça qui compte. Choisis l'outil qui colle à ton workflow.

Étape 1 : Récupère tes identifiants API D1

Tu as besoin de trois choses depuis Cloudflare :

  1. Account ID — tu le trouves dans le dashboard Cloudflare. Il est dans l'URL quand tu es connecté, ou sur la page d'aperçu du compte. C'est une chaîne hexadécimale.
  2. Database ID — l'ID de la base D1 spécifique à laquelle tu veux te connecter. Lance wrangler d1 list pour voir tes bases et leurs IDs, ou trouve-le dans le dashboard sous les paramètres de ta base D1.
  3. API Token — crées un token sur My Profile > API Tokens. Pour l'accès D1, le token a besoin au minimum de la permission « D1 Edit » (ou « D1 Read » si tu veux juste un accès en lecture). Limite-le à ton compte.

Garde-les sous la main. Tu en auras besoin dans une seconde.

Étape 2 : Connecte BaseVolt

Ouvre BaseVolt et ajoute une nouvelle source de données. Choisis « Cloudflare D1 » comme type. BaseVolt te demande les trois identifiants ci-dessus — account ID, database ID, API token. Saisis-les, clique sur connecter.

BaseVolt construit l'endpoint REST de D1 à partir de ton account ID et ton database ID :

https://api.cloudflare.com/client/v4/accounts/{account_id}/d1/database/{database_id}/query

Et envoie ton API token comme header d'authentification bearer. C'est tout. Il n'y a pas de serveur intermédiaire — BaseVolt parle directement à l'API de Cloudflare depuis ta machine. Ton API token est stocké localement, pas envoyé à un service tiers.

Une fois connecté, BaseVolt introspecte ton schéma en interrogeant sqlite_master et récupère ta liste de tables. Tu vois tes tables dans la sidebar en quelques secondes.

Étape 3 : Parcours les tables, lance des requêtes, construis des vues

C'est là que l'app de bureau justifie son existence. Une fois connecté, tu as :

Un vrai navigateur de tables. Clique sur une table, vois ses lignes dans une grille. Les colonnes sont redimensionnables et réordonnables. Clique sur un en-tête de colonne pour trier. Parcours les résultats sans relancer la requête. Clique sur une ligne pour voir tous ses champs dans un panneau de détail. Édite une valeur en place en double-cliquant sur une cellule. C'est du tooling de base de données, mais c'est le jour et la nuit comparé au dashboard web.

Un éditeur SQL. Un vrai éditeur avec coloration syntaxique, autocomplétion des noms de tables et de colonnes, et historique des requêtes. Lance une requête, vois les résultats en dessous. Relance la même requête avec une modif, vois les nouveaux résultats. La latence, c'est l'aller-retour de l'API D1 — comme le dashboard — mais l'interface ne te gêne pas, donc la latence est la seule chose que tu attends, pas l'UI.

Des vues. C'est ce qui m'a convaincu. BaseVolt te laisse construire différentes vues par-dessus n'importe quelle table :

  • Vue grille — la vue par défaut, une table façon tableur.
  • Vue galerie — affiche chaque ligne comme une carte, pratique pour les données avec des images ou des fichiers.
  • Vue kanban — groupe les lignes par un champ de statut, pratique pour les tickets, les tâches, tout ce qui a un workflow.
  • Vue dashboard — graphiques et métriques construits depuis tes données, pratique pour le monitoring.

Pour ma table de tickets de support dans D1, j'ai une vue kanban groupée par statut. Pour ma table d'événements, j'ai un dashboard avec un compte des événements du jour et un graphique en barres des événements par type. Ce sont des vues que je n'aurais jamais eues avec le dashboard web. Elles ne sont tout simplement pas possibles là-bas.

Tout ça tourne localement. Les requêtes vont vers D1 via la REST API, mais l'interface — la grille, le kanban, les graphiques — est entièrement rendue sur ta machine. Pas de SaaS cloud qui rend ton UI.

Étape 4 : Utilise le serveur MCP pour le travail de schéma assisté par AI

C'est la partie qui m'a surpris. BaseVolt intègre un serveur MCP (Model Context Protocol). MCP, c'est le standard qui permet aux assistants AI comme Claude, Cursor et Windsurf de se connecter à des outils externes. Avec le serveur MCP de BaseVolt en marche, ton assistant AI peut voir ton schéma de base de données et lancer des requêtes contre lui.

Voilà ce que ça donne en pratique. Je suis dans Cursor, je travaille sur mon app. Je veux ajouter une nouvelle colonne à ma table users. Je dis à Cursor : « Ajoute une colonne last_login_at à la table users et mets à jour les requêtes pertinentes dans mon code Worker. » Cursor, connecté au serveur MCP de BaseVolt, peut :

  1. Lire mon schéma actuel (il voit la table users et toutes ses colonnes).
  2. Générer la migration ALTER TABLE.
  3. La lancer contre D1 via le serveur MCP.
  4. Mettre à jour mon code Worker pour référencer la nouvelle colonne.

Je n'ai pas à copier mon schéma dans le chat. Je n'ai pas à lancer la migration manuellement et faire un retour. L'assistant AI fait toute la boucle parce qu'il a une connexion live à ma base via BaseVolt.

Ça marche aussi pour le débogage. « Pourquoi le compte de cet utilisateur apparaît comme inactif ? » L'AI peut interroger la table users, regarder la ligne concernée, vérifier les tables liées, et comprendre — tout via la connexion MCP. C'est le genre de truc qui me prendrait dix minutes de requêtes manuelles, fait en une conversation.

Le serveur MCP tourne localement dans BaseVolt. Ton assistant AI s'y connecte sur localhost. Aucune donnée ne passe par un service cloud pour activer l'intégration AI — l'outil AI parle à BaseVolt, BaseVolt parle à D1, et le seul cloud dans la boucle, c'est Cloudflare lui-même.

Pourquoi le local-first compte pour D1

Voilà une objection que j'ai déjà entendue : « Tes données D1 sont déjà dans le cloud de Cloudflare. Pourquoi est-ce important que ton outil de base de données soit aussi un SaaS cloud ? »

Ça compte à cause de ce qu'il y a entre les deux. Quand tu utilises un outil d'administration de base de données hébergé dans le cloud — un SaaS web qui se connecte à ta base D1 — tes données transitent par les serveurs de ce SaaS. Tes requêtes vont de ton navigateur vers leur serveur, puis vers Cloudflare, puis reviennent par leur serveur vers ton navigateur. Ce serveur intermédiaire voit ton SQL, tes résultats, ton schéma. C'est un man-in-the-middle par conception.

Quand tu utilises une application de bureau local-first, tes requêtes vont de ta machine directement à l'API de Cloudflare. Pas de serveur intermédiaire. Les seules parties qui voient tes données, c'est toi et Cloudflare, et Cloudflare a déjà tes données puisque c'est leur base de données.

Ce n'est pas qu'une question de confiance — c'est aussi une question de latence et de fiabilité. Une app locale n'a pas de serveur qui peut tomber. Elle n'a pas de backend qui peut être rate-limited ou DDoSé. Elle n'a pas de système de login qui peut te verrouiller dehors. Tu ouvres l'app, elle se connecte à D1, tu travailles. La seule dépendance, c'est que l'API de Cloudflare soit up, ce qui est déjà ta dépendance.

Local-first veut aussi dire capable de fonctionner hors ligne pour les parties qui n'ont pas besoin du réseau. BaseVolt met en cache ton schéma et tes résultats de requêtes récents localement. Si je perds internet, je peux toujours regarder mon schéma, revoir mes derniers résultats, et planifier ma prochaine migration. Je ne peux pas lancer de nouvelles requêtes, mais je peux réfléchir — et une grande partie du travail sur une base de données, c'est réfléchir, pas interroger.

Le principe est simple : tes données sont dans le cloud parce qu'elles doivent être accessibles globalement. Tes outils n'ont pas besoin d'être dans le cloud, et les y mettre ne t'apporte rien d'autre qu'un intermédiaire.

Tableau comparatif

Voilà comment les options se comparent. Ce sont mes évaluations honnêtes après avoir utilisé les quatre.

Wrangler CLID1 REST APIDashboard webBaseVolt
Temps de configuration5 min (npm install + login)10 min (créer un token API)0 min (déjà dans le dashboard)5 min (install + identifiants)
Expérience de navigationMédiocre (sortie texte terminal)Aucune (HTTP brut)Basique (table HTML, sans fioritures)Complète (grille, vue détaillée, édition en place)
Vitesse des requêtesRapide (appel API direct)Rapide (appel API direct)Lent (aller-retour + rendu UI)Rapide (appel API direct, UI locale)
Hors ligneNonNonNonPartiel (schéma + résultats en cache)
Intégration AIAucuneManuelle (copier-coller)AucuneServeur MCP intégré
Vues/dashboardsAucuneAucuneAucuneGrille, galerie, kanban, dashboard
CoûtGratuitGratuitGratuitTier gratuit (2 sources) ; Pro $99/an
Idéal pourScripts, migrations, CI/CDIntégrations customTâches d'admin ponctuellesTravail quotidien sur la base

Quelques notes sur ce tableau :

Wrangler et la REST API ont la même vitesse sous-jacente parce qu'ils touchent la même API Cloudflare. La différence, c'est l'interface — Wrangler te donne un terminal, la REST API ne te donne rien (tu construis ta propre interface).

Le dashboard web est « lent » non pas parce que l'API de Cloudflare est lente, mais parce que la web app ajoute une surcharge de rendu au-dessus de chaque appel API. Chaque page de résultats nécessite un aller-retour et un re-rendu complet de l'UI.

La vitesse des requêtes de BaseVolt est la même que celle de Wrangler — elle touche la même API. La différence, c'est que les résultats sont rendus dans une UI locale qui ne te fait pas attendre qu'une page web se charge autour d'eux.

La ligne coût : Wrangler, la REST API et le dashboard sont gratuits parce que ce sont les outils de Cloudflare. BaseVolt a un tier gratuit qui couvre jusqu'à 2 sources de données — donc si D1 est ta seule base, ou si tu as D1 plus un Postgres, tu restes sur le tier gratuit pour toujours. Pro est à $99/an et ajoute la synchronisation entre appareils, que j'utilise pour garder mon historique de requêtes et mes vues sauvegardées cohérents entre mon laptop et mon desktop.

Quand utiliser quoi

Tu n'es pas obligé d'en choisir un seul et de t'y tenir. J'utilise tous ceux-là selon ce que je fais. Voici mon guide de décision :

Utilise Wrangler CLI quand :

  • Tu lances une migration dans un script de déploiement.
  • Tu es dans un pipeline CI/CD et dois exécuter du SQL programmatiquement.
  • Tu dois lancer une requête ponctuelle rapide depuis le terminal et tu as déjà Wrangler installé.
  • Tu crées ou supprimes des bases de données.

Utilise la D1 REST API quand :

  • Tu construis une intégration custom (un script, un bot, un outil interne).
  • Tu veux interroger D1 depuis un langage ou un environnement qui n'a pas Wrangler.
  • Tu écris ton propre outil d'administration et tu as besoin de l'API brute.

Utilise le dashboard web quand :

  • Tu configures une nouvelle base D1 pour la première fois.
  • Tu configures des bindings Workers.
  • Tu vérifies la facturation ou les métriques d'usage.
  • Tu es sur une machine qui n'est pas la tienne et tu ne peux rien installer.

Utilise un panneau d'administration de bureau local (BaseVolt ou autre) quand :

  • Tu fais du travail quotidien sur ta base — parcourir des tables, explorer des données, déboguer des problèmes.
  • Tu veux des vues (kanban, galerie, dashboard) sur tes données D1.
  • Tu veux la gestion de schéma assistée par AI via un serveur MCP.
  • Tu travailles hors ligne ou sur une mauvaise connexion et veux une UI réactive.
  • Tu gères D1 à côté d'autres bases (Postgres, MySQL, SQLite local) et veux un seul outil pour tout.

Le pattern auquel je me suis habitué : Wrangler pour les migrations et les scripts, le dashboard web pour l'admin au niveau du compte, et BaseVolt pour tout le reste. Je passe probablement 80% de mon temps D1 dans BaseVolt, 15% dans Wrangler, et 5% dans le dashboard.

En résumé

Cloudflare D1, c'est du SQLite à l'edge. C'est une super architecture pour ton app. Mais les outils que Cloudflare te donne pour le gérer — un dashboard web et un CLI — sont conçus pour un usage occasionnel, pas quotidien. Si tu es dans ta base D1 tous les jours, tu mérites une vraie interface.

La bonne nouvelle, c'est que la REST API de D1 veut dire que tu n'es pas coincé avec les outils de Cloudflare. N'importe quel client HTTP peut interroger ta base. Et une application de bureau local-first comme BaseVolt peut transformer cette API en un panneau d'administration complet — vues grille, kanban, dashboards, édition en place, intégration AI — tout en tournant sur ta machine, avec les requêtes qui vont directement à Cloudflare.

Tu n'as pas à me croire sur parole. Le tier gratuit couvre deux sources de données, ce qui est largement suffisant pour l'essayer avec D1 et voir si ça colle à ton workflow.

Essayez-le sur basevolt.app — pas d'inscription, pas de carte bancaire.

Si tu construis des trucs sur l'edge et que tu veux parler d'outillage de bases de données, retrouvez-moi sur X.

BasevoltBasevolt

Essayez Basevolt — un panneau d'administration de base de données local et gratuit pour PostgreSQL, MySQL, SQLite et Cloudflare D1.

Télécharger Basevolt gratuitement