Swush
Swush is a secure, self-hosted full‑stack file manager and personal dashboard built with Next.js, TypeScript, TailwindCSS, and Better Auth. It offers a unified platform to manage your files, short links, upload requests, watchlist (anime, movies, TV shows), and more; all with privacy and control in mind.
✨ Features
Authentication & Security
- Better Auth sessions with optional 2FA (TOTP).
- Robust session management and role-based access.
- Role-based access control with Owner, Admin, and User roles.
- Admin capabilities to promote/demote users and protect API endpoints.
Content Management Modules
- Files, Short Links, Upload Requests.
- Pagination, bulk selection and deletion.
- Slug support for friendly URLs.
Sharing & Growth
- Public profiles and share pages with optional passwords.
- QR sharing with presets and avatar overlays.
- UTM builder for short links.
Watchlist
- Track movies, TV shows, and anime via TMDB & AniList integrations. (Integrations are solely per the session, no user data is saved, but the selected data is retained.)
- Season and episode progress tracking.
- Adding personal notes.
- Bulk actions (delete, change visibility).
- Public sharing via
/l/usernamewith optional privacy toggle for each show. - Import data from AniList.
UI/UX
- Responsive design powered by Tailwind CSS v4.
- Smooth animations and transitions.
- Image paste-to-upload functionality.
Infrastructure & Integrations
- Minimal API routes abstracted into reusable
lib/functions. - Email notifications for password resets, new logins, and import summaries.
- Docker support for streamlined production deployment.
📦 Tech Stack
- Frontend: Next.js, React, TailwindCSS
- Backend: Next.js API routes, TypeScript, Better Auth (authentication)
- Database: PostgreSQL (Neon or self-hosted)
- ORM: Drizzle
- External APIs: TMDB, AniList, Steam, RAWG
- Email: SMTP (configurable)
🚀 Getting Started
1. Clone the repository
pnpm x degit imthatdev/swush
cd swush
2. Install dependencies
pnpm install
Note: Swush uses PNPM and Node.js. You can use
npmoryarnas alternatives if you prefer, but ensure the lockfile and workspace compatibility.
3. Setup environment variables
Copy example.env to .env and update the values:
cp example.env .env
4. Environment Variables Overview
Core
- Please consider checking the
.envfile for all available options. Commented variables have default values or optional.
5. Run database migrations
pnpm db:migrate
6. Start the development server
pnpm dev
Open http://localhost:3000 in your browser.
🐳 Deployment with Docker
Note: The Docker setup has been recently updated and optimized for smaller image size and faster builds.
Compose files now run two services by default:
app(JOB_RUNNER_ROLE=api) serves HTTP/API traffic.worker(JOB_RUNNER_ROLE=worker) handles heavy background jobs (transcoding, previews, remote uploads, exports, cleanup).
This keeps API latency stable while long-running jobs are isolated.
Build and run with remote database (Neon, Supabase, etc.)
docker compose -f docker/docker-compose.remote.yml up -d --build
Run with self-hosted PostgreSQL
docker compose -f docker/docker-compose.yml up -d --build
Scale workers independently
docker compose -f docker/docker-compose.yml up -d --scale worker=2
- The app will be accessible at http://localhost:3419.
- PostgreSQL will be exposed on port
5432(credentials configured in.env).
☁️ Cloudflare Cache Rules (HLS Only)
If you use Cloudflare Tunnels (cloudflared) and a global “Bypass Cache” rule, you can still safely cache HLS streaming assets only. This improves playback startup and reduces origin load while leaving everything else uncached.
Recommended rule (Cache Everything only for HLS):
Expression
(http.host eq "sub.example.domain" and starts_with(http.request.uri.path, "/hls/"))
Settings
- Cache: Cache Everything
- Origin Cache Control: On (respect origin headers)
- Edge Cache TTL: Use Cache-Control header
This keeps:
.m3u8playlists short‑lived (origin sends short cache).ts/.m4s/.aacsegments long‑lived (origin sends immutable cache)
If you want to keep your global bypass rule, just add this HLS rule above it
so /hls/* is cached while all other routes stay bypassed.
🔧 Self‑Hosting Guide
-
DNS & Reverse Proxy
- Point your domain to your server's IP.
- Use a reverse proxy like Nginx, Traefik, or Caddy with HTTPS enabled (Let's Encrypt recommended).
-
Environment Variables
- Set
APP_URLto your domain with HTTPS. - Securely configure
BETTER_AUTH_SECRETand database credentials.
- Set
-
Database
- Choose Neon (managed) or self-hosted PostgreSQL.
- Regularly back up your database.
-
Email
- Configure SMTP settings for password resets and notifications.
📸 Screenshots


Coming Soon: (Games Collection, Snippets, and more)


🌐 Demo
Experience Swush live at demo.swush.app.
You can sign up and test all features with your account, if the demo is online and if the registration is open. (You may contact me if it's closed.)
Feel free to explore the features and get a feel for the app before deploying your own instance.
🤝 Contributing
Contributions are welcome! To contribute:
- Fork the repository.
- Create a feature branch.
- Open a pull request.
Before committing, run linting and tests:
pnpm lint
📜 License
APACHE 2.0 © 2026 Iconical
💬 Support
- X: x.com/imthatdevy
- Website: iconical.dev
- Changelog: iconical.dev/changelog/swush
- Roadmap: iconical.dev/roadmap/swush
- Feedback: iconical.dev/feedback/swush
- GitHub: imthatdev
- Email: [email protected]
🙏 To Note Again
Swush is fully free and open-source. There are no paid tiers or upgrade requirements to use it.