Emberly is an open-source platform for modern file storage, sharing, discovery, and identity verification. Build your digital presence with powerful tools for teams and individuals.
File Storage & Sharing
- S3-compatible object storage with configurable upload limits
- Secure file sharing with customizable access controls
- File organization, tagging, and search
- OCR-powered text extraction from uploaded images and documents
- URL shortening with redirect tracking
- Bandwidth-efficient delivery through global infrastructure
Domain & Branding
- Custom domain support with annual registration
- Personal or team branded file-sharing pages
- Domain SSL certificate management
- DNS configuration assistance
Identity & Verification
- User verification badges with multiple tier options
- Verification queue with application review system
- Badge display on public profiles
- Organization verification for teams
Team & Collaboration
- Squad-based team subscriptions with seat-based pricing
- Granular permission management (roles:
SUPPORT,DEVELOPER,MODERATOR,DESIGNER,STAFF) - Team member invitations and management
- Shared storage pools with usage tracking
Applications & Trust
- Staff application system for organizational partnerships
- Partner program enrollment
- Verification badge applications
- Ban appeal process with review workflow
- Email notifications for all application updates
Administrative Tools
- Promo code management with configurable discounts
- User management dashboard
- Application review queue with multi-stage triage
- Service status page (emberlystat.us)
- Analytics and usage reporting
For contribution guidelines and detailed documentation see CONTRIBUTING.md.
- Node.js 18+
- Bun (recommended package manager)
- PostgreSQL 14+
- Redis 6+ (required — used for caching, rate limiting, and the job queue)
# Clone the repository
git clone https://github.com/EmberlyOSS/Emberly.git
cd Emberly
# Install dependencies
bun install
# Configure environment
cp .env.template .env
# Edit .env with your local configuration
# Initialize database
bun run db:generate
bun run db:migrate
# (Optional) Seed subscription plans
bun run db:seed
# Start development server
bun devThe application will be available at http://localhost:3000.
In development, the event worker runs in-process automatically — no extra steps needed. See Event Worker for production deployment.
Frontend & Framework
- Next.js 16 — React framework with App Router
- React 19 — UI library
- TypeScript — strict-mode type safety
- Tailwind CSS — utility-first styling
- shadcn/ui — accessible component library
Backend & Database
- PostgreSQL — relational database
- Prisma ORM — database toolkit and migrations
- Redis + BullMQ — caching, rate limiting, and background job queue
- Stripe — payment processing
- Resend — transactional email delivery
Infrastructure & Services
- S3-compatible object storage (AWS S3 / Vultr) — file storage
- NextAuth — authentication (Discord OAuth, GitHub OAuth, credentials)
- Sentry — error tracking and monitoring
- VirusTotal — file scanning on upload
Development Tools
- Bun — runtime and package manager
- ESLint + Prettier — linting and formatting
- Husky + commitlint — git hooks and commit linting
app/ Next.js App Router pages and routes
(main)/ Public user pages (auth, admin, user profiles)
(raw)/ Raw file serving
(shorturl)/ Short URL redirects
api/ ~180 REST API endpoints
packages/
components/ React component library
admin/ Admin dashboard components
dashboard/ User dashboard
auth/ Authentication UI
file/ File management UI
pricing/ Pricing and plans
ui/ shadcn/ui base components
hooks/ Custom React hooks
use-file-upload.tsx File uploading with progress
use-profile.ts User profile data
use-user-content.ts User content queries
use-file-actions.ts File action handlers
lib/ Business logic and integrations
api/ API handler wrapper (auth, logging, errors)
auth/ NextAuth config and helpers
events/ BullMQ job queue — emit helpers and per-event handlers
cache/ Redis helpers
storage/ S3 / Vultr integration
emails/ Email templates (Resend)
stripe/ Payment processing
permissions/ RBAC permission helpers
nexium/ Team/squad system
security/ Security utilities and rate limiting
logger/ Pino structured logging
types/ Shared TypeScript type definitions
prisma/
schema.prisma Database schema
migrations/ Migration history
public/ Static assets
scripts/ Utility scripts (seed, media-kit, worker)
Emberly uses BullMQ (backed by Redis) to process background jobs: emails, audit logs, Discord notifications, file expiry, storage sync, and more.
All API routes call events.emit('some.event', payload), which pushes a job onto the emberly-events BullMQ queue. A worker process dequeues jobs and dispatches them to the registered handlers.
In development the worker runs in-process alongside the Next.js dev server — no extra setup needed beyond REDIS_URL in your .env.
You can also run it as a dedicated process:
bun run workerThe in-process worker is controlled by EMBERLY_RUN_EVENT_WORKER:
| Value | Behaviour |
|---|---|
| unset | Auto-starts in development, skipped in production |
true |
Always starts (useful for single-container deploys) |
false |
Never starts (use standalone worker instead) |
In production, run the worker as a separate process alongside the web server:
# web server
bun run start
# event worker (separate terminal / container)
bun run workerUse the same image with a different start command:
# web container
CMD ["bun", "run", "start"]
# worker container
CMD ["bun", "run", "worker"]Both need the same REDIS_URL and DATABASE_URL. The worker serves no HTTP traffic and does not need PORT or NEXTAUTH_URL.
| Variable | Required | Description |
|---|---|---|
REDIS_URL |
Yes | Redis connection string (redis://host:6379) |
DATABASE_URL |
Yes | PostgreSQL connection string |
WORKER_CONCURRENCY |
No | Jobs processed in parallel (default: 10) |
Provider credentials (SMTP, Discord webhook, etc.) are stored in the database via Admin → Integrations, not in env.
Create a unit file at /etc/systemd/system/emberly-worker.service:
[Unit]
Description=Emberly Event Worker
After=network.target redis.service postgresql.service
Requires=redis.service
[Service]
Type=simple
User=emberly
WorkingDirectory=/opt/emberly
EnvironmentFile=/opt/emberly/.env
ExecStart=/usr/local/bin/bun run worker
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=emberly-worker
# Prevent the worker from using excessive resources
MemoryMax=512M
CPUQuota=80%
[Install]
WantedBy=multi-user.targetThen enable and start it:
sudo systemctl daemon-reload
sudo systemctl enable emberly-worker
sudo systemctl start emberly-worker
# Check status and live logs
sudo systemctl status emberly-worker
sudo journalctl -u emberly-worker -fThe EnvironmentFile path should point to the same .env used by your web server. Make sure it contains at minimum REDIS_URL and DATABASE_URL.
To deploy a new version:
# Pull changes, then restart the worker
sudo systemctl restart emberly-workerMultiple worker instances can run simultaneously — BullMQ uses Redis atomic operations so each job is processed exactly once. Add more worker containers or systemd units to increase throughput.
BullMQ exposes queue and job state via Redis. Any BullMQ-compatible dashboard (e.g. Bull Board) can connect using:
- Queue name:
emberly-events - Completed jobs are retained for 24 hours
- Failed jobs are retained for 7 days and retried up to 3 times with exponential backoff
We welcome contributions from the community. Please see CONTRIBUTING.md for detailed guidelines including:
- Development environment setup
- Code standards and conventions
- Pull request process
- Commit message format
- How to report issues
- Community channels and support
- Discord — Join our server for real-time discussions
- GitHub Discussions — Ask questions and share ideas
- Email — hey@embrly.ca for support
This project is licensed under the GNU Affero General Public License v3 (AGPL-3.0). See the LICENSE file for details.
This project adheres to the Contributor Covenant Code of Conduct. By participating, you agree to uphold this code. See CODE_OF_CONDUCT.md for the full text.
Thank you to all contributors who have helped make Emberly possible, and to the open-source projects that power it.