Self-hosted web console for managing personal Google Drive — browse, upload, download, share, and organise files through a beautiful Apple-inspired glass UI.
- Full Drive browser — folder navigation, breadcrumbs, Spotlight-style search (Ctrl/Cmd+K), type filters
- Resumable chunked uploads — pause/resume, progress tracking, drag-and-drop
- Parallel downloads — multi-stream Range requests for large files
- Batch operations — multi-select trash, move, ZIP download
- Media preview — images (pinch-zoom), video, PDF, text editing
- Sharing & revisions — generate share links, browse file history
- Media download — yt-dlp powered: YouTube, Bilibili, direct links → auto-upload to Drive
- Overview dashboard — storage usage, upload history, type breakdown
- Responsive — works on desktop and mobile with touch-optimised UI
- Dark / Light / System theme with Apple Liquid Glass design
- Agent-ready API — stable
/api/v1with API keys (read / readwrite scopes) and OpenAPI spec at/api/v1/openapi.json - Performance — content-aware Gzip, connection pooling, thumbnail caching, adaptive chunk pipeline, context-aware retries
| Layer | Tech |
|---|---|
| Backend | Go 1.23, net/http, Google Drive API v3 |
| Frontend | Vite 5 + React 18 + TypeScript + Tailwind CSS |
| Auth | Google OAuth 2.0 (server-side token storage) |
| Deploy | Docker multi-stage build |
- Go 1.23+
- Node 20+ / npm 10+
- Google Cloud project with OAuth 2.0 Web credentials
- yt-dlp (for download feature) — install
- ffmpeg (for download feature — yt-dlp uses it for merging formats)
- (Optional) Docker & Docker Compose for containerised deployment
cp .env.example .env
# Edit .env with your Google OAuth credentialsRequired variables:
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID |
OAuth 2.0 client ID |
GOOGLE_CLIENT_SECRET |
OAuth 2.0 client secret |
SESSION_SECRET |
Random string for cookie signing |
OAUTH_REDIRECT_URL |
Callback URL (default: http://localhost:3000/oauth2/callback) |
FRONTEND_ORIGIN |
SPA URL for post-login redirect (default: http://localhost:5174/) |
Optional:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server listen port |
DEV_MODE |
0 |
1 = skip OAuth secret validation |
DATA_DIR |
./data |
Token & upload data directory |
ROOT_FOLDER_ID |
(empty) | Limit browsing to a specific Drive folder |
HTTP_PROXY |
(empty) | Proxy for Google API calls (e.g. socks5://...) |
WEB_DIST_DIR |
./web/dist |
Path to built SPA assets |
YTDLP_PATH |
(empty) | Path to yt-dlp binary; enables download feature |
DOWNLOAD_PROXY |
(empty) | Proxy for yt-dlp (e.g. socks5://127.0.0.1:10808) |
DOWNLOAD_COOKIE_PATH |
(empty) | Netscape cookie file for auth-required sites |
DOWNLOAD_TMP_DIR |
DATA_DIR/downloads |
Temp directory for downloaded files |
The download feature requires yt-dlp and ffmpeg.
Windows (winget):
winget install yt-dlp.yt-dlp
winget install Gyan.FFmpegmacOS (Homebrew):
brew install yt-dlp ffmpegLinux (pip):
pip install yt-dlp
sudo apt install ffmpeg # or: brew install ffmpegFind the binary path and set it in .env:
# Windows: typically C:\Users\<you>\AppData\Local\Programs\yt-dlp\yt-dlp.exe
# macOS/Linux: /opt/homebrew/bin/yt-dlp or /usr/local/bin/yt-dlp or ~/.local/bin/yt-dlp
which yt-dlp # macOS/Linux
where yt-dlp # WindowsSet in .env:
YTDLP_PATH=/path/to/yt-dlpDocker users: yt-dlp and ffmpeg are pre-installed in the Docker image. Skip this step.
# Backend (terminal 1)
go run ./cmd/server
# Frontend (terminal 2)
cd web && npm install && npm run dev- API: http://localhost:3000/api/health
- SPA: http://localhost:5174 (proxies
/api→:3000)
docker compose up --build -dOpen http://localhost:3000 — the Go server serves both API and SPA, with yt-dlp and ffmpeg pre-installed.
See docs/docker.md for full deployment guide.
cmd/server/ Server entrypoint
internal/
api/ HTTP handlers, middleware, router
apikey/ API key store for /api/v1 (agents & scripts)
auth/ OAuth 2.0 + session management
config/ Environment configuration
drive/ Google Drive API client
download/ yt-dlp download service & job store
upload/ Resumable upload job store
web/
src/ React SPA source
dist/ Production build output
cmd/
server/ Server entrypoint
cookieconvert/ Cookie Editor JSON → Netscape format converter
docs/ Design docs, API contract, progress
data/ Runtime data (gitignored)
# Go unit tests
go test ./... -count=1
# Frontend tests
cd web && npm test -- --run
# Type check
cd web && npx tsc --noEmit- API Contract
- Agent Skill — operate the drive via API
- Design Spec
- Agent File API Design
- Docker Deployment
- Development Workflow
- Progress Log
The download feature uses yt-dlp to download media from YouTube, Bilibili, Douyin, direct links, and other supported sites, then automatically uploads the result to Google Drive.
Docker: yt-dlp + ffmpeg are pre-installed. Just
docker compose up --buildand the feature is ready. Local dev: see the Install yt-dlp step above.
Sites like Bilibili and Douyin require authentication cookies. To set up:
- Install the Cookie Editor browser extension.
- Navigate to the site and log in.
- Open Cookie Editor → Export → JSON format → save as
bilibili.com.json. - Convert to Netscape format:
# Using the built-in converter tool
go run ./cmd/cookieconvert bilibili.com.json > data/cookies.txt
# Or inside Docker
docker compose exec app /cookieconvert /tmp/bilibili.com.json > /data/cookies.txt- Set in
.env:
DOWNLOAD_COOKIE_PATH=./data/cookies.txt # local dev
# DOWNLOAD_COOKIE_PATH=/data/cookies.txt # Docker- Restart the server.
- Two-phase pipeline: metadata resolution → download → upload to Drive (resumable for large files).
- Retry upload: if upload fails but the download succeeded, retry only re-uploads — no re-download.
- Non-video files: when yt-dlp returns
unknown_videoextension (common for direct links), the server infers the correct extension from the URL. - Folder routing: downloaded files go to
ROOT_FOLDER_IDor a specified Drive folder. Virtual folder names (e.g.Videos) are auto-created. - Proxy routing: domestic sites (Bilibili, Douyin) automatically bypass the download proxy; foreign sites (YouTube) use
DOWNLOAD_PROXYif set. - Job persistence: download jobs survive server restarts via
DATA_DIR/downloads.json. - Cleanup: a background reaper removes terminal jobs older than 1 hour; temp files are deleted after upload.
Private — personal use only.