Open-source file storage platform. A self-hostable alternative to Dropbox and Google Drive.
- File Explorer — Upload, organize, rename, move, and delete files and folders
- Share Links — Generate shareable links with optional password protection, expiration, and download limits
- Upload Links — Let others upload files to your storage without an account
- Storage Provider Agnostic — Swap between Local, AWS S3, Cloudflare R2, or Vercel Blob via a single env var
- Storage Quotas — Per-user storage limits with usage tracking
- Virtual Bash Filesystem (beta) — Traverse workspace files with
ls,cd,find,cat,grep, etc. viajust-bash
- Framework: Next.js 16 (App Router, Turbopack)
- Monorepo: Turborepo + pnpm workspaces
- Database: PostgreSQL 16 + Drizzle ORM
- API: tRPC 11 (end-to-end type safety)
- Auth: BetterAuth (email/password, Google OAuth)
- UI: Tailwind CSS 4, Radix UI, Geist fonts, Lucide icons
- Language: TypeScript (strict mode)
locker/
├── apps/web/ Next.js web app
│ ├── app/ Pages and API routes
│ ├── components/ UI components
│ ├── server/ tRPC routers and auth config
│ └── lib/ Utilities
├── packages/
│ ├── common/ Shared types, validation, constants
│ ├── database/ Drizzle schema and database client
│ └── storage/ Storage provider adapters
├── docker-compose.yml PostgreSQL
└── turbo.json Build pipeline
pnpm installdocker compose up -dcp .env.example .envThe defaults work out of the box for local development. Edit .env to change the storage provider or add OAuth credentials.
pnpm db:generate
pnpm db:migratepnpm devOpen http://localhost:3000, create an account, and start uploading files.
Set BLOB_STORAGE_PROVIDER in .env:
| Provider | Value | Required Env Vars |
|---|---|---|
| Local filesystem | local |
LOCAL_BLOB_DIR |
| AWS S3 | s3 |
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET |
| Cloudflare R2 | r2 |
R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET |
| Vercel Blob | vercel |
BLOB_READ_WRITE_TOKEN |
| Command | Description |
|---|---|
pnpm dev |
Start all packages in dev mode |
pnpm build |
Production build |
pnpm typecheck |
Type-check all packages |
pnpm lint |
Lint all packages |
pnpm db:generate |
Generate a new Drizzle migration |
pnpm db:migrate |
Apply pending migrations |
pnpm db:seed |
Seed the database |
pnpm format |
Format code with Prettier |
Locker includes a read-only virtual filesystem over workspace files/folders, powered by just-bash.
The shell API is available on tRPC router vfsShell:
vfsShell.createSession({ cwd? })→ create a workspace-scoped shell sessionvfsShell.exec({ sessionId, command, timeoutMs? })→ run a bash commandvfsShell.session({ sessionId })→ get sessioncwd+ expiryvfsShell.closeSession({ sessionId })→ close a session
Implementation details:
- Directory tree is bootstrapped from
folders+filesand cached in memory. - File contents are fetched lazily from the configured storage provider and cached.
- All write operations (
rm,mv, redirections, etc.) fail withEROFS(read-only filesystem). - Access is workspace-scoped and enforced by existing workspace membership checks.
MIT