Installation
Step-by-step setup guide for Better Media.
Install Better Media
pnpm add @better-media/frameworknpm install @better-media/frameworkyarn add @better-media/frameworkInstall a storage adapter
For this example we'll use S3, which works with AWS S3, Cloudflare R2, MinIO, and any S3-compatible provider.
pnpm add @better-media/adapter-storage-s3npm install @better-media/adapter-storage-s3yarn add @better-media/adapter-storage-s3Other storage options
Filesystem and in-memory adapters are also available. See the Storage section for all options.
Install a database adapter
pnpm add @better-media/adapter-db-kysely pgnpm install @better-media/adapter-db-kysely pgyarn add @better-media/adapter-db-kysely pgOther databases
MongoDB, MySQL, and SQLite are also supported. See the Database section for setup guides.
Set environment variables
Add your storage and database credentials to your .env file:
# S3 Storage
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
S3_BUCKET=your-bucket-name
# Database
DATABASE_URL=postgres://user:password@localhost:5432/mydbConfigure the database adapter
Set up Kysely with your Postgres connection:
import { Pool } from "pg";
import { Kysely, PostgresDialect } from "kysely";
import { KyselyDbAdapter } from "@better-media/adapter-db-kysely";
import { schema } from "@better-media/core";
const db = new Kysely({
dialect: new PostgresDialect({
pool: new Pool({ connectionString: process.env.DATABASE_URL }),
}),
});
export const database = new KyselyDbAdapter(db, {
config: { provider: "pg" },
schema,
});Create a Better Media instance
Wire your storage, database, and plugins together in one place:
import { createBetterMedia } from "@better-media/framework";
import { S3StorageAdapter } from "@better-media/adapter-storage-s3";
import { database } from "./database";
export const media = createBetterMedia({
storage: new S3StorageAdapter({
region: process.env.AWS_REGION!,
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
bucket: process.env.S3_BUCKET!,
}),
database,
plugins: [],
});Import media anywhere in your app — route handlers, workers, scripts.
Create database tables
Better Media manages its own tables. Run the migration CLI to apply them:
pnpm exec media migratenpx media migrateyarn media migrateOr run migrations programmatically on app startup:
import { runMigrations } from "@better-media/core";
import { database } from "./lib/database";
import { schema } from "@better-media/core";
await runMigrations(database, schema);You're ready
Your media instance is ready to use. Upload your first file:
import { media } from "./lib/media";
const result = await media.upload.ingest({
file: { buffer: fileBuffer },
metadata: { filename: "photo.jpg", mimeType: "image/jpeg" },
});
console.log(result.id, result.key);From here, explore plugins to add validation, virus scanning, or image processing to the pipeline.