I've been running Nextcloud for years. It does everything — file sync, calendars, contacts, notes, tasks, video calls. The problem is it also breaks everything. PHP memory limits, background job failures, upgrade paths that require reading changelogs like legal documents. I just want file storage.
So I'm building LessCloud: a self-hosted cloud storage server with a clean UI, minimal infrastructure, and Nextcloud API compatibility so existing mobile apps keep working.
Why not just use Nextcloud
Nextcloud requires PHP, Redis, a cron job, and careful tuning to avoid the dreaded "background jobs not running" warning. Every major upgrade is a coin flip. And most of the features — Talk, Calendar, Deck, Mail — are bolted-on apps that add complexity without adding reliability.
I only use about 10% of Nextcloud: file storage, sync, and sharing. LessCloud does exactly that, with a single Go binary and Postgres.
The stack
| Layer | Technology |
|---|---|
| Backend | Go, Chi router, sqlc |
| Database | PostgreSQL |
| Frontend | React, Vite, TanStack Router, TanStack Query |
| Styling | Tailwind CSS |
No Redis. No queue system. No object storage adapter. Files go on disk, metadata goes in Postgres, and the Go binary serves both the API and the frontend.
Nextcloud compatibility layer
The key feature: existing Nextcloud mobile apps work out of the box. LessCloud implements:
- WebDAV — full file operations at
/remote.php/dav/files/{username}/ - Chunked uploads — for large files via
/remote.php/dav/uploads/{username}/ - OCS API — capabilities, user info, sharing
- Login flow v2 — the browser-based auth flow that Nextcloud apps use to get app passwords
This means you can point the Nextcloud Android/iOS app at your LessCloud instance and it just works. No custom app needed.
What it actually does
The web UI is closer to Google Drive than Nextcloud: list and grid views, drag-and-drop uploads, right-click context menus, keyboard shortcuts, and a details panel. Everything you'd expect.
Under the hood:
- Full-text search powered by Postgres
tsvector/tsquery— no Elasticsearch needed - File versioning with configurable retention
- Public sharing with optional passwords and expiration
- Realtime updates via Server-Sent Events — open two tabs and changes appear instantly
Deployment
Same philosophy as my other projects: single docker compose up -d. The multi-stage Dockerfile builds the React frontend, compiles the Go binary, and produces a minimal Alpine image. Two containers total — the app and Postgres.
Configuration is entirely through environment variables. No config files, no admin panels with 200 settings.
Current state
It's usable for daily driving. I've migrated my own files off Nextcloud and haven't looked back. The Nextcloud Android app syncs photos and documents without issues. The main things still missing are calendar/contacts (CalDAV/CardDAV) — but honestly, I'm not sure I want to add them. The whole point is to do less.