A simple, self-hosted file storage/transfer app.
Scatola Magica is a privacy first, lightweight alternative to overcomplicated, bloated file storage solutions, to transfer, manage, encrypt/decrypt your personal files and folders. It's built with Next.js 14, is easy to deploy, and keeps all your data on your own server.
It features optional PGP encryption for stored items and optional AES-256-GCM encryption for file transfer. Read more about how encryption works in the howto/ENCRYPTION.md guide.
Watch a quick demo of some of the app functionality here (enable subtitles!!)
Join the discord server for more info!
- Features
- Tech Stack
- Getting Started
- Data Storage
- Versioning Scheme
- Updating
- Shortcuts
- Single Sign-On (SSO) with OIDC
- File Management: Browse, upload, download, and organize your files in a hierarchical folder structure.
- Search & Sort: Powerful search functionality and multiple sorting options for finding files quickly.
- Chunk uploader Uses chunk technology to upload files in small chunks in parallel. On a local network the upload will be as fast as your internet speed/hard drive rw speed allows.
- Drop/paste to upload This is truly a magic box (scatola magica), drag a file anywhere in any screen (yes, the settings too) and it'll upload it on the dedicated upload folder. You can even copy a file and ctrl+v into the app, I promise it will work!
- Pasting text creates a new
.txtfile automatically - Upload folders You can literally drag a folder on the screen and it'll magically upload it in the right place, with all subfolders/files within it.
- Responsive Design: Works seamlessly on desktop, tablet, and mobile devices.
- File-Based: No database needed! Everything is stored in simple files and folders in a single data directory.
- Framework: Next.js 15
- Language: TypeScript
- Styling: Tailwind CSS
The recommended way to run Scatola Magica is with Docker.
-
Create a
docker-compose.ymlfile:📖 For advanced settings and more information about how the docker compose file works and what these variables do, please read howto/DOCKER.md
services: scatola-magica: image: ghcr.io/fccview/scatola-magica:latest container_name: scatola-magica user: "1000:1000" ports: - "1133:3000" volumes: - ./uploads:/app/data/uploads:rw - ./config:/app/data/config:rw - ./cache:/app/.next/cache:rw restart: unless-stopped environment: - NODE_ENV=production
-
Create the directories and set permissions:
mkdir -p uploads/temp cache sudo chown -R 1000:1000 uploads/ sudo chown -R 1000:1000 config/ sudo chown -R 1000:1000 cache/
Note: The cache directory is optional. If you don't want cache persistence, you can comment out the cache volume line in your
docker-compose.yml. -
Start the container:
docker compose up -d
The application will be available at http://localhost:1133.
On your first visit, you'll be redirected to /auth/setup to create your admin account if SSO is disabled, otherwise you'll be prompted to sign in via your choosen SSO provider.
Once that's done, you're ready to go! First user will be admin by default.
If you want to run the app locally for development:
-
Clone & Install:
git clone <repository-url> cd scatola-magica yarn install
-
Run Dev Server:
yarn dev
The app will be running at
http://localhost:3000.
Scatola Magica uses a simple file-based storage system with the following directory structure:
uploads/: Stores all uploaded files and folders.uploads/temp/: Temporary files chunks during upload processing.config/users.json: User accounts.config/sessions.json: User session data.config/preferences.json: App preferences and settings.config/avatars/: User profile pictures.
Make sure you back up both the uploads and config directories!
This project uses a [STABLE].[FEATURE].[FIX] versioning scheme, not strict SemVer. As a product (not a package), this format makes more sense for my specific release cycle.
My format is 1.10.1, which breaks down as:
-
1.x.x(Stable): The1represents the current stable generation. I will only change this (e.g., to2.0.0) for a complete rewrite or a fundamental shift in the product or seriously breaking changes. -
x.10.x(Feature): This is the main release number. I increment this for new features, code refactors, or significant changes (e.g.,1.9.0->1.10.0). This is the equivalent of a SemVerMINORbump. -
x.x.1(Fix): This is incremented only for hotfixes, bug-fix-only and very minor feature releases (e.g.,1.10.0->1.10.1). This is the equivalent of a SemVerPATCHbump.
A Feature release (like 1.10.0) may include major backend or data structure changes. When this happens, I will always provide an automatic migration script that runs on first launch to update your data seamlessly.
Because the migration is automatic, I do not consider this a "breaking" change that requires a 2.0.0 version.
I will always detail these migrations in the release notes. I highly recommend you back up your data before any feature update, just in case.
Pull the latest image and restart your container.
docker compose pull
docker compose up -dIf you're running from source, pull the latest changes and rebuild.
git pull
yarn install
yarn build
yarn startScatola Magica supports a wide range of keyboard shortcuts to help you navigate and manage files more efficiently without leaving the keyboard.
📖 For the complete SHORTCUTS documentation, see howto/SHORTCUTS.md
Scatola Magica supports any OIDC provider (Authentik, Auth0, Keycloak, Okta, Google, EntraID, etc.)
📖 For the complete SSO documentation, see howto/SSO.md
This project is licensed under GNU LESSER GENERAL PUBLIC LICENSE. I debated going for MIT, but I really want to protect this project and keep it open source. This means private corporations can use it, but they MUST keep their improvements open source as well.
All image contents within this project are protected by Copyright and owned by The Pokémon Company. All animations for the Pokémon images have been created by the vscode-pokemon dev.
For issues and questions, please open an issue on the GitHub repository.

