Showcase: Media Downloader
A production serverless media download service built on Mantle. Users submit YouTube URLs via an iOS app, the service downloads and processes the media asynchronously, then delivers it via CloudFront for offline playback. Originally built as a standalone CloudFormation/DynamoDB app, it is now the most feature-rich Mantle instance after a complete framework migration.
Architecture
iOS App
│
▼
CloudFront ──► API Gateway (custom authorizer)
│
├──► api/user/* (register, login, logout, refresh, subscribe, delete)
├──► api/device/* (register, event)
├──► api/files/* (list files)
└──► api/feedly/* (webhook, query auth)
│ (on download request)
▼
EventBridge (MediaDownloader bus)
│
├──► SQS DownloadQueue ──► StartFileUpload Lambda
│ │ (yt-dlp + ffmpeg layers)
│ ▼
│ S3 (files bucket)
│ │
│ ▼
│ S3ObjectCreated Lambda
│ │
│ ▼
│ SQS SendPushNotification ──► SNS ──► APNS (iOS)
│
└──► Scheduled: CleanupExpiredRecords, PruneDevices
Aurora DSQL (PostgreSQL-compatible, serverless)
◄── All Lambdas (Drizzle ORM, IAM auth)
standalone: ApiGatewayAuthorizer, MigrateDSQLMantle Features Used
| Feature | How it is used |
|---|---|
defineApiHandler | All 13 API routes — auth, schema validation, OpenAPI metadata |
defineEventBridgeHandler | StartFileUpload triggered by DownloadRequested event |
defineScheduledHandler | CleanupExpiredRecords, PruneDevices on CloudWatch schedules |
mantle build | Single command bundles all 18 handlers with esbuild |
mantle deploy --stage | OpenTofu plan + apply across staging and production |
mantle generate permissions | Auto-generates DSQL IAM grants from @RequiresTable decorators |
exportToS3 / emitEvent | S3 export + EventBridge follow-up events from @mantleframework/aws |
getDrizzleClient | Aurora DSQL with Drizzle ORM for all entity access |
@mantleframework/auth | Better Auth sessions, OAuth accounts, Sign In With Apple |
@mantleframework/observability | Structured logging, EMF metrics, X-Ray tracing (ADOT) |
Key Numbers
- 18 Lambda handlers across 5 trigger types (API, SQS, S3, Scheduled, Standalone)
- 5 entity types: User, File, Device, Session, Account (+ 3 join tables)
- 4 Lambda layers: yt-dlp, bgutil, QuickJS, ffmpeg (all x86_64)
- 2 SQS queues:
DownloadQueue(15 min visibility),SendPushNotification - 2 SNS topics: push notifications, operations alerts
- 12 ADRs documenting architecture decisions
Repo
aws-cloudformation-media-downloader/ — symlinked at the monorepo root.