A modern web platform for sharing and downloading multi-track music files. Wavtopia allows you to upload tracker music files (.xm, .it, .s3m, .mod formats) and automatically converts them into individual WAV stems and a full track WAV file.
- Track Management: Upload, manage, and share your music tracks
- Audio Conversion: Automatic conversion of .xm, .it, .s3m, and .mod files to WAV format
- Stem Extraction: Split tracks into individual instrument stems
- Multi-format Downloads:
- Download the original tracker file (.xm, .it, .s3m, .mod)
- Download the full track as WAV
- Download individual instrument stems as WAV
- Real-time Playback: Play and preview tracks directly in the browser
- Modern UI: Responsive design that works on desktop and mobile
- Secure Access: User authentication and personal track management
- Frontend: React, TypeScript, Vite, TailwindCSS, Tone.js
- Backend: Node.js, Express, TypeScript, Prisma
- Database: PostgreSQL
- Storage: MinIO/S3
- Audio Processing: FFmpeg, libxmp
- Node.js >= 18
- pnpm >= 8
- PostgreSQL >= 14
- FFmpeg
- libxmp
- MinIO (for local development) or S3-compatible storage
- milkycli utility (see below)
- schismtracker application (see below)
The project requires the milkycli utility from MilkyTracker for converting XM files to WAV format. This utility is included as a git submodule from this open pull request.
When cloning the repository, make sure to initialize the submodules:
# If cloning for the first time:
git clone --recursive https://github.com/your-repo/wavtopia.git
# If you've already cloned the repository:
git submodule update --init --recursive
# Pulling dependency changes into this repo:
git submodule update --remote
git add packages/media/deps/milkytracker packages/media/deps/schismtracker && git commitThe media service's Dockerfile will automatically build and install both the milkycli utility and Schism Tracker during container build.
Note: MilkyTracker submodule is a temporary requirement until PR #372 is merged into MilkyTracker's main branch.
Schism Tracker is used for additional module file format support and conversion. The media service's Docker image builds Schism Tracker from source to support multiple architectures.
For local development, you can install it:
# Build from source (same as Docker)
git clone https://github.com/schismtracker/schismtracker.git
cd schismtracker
git checkout 20250208
autoreconf -i
mkdir -p build && cd build
../configure
make
sudo cp schismtracker /usr/local/bin/- Install system dependencies:
# macOS
brew install ffmpeg libxmp
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install ffmpeg libxmp4- Install project dependencies:
pnpm install- Set up environment variables:
# Copy example env files
cp packages/backend/.env.example packages/backend/.env
cp packages/frontend/.env.example packages/frontend/.env
# Edit the .env files with your configuration- Set up MinIO:
# Install MinIO (macOS)
brew install minio/stable/minio
# Start MinIO server
minio server ~/minio --console-address :9001
# Create a bucket named 'wavtopia' using the MinIO Console (http://localhost:9001)
# Default credentials: minioadmin/minioadmin- Initialize the database:
# Set up the database schema and run migrations
pnpm db:setup
# Create an admin user and enable required feature flags
pnpm db:bootstrap- Start development servers:
# Start all services
pnpm dev
# Or start services individually:
cd packages/frontend && pnpm dev
cd packages/backend && pnpm devThe scripts/ directory contains several utility scripts:
deploy.sh: Main deployment script with several commands:setup-remote: Configure remote Docker context and registry for deploymentdeploy-prod: Deploy all services to productionbootstrap-prod: Bootstrap the production database with an admin user- Run
./scripts/deploy.sh --helpfor all available commands
apply-arch-lockfile.sh: Applies architecture-specific lockfile for better dependency managementupdate-arch-lockfile.sh: Updates the architecture-specific lockfiledistribute-env.sh: Distributes environment variables to package-specific .env files:- Takes a source .env file and creates package-specific versions
- Only includes variables used by each package's config.ts
- Usage:
./scripts/distribute-env.sh .env.docker
The project includes several database-related commands:
pnpm db:setup: Initialize the database schema and run migrationspnpm db:bootstrap: Create an admin user and set up required feature flags- Can be run with arguments:
-u <username> -e <email> -p <password> - Will prompt for missing values if not provided
- Can be run with arguments:
./scripts/deploy.sh bootstrap-prod: Bootstrap the production database (must runsetup-remotefirst)
The project supports both local development and containerized services using Docker Compose profiles:
For local development, you can run core dependencies (PostgreSQL, MinIO, Redis) while developing services locally:
# Start core dependencies
docker compose --profile development up -d
# Then run services locally:
cd packages/media && pnpm dev
# Or run all services locally:
pnpm devServices will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:3002
- Media Service: http://localhost:3001 (when running locally)
- PostgreSQL: localhost:5432
- MinIO: localhost:9000 (API) and localhost:9001 (Console)
- Redis: localhost:6379
For running services in containers:
# Build the workspace (required for media service)
docker compose --profile build build workspace
# Run specific services (e.g., media service)
docker compose --profile production up media
# Run all production services (including core dependencies)
docker compose --profile production upAvailable profiles:
build: For building service containersproduction: For running production-ready servicesdevelopment: For running development dependencies (database, storage, cache)
Each service has its own Dockerfile and can be configured via environment variables. See .env.docker.example for available options.
wavtopia/
├── packages/
│ ├── frontend/ # React frontend application
│ │ ├── src/ # Source files
│ │ └── public/ # Static assets
│ │
│ └── backend/ # Express backend application
│ ├── src/ # Source files
│ └── prisma/ # Database schema and migrations
│
└── README.md # This file
The backend provides the following main endpoints:
POST /api/auth/signup- Create a new user accountPOST /api/auth/login- Log in to existing accountGET /api/auth/me- Get current user info
POST /api/track- Upload a new trackGET /api/track/:id- Get track detailsPATCH /api/track/:id- Update track detailsDELETE /api/track/:id- Delete a trackGET /api/track/:id/original- Download file in original formatGET /api/track/:id/full- Download full track WAVGET /api/track/:id/stem/:stemId- Download stem WAV
GET /api/tracks- List all tracks owned by the current userGET /api/tracks/public- List all public tracksGET /api/tracks/shared- List all tracks shared with the current userGET /api/tracks/available- List all tracks that are accessible to the current user
-
"No token provided" error when downloading
- Make sure you're logged in
- Try logging out and back in
- Check that your token is being stored correctly in localStorage
-
File upload fails
- Check that your file is in a supported format (xm, it, mod)
- Ensure the file size is under 50MB
- Verify MinIO is running and accessible
-
Audio playback issues
- Click anywhere on the page first (browser autoplay policy)
- Check that your browser supports the Web Audio API
- Verify the track has finished processing
Make sure your .env files contain the following variables:
# packages/backend/.env
DATABASE_URL="postgresql://user:password@localhost:5432/wavtopia"
JWT_SECRET="your-secret-key"
MINIO_ENDPOINT="localhost"
MINIO_PORT="9000"
MINIO_USER="minioadmin"
MINIO_PASSWORD="minioadmin"
MINIO_BUCKET="wavtopia"
MILKYCLI_PATH="/usr/local/bin/milkycli"
# packages/frontend/.env
VITE_API_URL="http://localhost:3002"MIT