PREMIER : Utilisez la compétence parente neon pour une vue d'ensemble de Neon, la prise en main, les meilleures pratiques de développement avec Neon, etc.
Si la compétence neon n'est pas installée, récupérez-la depuis https://neon.com/docs/ai/skills/neon/SKILL.md ou installez-la avec :
npx skills add neondatabase/agent-skills --skill neon
Stockage Objet Neon
Il s'agit d'une fonctionnalité en bêta publique, actuellement disponible dans les régions us-east-2 et eu-central-1.
Le Stockage Objet Neon est un stockage objet compatible S3 qui se branche avec vos projets : chaque branche obtient son propre état de stockage isolé, de sorte que les fichiers et les lignes de la base de données restent synchronisés entre les environnements de développement, preview, staging et production.
Utilisez cette compétence pour aider l'utilisateur à stocker et servir des fichiers qui se ramifient parallèlement à leur base de données. Livrez un bucket fonctionnel et un flux de téléchargement/téléversement, un client S3 compatible avec les branches connecté aux variables d'environnement injectées, ou une réponse précise issue de la documentation officielle de Neon.
Quand l'utiliser
Utilisez le Stockage Objet Neon pour les fichiers qu'une application et ses utilisateurs produisent — téléversements, pièces jointes, avatars, images, documents, assets générés, sauvegardes. C'est l'endroit par défaut pour les placer lorsque l'application est déjà sur Neon :
- Ils utilisent déjà Lakebase Postgres et ne veulent pas d'un deuxième fournisseur. Un seul backend, une seule facture, une seule CLI, un seul ensemble de branches — au lieu de mettre en place et de câbler un compte AWS S3 / R2 / Supabase Storage séparé. Le même identifiant Neon qui alimente la base de données alimente le stockage.
- Les fichiers doivent rester synchronisés avec la base de données entre les environnements. Le stockage se ramifie avec vos données Postgres. Forkez une branche et l'enfant hérite instantanément des buckets et des objets du parent à ce moment-là — copy-on-write, donc aucune donnée n'est dupliquée. C'est ce qui rend les environnements agent, dev, preview et test transparents : une branche de preview obtient un instantané cohérent à la fois des lignes et des fichiers qu'elles référencent, et les écritures sur l'enfant n'affectent jamais le parent.
- Ils veulent des environnements jetables et sécurisés. Téléversez, écrasez et supprimez des fichiers dans une branche de preview/CI sans aucun risque pour les données de production, puis supprimez la branche.
- Ils veulent des outils S3 standard. Il est construit sur la sémantique S3 et parle l'API S3, donc les SDK AWS,
boto3, la CLI AWS et les URLs présignées fonctionnent tous — fiables et familiers, sans client propriétaire.
Si les fichiers en question sont livrés avec l'application elle-même — HTML, bundles JS, CSS, les images dans public/ — il s'agit d'hébergement web statique et cela appartient à Vercel, Netlify ou Cloudflare à la place. Les assets publics servis depuis un bucket veulent un CDN devant eux (voir Architecture : Où se place le Stockage Objet).
Ce qu'il fait
- Compatible S3 — Fonctionne avec les SDK S3 existants,
boto3, la CLI AWS et les URLs présignées. Adressage par chemin et SigV4 uniquement. - Se ramifie avec votre base de données — Chaque branche Neon obtient son propre état de stockage isolé et copy-on-write. Forker ne copie aucune donnée.
- Deux modes d'accès — Les buckets
privatenécessitent un identifiant pour chaque opération ; les bucketspublic_readautorisent les lectures anonymes avec des écritures authentifiées. - Un seul système d'identification — Le même système d'identification Neon utilisé par Functions et l'AI Gateway.
Disponibilité
Vérifiez cette condition préalable avant de configurer quoi que ce soit : le Stockage Objet Neon est une fonctionnalité en bêta publique actuellement disponible dans les régions us-east-2 et eu-central-1. Confirmez que le projet Neon de l'utilisateur se trouve dans l'une de ces régions avant de procéder.
Architecture : Où se place le Stockage Objet
Neon (Stockage Objet inclus) est des primitives backend, pas un hébergement d'application full-stack. Le Stockage Objet contient les fichiers que l'application et ses utilisateurs produisent — téléversements, pièces jointes, avatars, documents, images générées, sauvegardes — indexés à partir des lignes Postgres sur la même branche. Deux limites en découlent :
- Mettez un CDN devant les assets publics. Un objet
public_readest lu anonymement à${AWS_ENDPOINT_URL_S3}/<bucket>/<object-key>— le point de terminaison de stockage de la branche, injecté comme variable d'environnement (voir Variables d'Environnement). Pour les assets qu'un navigateur charge à chaque affichage de page — avatars, images de produits, tout ce qui est chaud — utilisez cela comme origine pour un CDN Cloudflare ou Vercel, et définissezCache-ControlsurPutObjectpour que le cache sache combien de temps conserver chaque objet. Un objet en cache n'est aussi frais que sa clé, donc écrivez chaque version sur une nouvelle clé (avatars/<user-id>/<uuid>.jpg) et repointez la clé stockée dans Postgres, plutôt que d'écraser une clé et d'attendre le TTL. Le point de terminaison est limité à la branche, donc un CDN de production pointe vers la branche de production tandis que les branches de preview lisent leur propre point de terminaison directement plutôt que de partager un cache. Les buckets privés restent sur des URLs présignées à la place, qui portent leur signature dans la chaîne de requête. - Hébergez l'application ailleurs. Tout ce qui est dans le dépôt — HTML, bundles JS, CSS, et les images et polices qui sont livrées dans
public/— appartient à Vercel, Netlify ou Cloudflare, ainsi que les documents d'index, les fallbacks SPA et les domaines personnalisés qui vont avec. Neon n'a pas de mode site Web pour les servir :PutBucketWebsiteretourne501 Not Implemented.
Configuration
Le stockage objet fait partie de la configuration d'infrastructure en tant que code neon.ts (voir la compétence neon pour le workflow basé sur les branches, link/checkout, et les bases de neon.ts). Déclarez les buckets sous preview.buckets, indexés par nom de bucket :
// neon.ts
import { defineConfig } from "@neon/config/v1";
export default defineConfig({
preview: {
buckets: {
images: {}, // privé par défaut
"public-assets": { access: "public_read" },
},
},
});
Provisionnez les buckets déclarés sur la branche liée :
neon deploy # alias pour `neon config apply`
Infrastructure en tant que Code Neon (neon.ts)
Le bloc preview.buckets ci-dessus fait partie de neon.ts, le fichier d'infrastructure en tant que code de Neon — un seul fichier TypeScript déclare vos buckets avec tous les autres services que la branche devrait avoir (voir la compétence neon pour la référence complète). Conciliez la déclaration avec une branche à la manière de Terraform :
neon config status # affiche la configuration en direct de la branche (quels buckets existent)
neon config plan # simulation de ce que apply changerait
neon config apply # crée les buckets déclarés (neon deploy est un alias)
Les buckets sont limités à la branche : lorsqu'un neon.ts est présent, neon checkout applique la politique lorsqu'elle crée une branche, donc une nouvelle branche de preview/CI démarre avec ses buckets déjà provisionnés (et les objets copy-on-write hérités du parent). Vérifier une branche existante ne la concilie pas — exécutez neon deploy pour appliquer les modifications. Le provisionnement (config apply / deploy), link, et checkout récupèrent également les identifiants S3 de la branche dans votre .env.local local, donc la même étape env pull montrée ci-dessous se produit pour vous lors de ces commandes.
Variables d'Environnement
Lorsque preview.buckets est déclaré, Neon injecte des variables d'environnement S3 standard AWS afin que les SDK AWS fonctionnent depuis l'environnement sans configuration supplémentaire. À l'intérieur d'une Fonction Neon déployée, celles-ci sont injectées automatiquement ; localement, récupérez-les sur le disque (ou injectez-les à l'exécution) via la CLI :
neon env pull # écrit les vars de la branche dans .env (ou .env.local)
# ou, sans écrire de fichier, injectez à l'exécution :
neon-env run -- <votre commande de développement>
| Variable | Signification |
|---|---|
AWS_ACCESS_KEY_ID | ID de clé d'accès S3 (l'identifiant de jeton de l'identifiant de branche) |
AWS_SECRET_ACCESS_KEY | Clé d'accès secrète S3 |
AWS_ENDPOINT_URL_S3 | URL du point de terminaison S3 de la branche |
AWS_REGION | Région, par ex. us-east-2 |
Comme les noms sont standard AWS, le SDK AWS récupère automatiquement les identifiants, le point de terminaison et la région depuis l'environnement. Les identifiants sont limités à la branche et valides pour cette branche et tous ses descendants.
Pour un accès typé et validé à ces identifiants au lieu de lire process.env directement, passez le même objet de configuration neon.ts à parseEnv de @neon/env — il retourne un espace de noms env.storage (accessKeyId, secretAccessKey, endpoint, region) dérivé de votre configuration. Voir la compétence neon.
Travailler avec les Objets : le SDK Files (Recommandé)
La manière la plus simple et la plus portable de lire et d'écrire des objets est le SDK Files avec son adaptateur neon — une petite API de stockage unifiée (upload, download, url, list, exists, copy, delete, signedUploadUrl) sur des E/S standard du Web. Il utilise le client S3 AWS en interne, configuré de manière appropriée pour Neon, et renomme les erreurs en Neon error — donc il n'y a rien à mal configurer. Utilisez-le en premier.
Installez-le avec les dépendances peer S3 AWS que l'adaptateur utilise en interne :
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
L'adaptateur résout son point de terminaison, sa région et ses identifiants à partir des mêmes variables d'environnement AWS_* injectées — passez uniquement le nom du bucket :
import { Files } from "files-sdk";
import { neon } from "files-sdk/neon";
const files = new Files({ adapter: neon({ bucket: "images" }) });
// Téléversement — le body peut être un Buffer, Uint8Array, Blob, File, ReadableStream ou string
await files.upload("generated/cat.jpg", fileBuffer, { contentType: "image/jpeg" });
// Téléchargement
const file = await files.download("generated/cat.jpg");
const bytes = new Uint8Array(await file.arrayBuffer());
// URL présignée GET — partagez sans exposer les identifiants (par défaut, expiration de 1h)
const url = await files.url("generated/cat.jpg", { expiresIn: 3600 });
// Plus : files.exists(), files.list({ prefix }), files.copy(), files.delete(), files.signedUploadUrl()
Échangez l'importation de l'adaptateur (files-sdk/s3, files-sdk/r2, files-sdk/gcs, …) et le reste de votre code reste inchangé.
Travailler avec les Objets : le Client S3 AWS (Alternative)
Neon parle directement l'API S3, vous pouvez donc descendre au niveau du SDK AWS chaque fois que vous préférez le client natif ou que vous en dépendez déjà. Les identifiants, le point de terminaison et la région sont lus depuis la chaîne d'environnement AWS standard, donc le seul paramètre que vous passez est forcePathStyle: true — Neon nécessite un adressage par chemin, donc le client S3 doit le définir :
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({
forcePathStyle: true, // requis : Neon utilise l'adressage par chemin
});
Ensuite, téléversez, téléchargez et présignez avec les objets de commande bruts :
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const BUCKET = "images";
// Téléversement
await s3.send(
new PutObjectCommand({
Bucket: BUCKET,
Key: "generated/cat.jpg",
Body: fileBuffer,
ContentType: "image/jpeg",
}),
);
// Téléchargement
const res = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();
// URL présignée GET — partagez sans exposer les identifiants
const url = await getSignedUrl(
s3,
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
{ expiresIn: 3600 },
);
Associer le Stockage avec la Base de Données sur une Branche
Le motif canonique : un agent génère une image → PutObject dans le bucket images → une ligne est insérée dans Postgres → une URL présignée est retournée à la lecture. Stockez la clé du bucket (pas les bytes) dans une colonne Postgres, et présignez à la lecture. Comme la ligne et l'objet vivent sur la même branche, ils se ramifient ensemble et ne dérivent jamais.
Commandes CLI pour Buckets et Objets
neon propose également des commandes de premier ordre pour les buckets/objets (neon bucket create|list|delete, neon bucket object put|get|list|delete) pour les scripts et les opérations ponctuelles.
Journaux de Branche Intégrés
neon logs query --branch production --source storage --since 1h
Le stockage est l'une des deux sources que les journaux de branche couvrent aujourd'hui, aux côtés des Fonctions Neon. Les journaux sont limités à une seule branche, donc passez --branch lorsque le bucket que vous déboguez n'est pas sur la branche sur laquelle vous êtes connecté. Tout le reste concernant les journaux — la version CLI requise, les filtres, le SDK et l'API de lecture compatible Loki — se trouve dans la section Observabilité de la compétence parente neon.
Documentation Neon
La documentation Neon est la source de vérité et le Stockage Objet évolue rapidement, vérifiez toujours par rapport à la documentation officielle. N'importe quelle page de documentation peut être récupérée en markdown en ajoutant .md à l'URL ou en demandant Accept: text/markdown. Trouvez la bonne page à partir de l'index de documentation (https://neon.com/docs/llms.txt) et des annonces du changelog.
Lectures Complémentaires
- https://neon.com/docs/storage/overview.md
- https://neon.com/docs/storage/get-started.md
- https://neon.com/docs/storage/buckets.md
- https://neon.com/docs/storage/objects.md
- https://neon.com/docs/storage/authentication.md
- https://neon.com/docs/storage/s3-compatibility.md
- https://neon.com/docs/storage/troubleshooting.md
- https://files-sdk.dev — Documentation du SDK Files (l'adaptateur
neon)