| backend | ||
| frontend | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
| screenshot.png | ||
VRChronicles
VRChronicles is a full-stack web application designed for VRChat users to discover, catalog, and share their favorite worlds. It provides a curated platform for users to submit worlds, organize them into personal lists, and receive notifications about updates to worlds they are watching.
The platform features a modern, responsive design with light and dark themes, administrative tools for moderation, and a user-friendly interface for seamless world discovery.
✨ Features
- World Discovery: Browse, search, and filter a curated collection of VRChat worlds.
- Advanced Search: Filter worlds by name, author, tags, platform compatibility (PC & Quest), and sort results.
- User-Created Lists: Logged-in users can create public or private lists to organize worlds.
- Unlisted Worlds: Submit worlds as "hidden" entries, accessible only via direct link, allowing for private sharing.
- World Watching & Notifications: "Watch" a world to receive email notifications when it's updated on VRChat.
- Automated Info Fetching:
- Automatically populate world details (name, author, capacity, etc.) from the VRChat API during submission.
- Auto-fill world ID from VRCX screenshot metadata to streamline the submission process.
- User-Specific Notes: Add private, user-specific notes to any world for personal reminders.
- "More from Author" Section: Easily discover other worlds created by the same author.
- Theming: Switch between a clean light mode and a sleek dark mode, with preference saved to local storage.
- Admin Dashboard: A comprehensive panel for administrators to:
- Approve or refuse pending user registrations and world submissions.
- Manage user roles (User, Moderator, Admin).
- Maintain a global ban list to prevent specific worlds from being submitted.
🚀 Tech Stack
Backend
- Framework: Express.js
- Database: SQLite with Knex.js as the query builder.
- Authentication: JSON Web Tokens (JWT)
- Image Processing: Sharp for resizing and converting images to WebP format.
- Email: Nodemailer for sending email notifications.
- API Interaction: Axios for making requests to the VRChat API.
Frontend
- Framework: React with Vite
- Routing: React Router
- Styling: Tailwind CSS
- API Client: Axios with global interceptors for rate-limit handling.
- State Management: React Context API for authentication and theming.
Deployment
- Containerization: Docker & Docker Compose
- Multi-stage Dockerfile: Efficiently builds the frontend and combines it with the backend for a single, optimized production image.
🛠️ Getting Started
Production Build & Deployment (Docker)
The project is configured for easy deployment with Docker.
-
Create your production
.envfile:cp .env.example .env -
Edit the
.envfile:- Set a very long, secure, random string for
JWT_SECRET. - Configure the
MAIL_*variables with your SMTP provider's credentials.
- Set a very long, secure, random string for
-
Build and run the container:
docker-compose up --build -d
The application will be running and accessible at http://localhost:8080 (or whichever host port you configure in docker-compose.yml). The Docker entrypoint script will automatically run database migrations on container startup.
Data is persisted in volumes defined in docker-compose.yml, so your database and uploaded images will be safe across container restarts.
Local Development Setup
Prerequisites
-
Clone the repository:
git clone https://git.eidenz.moe/Eidenz/VRChronicles.git cd VRChronicles -
Backend Setup:
- Navigate to the backend directory:
cd backend - Install dependencies:
npm install - Create a
.envfile from the example:cp ../.env.example .env - Edit the
.envfile and set yourJWT_SECRET. For local development, you don't need to configure mail settings yet. - Run database migrations:
npx knex migrate:latest --knexfile knexfile.cjs --env development - Start the backend dev server:
npm run dev(This will run onhttp://localhost:3001)
- Navigate to the backend directory:
-
Frontend Setup:
- In a new terminal, navigate to the frontend directory:
cd frontend - Install dependencies:
npm install - Start the frontend dev server:
npm run dev(This will run onhttp://localhost:5173by default)
- In a new terminal, navigate to the frontend directory:
The frontend dev server is configured to proxy all /api requests to the backend server, so everything should work together seamlessly.
📝 API Endpoints
The backend exposes a RESTful API that the frontend consumes. All endpoints are prefixed with /api.
Authentication (/api/auth)
| Method | Endpoint | Access | Description |
|---|---|---|---|
POST |
/login |
Public | Authenticate a user and receive a JWT. |
GET |
/me |
Private | Get the profile information of the logged-in user. |
Worlds (/api/worlds)
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/ |
Public (Optional) | Get a paginated list of all approved/accessible worlds. Supports search & sort. |
GET |
/:vrc_world_id |
Public | Get detailed information for a single world by its VRChat ID. |
POST |
/:id/watch |
Private | Add a world to the user's watch list. |
DELETE |
/:id/watch |
Private | Remove a world from the user's watch list. |
GET |
/:vrc_world_id/watch-status |
Private | Check if the current user is watching a specific world. |
GET |
/by-author/:authorName |
Public | Get a paginated list of worlds by a specific VRChat author. |
Lists (/api/lists)
| Method | Endpoint | Access | Description |
|---|---|---|---|
POST |
/ |
Private | Create a new personal list. |
GET |
/my-lists |
Private | Get all lists created by the logged-in user. |
GET |
/:id |
Private | Get details and all worlds for a specific list. |
PUT |
/:id |
Private | Update a list's name or description. |
DELETE |
/:id |
Private | Delete an entire list. |
POST |
/:listId/worlds |
Private | Add a world to a specific list. |
DELETE |
/:listId/worlds/:vrc_id |
Private | Remove a world from a specific list. |
User Notes (/api/notes)
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/world/:worldId |
Private | Get the logged-in user's private note for a world. |
POST |
/world/:worldId |
Private | Create or update the user's note for a world. |
📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
