cloud_queue
Better MediaDeveloper docs

Installation

Step-by-step setup guide for Better Media.

Install Better Media

pnpm add @better-media/framework
npm install @better-media/framework
yarn add @better-media/framework

Install 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-s3
npm install @better-media/adapter-storage-s3
yarn add @better-media/adapter-storage-s3

Other 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 pg
npm install @better-media/adapter-db-kysely pg
yarn add @better-media/adapter-db-kysely pg

Other 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/mydb

Configure the database adapter

Set up Kysely with your Postgres connection:

lib/database.ts
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:

lib/media.ts
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 migrate
npx media migrate
yarn media migrate

Or 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.

On this page