OmniCloud is a full-stack cloud drive aggregation platform that presents multiple storage providers through a single, consistent workspace. The application combines a Vue-based client with an Express API and provider adapter layer, enabling users to browse, upload, download, and manage files across connected cloud accounts from one interface.
- Connect multiple cloud storage accounts in one application
- All providers are normalized through a consistent adapter layer
- Active provider support includes OAuth, account-based login, and access-key-based connections
Home,My Drive,Recent,Starred,Shared with Me, andQuotaviews- Virtual-path-based file navigation across providers
- File metadata is presented consistently across different provider sources
- Browse files and folders from connected accounts
- Create folders
- Rename files and folders
- Delete files and folders, including bulk delete
- Download provider files
- View file details and previews for supported file types
- Star / unstar files on providers that support it
- Browser-based file uploads
- Folder upload support
- Drag-and-drop uploads
- Upload session initiation through the API
- Real-time upload progress over WebSocket
- Automatic upload account allocation based on storage selection strategy
- File metadata is stored in SQLite for fast navigation
- Account synchronization runs on a schedule using
node-cron - The API exposes a manual sync trigger
- Delta sync reports are available through the health/sync layer
localmode for personal or simple self-hosted usagehostedmode for multi-user deployments with session-cookie-based register/login/logout- Account data, file mirrors, allocation config, and settings are scoped per user
- User settings such as language and theme
- Storage allocation strategies:
round_robinweighted_round_robinleast_usedmost_freemanual
- Account priority order can be configured for the manual strategy
| Provider | Status | Integration model |
|---|---|---|
| Google Drive | Active | OAuth + Google Drive API |
| OneDrive | Active | OAuth + Microsoft Graph |
| Dropbox | Active | OAuth + Dropbox API |
| Yandex Disk | Active | OAuth + Yandex Disk API |
| MEGA | Active | Email/password account connection |
| pCloud | Active | Email/password account connection |
| S3-compatible storage | Active | Access key / secret key / endpoint based |
Detailed provider credential setup is available in
docs/provider-setup.md.
OmniCloud/
ββ frontend/ # Vue 3 app (Vite, Pinia, Vue Router, i18n)
ββ backend/ # Express API, adapters, sync engine, SQLite
ββ docs/ # Provider setup documentation
ββ package.json # Root workspace scripts
ββ LICENSE
ββ README.md
flowchart TD
U[User] --> F[Frontend<br/>Vue 3 + Vite]
F -->|REST API requests| B[Backend API<br/>Express.js]
subgraph Frontend Features
F1[Auth]
F2[Accounts]
F3[File Explorer]
F4[Uploads]
F5[Settings]
F6[Allocation]
end
F --> F1
F --> F2
F --> F3
F --> F4
F --> F5
F --> F6
B --> A[Adapter Registry]
A --> G[Google Drive Adapter]
A --> O[OneDrive Adapter]
A --> D[Dropbox Adapter]
A --> M[MEGA Adapter]
A --> P[pCloud Adapter]
A --> Y[Yandex Adapter]
A --> S[S3 Adapter]
G --> CP[Cloud Providers]
O --> CP
D --> CP
M --> CP
P --> CP
Y --> CP
S --> CP
B --> N[Normalized OmniCloud Data Model]
CP --> N
N --> DB[SQLite Metadata Mirror]
B --> DB
B -->|Upload progress| WS[WebSocket Hub]
WS --> F
B --> SY[Sync Service]
SY --> CRON[node-cron Scheduler]
SY --> CP
SY --> DB
B --> AL[Allocation Service]
AL --> ACC[Target Account Selection<br/>round_robin / weighted / least_used / most_free / manual]
ACC --> CP
B --> AU[Auth & Session Layer]
AU --> DB
At a high level:
- The frontend calls the REST API for auth, accounts, files, uploads, settings, and allocation
- The backend selects the appropriate provider adapter (
google_drive,onedrive,dropbox,mega,pcloud,yandex,s3) - Provider responses are normalized into the OmniCloud data model
- File metadata is mirrored into SQLite for fast access
- Upload progress is pushed to the client over WebSocket
- The sync service keeps local metadata aligned with provider state
The frontend currently includes these main views:
/β Home dashboard/my-driveβ main file explorer/shared-with-meβ shared files from supported providers/recentβ recent files/starredβ starred files/quotaβ quota overview, account management, allocation settings/loginand/registerβ used in hosted mode
Before running the project, make sure you have:
- Node.js 20+
- npm
- Provider credentials for the cloud services you want to use
Using a current compatible Node.js LTS release is recommended.
From the project root:
npm installCopy the env template:
copy backend/.env.example backend/.envOr create it manually based on backend/.env.example.
Example environment values for the current project:
PORT=8787
# local = single-user, hosted = multi-user with login/register
APP_MODE=local
CORS_ORIGIN=http://localhost:5173
FRONTEND_URL=http://localhost:5173
SYNC_INTERVAL_MINUTES=5
OMNICLOUD_SECRET_HALF=replace-this-with-random-half-key
AUTH_COOKIE_NAME=omnicloud_session
AUTH_SESSION_TTL_HOURS=336
AUTH_SECRET=replace-this-with-a-strong-random-secret
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:8787/api/accounts/google/callback
ONEDRIVE_CLIENT_ID=
ONEDRIVE_CLIENT_SECRET=
ONEDRIVE_TENANT_ID=common
ONEDRIVE_REDIRECT_URI=http://localhost:8787/api/accounts/onedrive/callback
DROPBOX_CLIENT_ID=
DROPBOX_CLIENT_SECRET=
DROPBOX_REDIRECT_URI=http://localhost:8787/api/accounts/dropbox/callback
YANDEX_CLIENT_ID=
YANDEX_CLIENT_SECRET=
YANDEX_REDIRECT_URI=http://localhost:8787/api/accounts/yandex/callbackNotes:
- MEGA and pCloud do not use
.envcredentials; they are connected from the UI using email/password - S3-compatible storage is configured from the UI using endpoint/bucket/access key/secret key
APP_MODE=hostedenables the register/login/logout flow using session cookies
Follow the detailed guide in:
Run the frontend and backend together from the root:
npm run devDefault local endpoints:
- Frontend:
http://localhost:5173 - API:
http://localhost:8787
The project includes Docker integration for running the API and production frontend behind Nginx.
copy backend/.env.example backend/.envThen fill in the provider credentials and secrets in backend/.env.
For the default Docker Compose setup, the app is exposed at http://localhost:8080, so OAuth redirect URLs should use the proxied API URLs:
GOOGLE_REDIRECT_URI=http://localhost:8080/api/accounts/google/callback
ONEDRIVE_REDIRECT_URI=http://localhost:8080/api/accounts/onedrive/callback
DROPBOX_REDIRECT_URI=http://localhost:8080/api/accounts/dropbox/callback
YANDEX_REDIRECT_URI=http://localhost:8080/api/accounts/yandex/callbackThese values are also set in docker-compose.yml so they override the local-development defaults from backend/.env when running with Compose.
docker compose up --buildOpen the app at:
- Frontend:
http://localhost:8080 - API through Nginx proxy:
http://localhost:8080/api
docker compose downSQLite data is persisted in the Docker volume omnicloud_api_data. To remove containers and the persisted Docker database volume:
docker compose down -v| Script | Description |
|---|---|
npm run dev |
Run frontend and backend in parallel |
npm run build |
Build the production frontend |
npm run build:web |
Build only the frontend |
npm run dev:web |
Run the Vite dev server |
npm run dev:api |
Run the backend with node --watch |
npm start |
Start the backend without watch mode |
| Script | Description |
|---|---|
npm --prefix frontend run dev |
Start the Vite dev server |
npm --prefix frontend run build |
Build the frontend |
npm --prefix frontend run preview |
Preview the built frontend |
| Script | Description |
|---|---|
npm --prefix backend run dev |
Run the API with file watch |
npm --prefix backend start |
Run the API normally |
These are the main API surfaces currently present in the project.
GET /api/healthPOST /api/sync/run
GET /api/auth/mePOST /api/auth/registerPOST /api/auth/loginPOST /api/auth/logout
GET /api/accountsDELETE /api/accounts/:idGET /api/accounts/google/statusGET /api/accounts/onedrive/statusGET /api/accounts/dropbox/statusGET /api/accounts/yandex/statusGET /api/accounts/mega/statusGET /api/accounts/google/connectGET /api/accounts/onedrive/connectGET /api/accounts/dropbox/connectGET /api/accounts/yandex/connectPOST /api/accounts/mega/connectPOST /api/accounts/pcloud/connectPOST /api/accounts/s3/connect- OAuth callback routes under
/api/accounts/*/callback
GET /api/filesGET /api/files?path=/GET /api/files?recent=1GET /api/files?starred=1GET /api/files?shared=1GET /api/files/:id/shared-childrenPATCH /api/files/:id/starPOST /api/files/bulk/delete
The project also includes additional file routes for file explorer operations such as details, download, rename, create folder, and per-item delete in the file service / adapter workflow.
POST /api/uploads/initiatePOST /api/uploads/:uploadId/streamWS /ws/uploads?uploadId=...
GET /api/settingsPATCH /api/settingsGET /api/allocationPATCH /api/allocation
When an upload starts, the backend selects the target account based on the user's allocation configuration. This allows file distribution across providers to be automatic or manually prioritized depending on the user's preference.
Example use cases:
- Distribute uploads across multiple accounts in rotation
- Prioritize the account with the most free space
- Enforce a specific manual ordering
Important data stored locally includes:
- Mirrored file metadata in SQLite (
backend/omnicloud.db) - Linked account metadata
- Encrypted provider credentials / token material
- User settings
- Allocation config and rotation state
- Auth session data for hosted mode
- Do not commit
backend/.env - Do not commit local production or personal testing database files
- OAuth client secrets, refresh tokens, session secrets, access keys, and provider passwords must be treated as sensitive
OMNICLOUD_SECRET_HALFis used as part of local encryption key material- For
APP_MODE=hosted, use a strongAUTH_SECRETand the correct frontend origin
This project is licensed under the MIT License.




