Neon Object Storage
Il s'agit d'une fonctionnalité en prévisualisation et uniquement disponible dans us-east-2. Neon Object Storage est un stockage d'objets compatible S3 qui se déploie avec vos projets : chaque branche reçoit son propre état de stockage isolé, de sorte que fichiers et lignes de base de données restent synchronisés entre dev, preview, staging et production.
Utilisez cette skill pour aider l'utilisateur à stocker et servir des fichiers qui se déploient avec sa base de données. Fournissez un bucket fonctionnel et un flux d'upload/download, un client S3 conscient des branches câblé aux variables d'env injectées, ou une réponse précise de la documentation officielle de Neon.
Quand l'utiliser
Optez pour Neon Object Storage quand l'utilisateur a besoin de stocker des fichiers (images, uploads, assets générés, documents, backups) et qu'au moins l'un des points suivants est vrai :
- Il utilise déjà Neon Postgres et ne veut pas d'un second prestataire. Un backend, une facture, une CLI, un 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 credential Neon qui sauvegarde la base de données sauvegarde le stockage.
- Les fichiers doivent rester synchronisés avec la base de données entre environnements. Le stockage se déploie avec vos données Postgres. Déployez une branche et l'enfant hérite instantanément des buckets et objets du parent à ce moment — copy-on-write, donc pas de duplication de données. C'est ce qui rend les environnements agent, dev, preview et test fluides : une branche preview reçoit un snapshot cohérent à la fois des lignes et des fichiers qu'elles référencent, et les écritures sur l'enfant ne touchent jamais le parent.
- Ils veulent des environnements sûrs et jetables. Uploadez, écrasez et supprimez des fichiers dans une branche preview/CI sans risque pour les données de production, puis supprimez la branche.
- Ils veulent l'outillage S3 standard. C'est bâti sur la sémantique S3 et communique via l'API S3, donc les AWS SDKs,
boto3, l'AWS CLI et les URLs présignées fonctionnent tous — fiable et familier, sans client propriétaire.
Si l'utilisateur n'a pas de projet Neon, n'est pas sur Postgres et a juste besoin d'un magasin d'assets CDN-backed autonome, un object store dédié pourrait être plus adapté — mais dès que des fichiers et lignes cohérents entre branches importent, c'est la raison de l'utiliser.
Ce qu'il fait
- Compatible S3 — Fonctionne avec les SDKs S3 existants,
boto3, l'AWS CLI et les URLs présignées. Adressage path-style et SigV4 uniquement. - Se déploie avec votre base de données — Chaque branche Neon reçoit son propre état de stockage isolé et copy-on-write. Déployer une branche ne copie aucune donnée.
- Deux modes d'accès — Les buckets
privateexigent un credential pour chaque opération ; les bucketspublic_readpermettent les lectures anonymes avec écritures authentifiées. - Un système de credential unique — Le même système de credential Neon utilisé par Functions et l'AI Gateway.
Configuration
Le stockage d'objets fait partie de la config infrastructure-as-code neon.ts (voir la skill neon pour le workflow branch-first, 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 "@neondatabase/config/v1";
export default defineConfig({
preview: {
buckets: {
images: {}, // private par défaut
"public-assets": { access: "public_read" },
},
},
});
Mettez en place les buckets déclarés sur la branche liée :
neonctl deploy # alias for `neonctl config apply`
Variables d'environnement
Quand preview.buckets est déclaré, Neon injecte les variables d'env S3 conformes à AWS pour que les AWS SDKs fonctionnent depuis l'environnement sans config supplémentaire. À l'intérieur d'une Neon Function déployée, elles sont injectées automatiquement ; en local, récupérez-les sur disque (ou injectez-les à l'exécution) via la CLI :
neonctl env pull # writes the branch's vars into .env (or .env.local)
# or, without writing a file, inject at runtime:
neon-env run -- <your dev command>
| Variable | Signification |
|---|---|
AWS_ACCESS_KEY_ID |
S3 Access Key ID (ID du token du credential de branche) |
AWS_SECRET_ACCESS_KEY |
S3 Secret Access Key |
AWS_ENDPOINT_URL_S3 |
URL de l'endpoint S3 de la branche |
AWS_REGION |
Région, ex. us-east-2 (aussi injectée comme NEON_STORAGE_REGION) |
NEON_STORAGE_FORCE_PATH_STYLE |
Toujours "true" — l'adressage path-style est requis |
Puisque les noms respectent le standard AWS, le AWS SDK récupère automatiquement les credentials, l'endpoint et la région depuis l'environnement. La seule préoccupation Neon-spécifique est l'adressage path-style (forcePathStyle: true), qui n'a pas d'équivalent en variable d'env AWS — et les AWS SDKs utilisent par défaut path-style pour un endpoint personnalisé. Les credentials sont scoped à une branche et valides pour cette branche et tous ses descendants.
Configurer le client S3
Puisque chaque valeur sauf forcePathStyle est lue depuis la chaîne AWS env standard, le client est minuscule — pas d'endpoint ou de clés en dur :
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({
forcePathStyle:
(process.env.NEON_STORAGE_FORCE_PATH_STYLE ?? "true").toLowerCase() !==
"false",
});
Si vous préférez un accès typé au lieu de lire process.env directement, parseEnv (from @neondatabase/env) retourne un namespace validé env.storage (accessKeyId, secretAccessKey, endpoint, region, forcePathStyle) dérivé de votre neon.ts — voir la skill neon.
Upload, download et presigning
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const BUCKET = "images";
// Upload
await s3.send(
new PutObjectCommand({
Bucket: BUCKET,
Key: "generated/cat.jpg",
Body: fileBuffer,
ContentType: "image/jpeg",
}),
);
// Download
const res = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();
// Presigned GET — share without exposing credentials
const url = await getSignedUrl(
s3,
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
{ expiresIn: 3600 },
);
C'est exactement le pattern utilisé bout en bout dans l'exemple with-ai-sdk (agent génère une image → PutObject dans le bucket images → ligne insérée dans Postgres → URL présignée retournée), qui est la référence canonique pour coupler stockage et base de données sur une branche.
Un pattern d'app courant : stockez la clé du bucket (pas les bytes) dans une colonne Postgres, et générez une URL présignée à la lecture. Puisque la ligne et l'objet vivent sur la même branche, ils se déploient ensemble et ne dérivent jamais.
neonctl a aussi des commandes de bucket/objet de première classe (neonctl bucket create|list|delete, neonctl bucket object put|get|list|delete) pour les scripts et les opérations ponctuelles.
Disponibilité
Neon Object Storage est une fonctionnalité en prévisualisation (early access) disponible uniquement sur de nouveaux projets dans la région us-east-2. Confirmez que le projet Neon de l'utilisateur est un nouveau projet dans us-east-2 avant de procéder ; il ne peut pas être activé sur des projets existants. Si l'utilisateur n'a pas encore accès, pointez-le vers l'inscription au bêta privé : https://neon.com/blog/were-building-backends#access
Documentation Neon
La documentation Neon est la source de vérité et Object Storage évolue rapidement, donc vérifiez toujours contre la docs officielle. N'importe quelle page de doc peut être récupérée en markdown en ajoutant .md à l'URL ou en demandant Accept: text/markdown. Trouvez la bonne page depuis l'index des docs (https://neon.com/docs/llms.txt) et les 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