Skip to content

Serkanbyx/online-code-editor

</> CodeNest

CodeNest

A full-stack realtime collaborative code editor with Monaco-powered IDE, Yjs CRDT synchronization, multi-language code execution via Piston, snippet sharing with social features, and a complete admin moderation panel.

License Node.js version React 19 Express 5 MongoDB Atlas Tailwind CSS v4 Socket.io Monaco Editor Yjs CRDT Swagger PRs welcome

FeaturesScreenshotsQuick StartAPI DocsArchitecture


Features

  • Realtime Collaborative Editing — Yjs CRDT-based document synchronization over WebSocket with conflict-free concurrent editing and live cursor positions
  • Monaco Code Editor — Full VS Code editing experience with IntelliSense, syntax highlighting for 25+ languages, customizable themes, keymaps, and minimap
  • Multi-Language Code Execution — Run code in JavaScript, Python, Java, Go, Rust, C/C++, and 20+ languages via the Piston execution engine
  • Snippet Sharing Platform — Create, fork, tag, and share code snippets publicly with full-text search, filtering by language/tag, and popularity sorting
  • Collaboration Rooms — Create private or public rooms, invite participants by username, and code together with real-time presence indicators
  • Social Features — Like snippets, write threaded comments with replies, view public profiles, and report inappropriate content
  • JWT Authentication — Secure register/login flow with bcrypt password hashing, token expiry, and banned-user enforcement
  • Role-Based Admin Panel — Full moderation dashboard with user management, snippet/comment moderation, report queue resolution, and analytics
  • Customizable Preferences — Per-user editor settings (theme, font, tab size, keymap, word wrap, line numbers), appearance mode, and privacy controls
  • Swagger API Documentation — Interactive OpenAPI 3.1 docs served at /api-docs with all endpoints, schemas, and authentication flows
  • Avatar Uploads — Cloudinary-powered profile picture uploads with image optimization
  • Security Hardened — Helmet headers, CORS whitelist, tiered rate limiting, input sanitization, express-validator schemas, and mongo-sanitize

Screenshots

All screenshots are captured from the live deployment.

Landing Landing
Public snippet discovery & hero
Editor Editor
Monaco IDE with live collaboration
Snippet Detail Snippet Detail
Code view, likes & comments
Rooms Hub Rooms Hub
Create & manage collab rooms
My Snippets My Snippets
Personal snippet management
Profile Profile
Public user profile & activity
Settings Settings
Editor, appearance & privacy prefs
Admin Dashboard Admin Dashboard
Analytics & moderation overview
Admin Users Admin Users
User management & banning

Architecture

A high-level visual map of the system. Both diagrams render natively on GitHub thanks to Mermaid support.

Domain Model

How the core collections relate to each other and how real-time delivery fans out.

graph LR
  User(("User"))
  Snippet(["Snippet"])
  Comment(["Comment"])
  Like(["Like"])
  Room(["Room"])
  Report(["Report"])

  User -- "creates" --> Snippet
  User -- "writes" --> Comment
  User -- "toggles" --> Like
  User -- "owns" --> Room
  User -- "joins" --> Room
  User -- "files" --> Report
  Snippet -- "receives" --> Comment
  Comment -- "replies to" --> Comment
  Like -- "targets" --> Snippet
  Snippet -- "belongs to" --> Room
  Report -- "targets" --> Snippet
  Report -- "targets" --> Comment
Loading

Request Lifecycle

How a single browser action travels through the stack.

flowchart LR
  Browser["React 19 SPA<br/>(Vite + Tailwind v4)"]
  API["Express 5 API<br/>(REST + JWT)"]
  WS["Socket.io<br/>(presence + cursors)"]
  YJS["y-websocket<br/>(CRDT sync)"]
  DB[("MongoDB<br/>Mongoose 9")]
  CDN[("Cloudinary<br/>avatars")]
  Piston[("Piston API<br/>code execution")]

  Browser -- "Axios + JWT (Bearer)" --> API
  Browser <-. "WebSocket (JWT handshake)" .-> WS
  Browser <-. "WebSocket (JWT query)" .-> YJS
  API --> DB
  API -- "stream upload" --> CDN
  API -- "POST /execute" --> Piston
  WS -. "presence:userJoined" .-> Browser
  WS -. "cursor:update" .-> Browser
  YJS -. "CRDT doc sync" .-> Browser
Loading

Technologies

Frontend

  • React 19: Modern UI library with hooks, context, and concurrent features
  • Vite 6: Lightning-fast build tool with HMR and optimized production bundles
  • Tailwind CSS 4: Utility-first CSS framework with Vite plugin integration
  • Monaco Editor: VS Code's editor component with full language support and IntelliSense
  • Yjs + y-monaco: CRDT-based real-time collaborative editing bound to Monaco
  • Socket.io Client: Real-time presence and cursor position broadcasting
  • React Router 7: Declarative client-side routing with nested layouts and guards
  • Axios: Promise-based HTTP client with JWT interceptors
  • React Hot Toast: Lightweight toast notification system
  • clsx: Conditional className utility

Backend

  • Node.js: Server-side JavaScript runtime (ES Modules)
  • Express 5: Minimal web framework with async error handling
  • MongoDB (Mongoose 9): NoSQL database with schema validation, compound indexes, and text search
  • Socket.io 4: Real-time bidirectional communication for presence and cursor events
  • y-websocket + Yjs: WebSocket server for CRDT document synchronization
  • JSON Web Token (JWT): Stateless authentication with configurable expiry
  • bcrypt: Password hashing with salt rounds
  • Piston API: Sandboxed multi-language code execution proxy
  • Cloudinary: Cloud-based image upload and optimization
  • Swagger UI Express: Interactive OpenAPI 3.1 documentation
  • Helmet: HTTP security headers
  • express-rate-limit: Tiered rate limiting (global, auth, code-run, write, admin)
  • express-validator: Request payload validation with custom sanitizers
  • express-mongo-sanitize: NoSQL injection prevention
  • Multer: Multipart file upload handling
  • Morgan: HTTP request logging

Installation

Prerequisites

  • Node.js v20+ and npm
  • MongoDB — MongoDB Atlas (free tier) or local instance
  • Cloudinary account (optional, for avatar uploads)

Local Development

1. Clone the repository:

git clone https://github.com/Serkanbyx/codenest.git
cd codenest

2. Set up environment variables:

cp server/.env.example server/.env
cp client/.env.example client/.env

server/.env

NODE_ENV=development
PORT=5000

MONGO_URI=mongodb://127.0.0.1:27017/codenest

JWT_SECRET=your_super_secret_key_here
JWT_EXPIRES_IN=7d

CORS_ORIGIN=http://localhost:5173

PISTON_BASE_URL=https://emkc.org/api/v2/piston

CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

ADMIN_EMAIL=[email protected]
ADMIN_PASSWORD=your_admin_password

MAX_CODE_PAYLOAD_KB=64

client/.env

VITE_API_URL=http://localhost:5000/api
VITE_SOCKET_URL=http://localhost:5000
VITE_YJS_URL=ws://localhost:5000

3. Install dependencies:

cd server && npm install
cd ../client && npm install

4. Seed the admin user:

cd server && npm run seed

5. Run the application:

# Terminal 1 — Backend
cd server && npm run dev

# Terminal 2 — Frontend
cd client && npm run dev

The API will be available at http://localhost:5000 and the client at http://localhost:5173.


Usage

  1. Register — Create a new account with username, email, and password
  2. Login — Authenticate and receive a JWT for protected actions
  3. Explore Snippets — Browse public snippets on the homepage, filter by language or tags
  4. Create a Snippet — Write code in the editor and save as public or private snippet
  5. Fork a Snippet — Clone any public snippet to your own collection and modify it
  6. Create a Room — Start a collaboration room and invite participants by username
  7. Code Together — Edit code simultaneously with live cursors and presence indicators
  8. Run Code — Execute code in 25+ languages directly from the editor
  9. Interact — Like snippets, write comments, and report inappropriate content
  10. Customize — Adjust editor theme, font, keymap, and privacy settings
  11. Admin Panel — Moderators can manage users, review reports, and moderate content

How It Works?

Authentication Flow

The app uses stateless JWT authentication. On login, the server issues a signed token containing the user ID. The client stores the token in memory and attaches it as a Bearer header on every subsequent API request.

// Axios interceptor attaches JWT automatically
axiosInstance.interceptors.request.use((config) => {
  const token = getStoredToken();
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

Real-Time Collaboration

Collaboration is powered by two parallel WebSocket channels:

  1. Socket.io — Handles room presence (join/leave events) and cursor position broadcasting with token-bucket throttling (20 events/sec).
  2. y-websocket (Yjs) — Manages the CRDT document state. Each room maps to a Yjs document that synchronizes edits conflict-free across all connected clients via y-monaco bindings.
// y-websocket upgrade path: /yjs/{roomId}?token=JWT
// Socket.io path: /socket.io (with JWT in handshake auth)

Code Execution

Code execution is proxied through the Piston API. The server validates the language against a supported list, resolves the latest runtime version, and forwards the code payload. Results (stdout, stderr, exit code) are returned to the client.

Admin Moderation

The admin panel uses role-based access control (adminOnly middleware). Admins can view dashboard statistics, manage user roles/bans, moderate snippets/comments (active → hidden → removed), and resolve user reports with configurable actions (noop, hide, remove, ban).


API Endpoints

Full interactive documentation is available at /api-docs (Swagger UI).

Auth

Method Endpoint Auth Description
POST /api/auth/register No Create a new user
POST /api/auth/login No Login and receive JWT
GET /api/auth/me Yes Get current user profile
PATCH /api/auth/me Yes Update profile (displayName, bio, avatar)
PATCH /api/auth/password Yes Change password
DELETE /api/auth/me Yes Delete account

Snippets

Method Endpoint Auth Description
POST /api/snippets Yes Create a snippet
GET /api/snippets/me Yes List own snippets (paginated)
GET /api/snippets/public Optional Explore public snippets with filters
GET /api/snippets/:id Optional Read a single snippet
PATCH /api/snippets/:id Yes Update a snippet
DELETE /api/snippets/:id Yes Delete a snippet
POST /api/snippets/:id/fork Yes Fork a public snippet

Rooms

Method Endpoint Auth Description
POST /api/rooms Yes Create a collaboration room
GET /api/rooms/me Yes List own/joined rooms
GET /api/rooms/:roomId Optional Read room details
POST /api/rooms/:roomId/join Yes Join a room
POST /api/rooms/:roomId/leave Yes Leave a room
POST /api/rooms/:roomId/participants Yes Add participant by username
PATCH /api/rooms/:roomId Yes Update room settings
DELETE /api/rooms/:roomId Yes Delete a room

Code Execution

Method Endpoint Auth Description
GET /api/code/runtimes Optional List supported runtimes
POST /api/code/run Yes Execute code (rate limited: 8/min)

Comments

Method Endpoint Auth Description
GET /api/comments/snippet/:snippetId Optional List snippet comments
GET /api/comments/:commentId/replies Optional List comment replies
POST /api/comments Yes Create a comment or reply
PATCH /api/comments/:id Yes Update a comment
DELETE /api/comments/:id Yes Soft-delete a comment

Likes

Method Endpoint Auth Description
POST /api/likes/:snippetId Yes Toggle like on a snippet
GET /api/likes/me Yes List liked snippets
GET /api/likes/:snippetId/me Yes Check like state

Profiles

Method Endpoint Auth Description
PATCH /api/profile/me/preferences Yes Update preferences
GET /api/profile/:username Optional Read public profile
GET /api/profile/:username/snippets Optional List profile snippets
GET /api/profile/:username/likes Optional List profile likes
GET /api/profile/:username/comments Optional List profile comments

Reports

Method Endpoint Auth Description
POST /api/reports Yes Create a moderation report
GET /api/reports/me Yes List own reports

Admin

Method Endpoint Auth Description
GET /api/admin/stats Admin Dashboard statistics
GET /api/admin/users Admin List all users
GET /api/admin/users/:id Admin User details
PATCH /api/admin/users/:id/role Admin Update user role
PATCH /api/admin/users/:id/ban Admin Ban/unban user
DELETE /api/admin/users/:id Admin Delete user
GET /api/admin/snippets Admin List snippets for moderation
PATCH /api/admin/snippets/:id/status Admin Moderate snippet status
DELETE /api/admin/snippets/:id Admin Hard-delete snippet
GET /api/admin/comments Admin List comments for moderation
PATCH /api/admin/comments/:id/status Admin Moderate comment status
GET /api/admin/reports Admin List report queue
PATCH /api/admin/reports/:id Admin Resolve/dismiss a report

Uploads

Method Endpoint Auth Description
POST /api/upload/avatar Yes Upload avatar (multipart)

All protected endpoints require Authorization: Bearer <token> header. Rate limits vary by tier: global (300/15min), auth (10/15min), code-run (8/min), write (30/min), admin (60/15min).


Project Structure

A clean monorepo layout with an explicit backend / frontend split. Each panel below is collapsible — expand the one you care about.

Server — Express 5 API + Socket.io + y-websocket
server/
├── config/          # env validation, db connection, swagger spec
├── controllers/     # auth, snippet, room, code, comment, like, report, admin, profile, upload
├── middleware/      # auth (protect/optionalAuth/adminOnly), rateLimiters, validate, sanitize, upload, errorHandler, notFound, socketAuth
├── models/          # User, Snippet, Room, Comment, Like, Report (Mongoose schemas)
├── routes/          # one file per resource group (10 route files)
├── scripts/         # seedAdmin.js, migrateSnippetIndexes.js
├── sockets/         # Socket.io init, presenceHandlers, cursorHandlers, yjsServer, socketUtils
├── utils/           # ApiError, generateToken, pistonClient, cloudinary, constants, escapeRegex
├── validators/      # express-validator schemas per resource (8 validator files)
├── index.js         # Express app composition, HTTP server, Socket.io + Yjs attach
├── .env.example
└── package.json
Client — React 19 + Vite 6 SPA
client/
├── public/              # static assets
├── src/
│   ├── api/             # Axios instance + 11 service modules (auth, snippet, room, code, comment, like, report, admin, profile, upload)
│   ├── components/
│   │   ├── auth/        # AuthCard, PasswordField, PasswordStrengthMeter
│   │   ├── common/      # Avatar, Spinner, FormField, ConfirmModal, Skeleton, EmptyState, ToggleSwitch, RoleBadge, StatusBadge…
│   │   ├── editor/      # MonacoPane, EditorToolbar, LanguageSelect, OutputPanel, UserListSidebar, SaveSnippetModal
│   │   ├── layout/      # Navbar, Footer
│   │   └── snippets/    # SnippetCard, SnippetGrid, SnippetFilters, CommentThread, CommentItem
│   ├── context/         # AuthContext, SocketContext, PreferencesContext
│   ├── hooks/           # useYjsRoom, useSocket, useDebounce, useLocalStorage, useCopyToClipboard, useGuestId
│   ├── layouts/         # MainLayout, AdminLayout, SettingsLayout
│   ├── pages/
│   │   ├── admin/       # AdminDashboardPage, AdminUsersPage, AdminSnippetsPage, AdminCommentsPage, AdminReportsPage
│   │   ├── auth/        # LoginPage, RegisterPage
│   │   ├── home/        # HomePage
│   │   ├── misc/        # NotFoundPage, ForbiddenPage
│   │   ├── profile/     # ProfilePage
│   │   ├── rooms/       # RoomsHubPage, EditorPage
│   │   ├── settings/    # ProfileSettingsPage, AccountSettingsPage, AppearanceSettingsPage, EditorSettingsPage, PrivacySettingsPage, NotificationsSettingsPage
│   │   └── snippets/    # SnippetDetailPage, EditSnippetPage, MySnippetsPage
│   ├── routes/          # ProtectedRoute, AdminRoute, GuestOnlyRoute
│   ├── App.jsx          # router + providers + scroll-to-top
│   └── main.jsx         # entry point
├── .env.example
└── package.json
Repository root — docs, governance & shared assets
codenest/
├── client/              # → see Client panel above
├── server/              # → see Server panel above
├── docs/                # build-guide.md
├── assets/              # screenshots/
├── .github/
│   ├── ISSUE_TEMPLATE/  # bug_report.yml, feature_request.yml, config.yml
│   └── PULL_REQUEST_TEMPLATE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
└── README.md

Security

  • Helmet — Sets strict HTTP security headers (CSP, HSTS, X-Frame-Options, etc.)
  • CORS Whitelist — Only the configured client origin can access the API
  • Tiered Rate Limiting — Global, auth, code-run, write, and admin rate limiters with draft-7 standard headers
  • JWT Authentication — Signed tokens with configurable expiry, Bearer scheme enforcement
  • bcrypt Hashing — Passwords hashed with 12 salt rounds, never stored in plaintext
  • Input Validation — All request bodies validated via express-validator schemas before reaching controllers
  • Mongo Sanitize — Prevents NoSQL injection by stripping $ and . from user input
  • Payload Limits — JSON body size capped at 64KB (96KB for code execution)
  • Socket Authentication — WebSocket connections require valid JWT in handshake/query params
  • Cursor Throttling — Token-bucket rate limiting on cursor events (20/sec) to prevent flooding
  • Banned User Enforcement — Banned users are rejected at both HTTP and WebSocket layers
  • Sensitive Field Stripping — Password and internal fields are never exposed in API responses

Deployment

Backend (Render)

1. Create a new Web Service on Render:

Setting Value
Root Directory server
Build Command npm install
Start Command npm start
Environment Node

2. Add environment variables:

Variable Value
NODE_ENV production
PORT 5000
MONGO_URI Your MongoDB Atlas connection string
JWT_SECRET A strong random secret
JWT_EXPIRES_IN 7d
CORS_ORIGIN Your Netlify deployment URL
PISTON_BASE_URL https://emkc.org/api/v2/piston
CLOUDINARY_CLOUD_NAME Your Cloudinary cloud name
CLOUDINARY_API_KEY Your Cloudinary API key
CLOUDINARY_API_SECRET Your Cloudinary API secret

Frontend (Netlify)

1. Create a new site on Netlify:

Setting Value
Base Directory client
Build Command npm run build
Publish Directory client/dist

2. Add environment variables:

Variable Value
VITE_API_URL https://your-api.onrender.com/api
VITE_SOCKET_URL https://your-api.onrender.com
VITE_YJS_URL wss://your-api.onrender.com

3. Add a _redirects file for SPA routing:

/*    /index.html   200

Important: Make sure CORS_ORIGIN in the backend matches your Netlify URL exactly (no trailing slash).


Features in Detail

Completed Features

✅ JWT-based authentication (register, login, password change, account deletion) ✅ Monaco Editor with full language support and customizable settings ✅ Real-time collaborative editing via Yjs CRDT over WebSocket ✅ Live cursor positions and presence indicators via Socket.io ✅ Multi-language code execution (25+ languages) via Piston ✅ Snippet CRUD with public/private visibility and tagging ✅ Snippet forking with lineage tracking ✅ Full-text search across snippets (title, description, tags) ✅ Threaded comments with nested replies ✅ Like/unlike toggle with aggregated counts ✅ Public user profiles with activity feeds ✅ Collaboration rooms with participant management ✅ Room language switching (owner-only) ✅ Avatar upload via Cloudinary ✅ Admin dashboard with aggregate statistics ✅ User management (role assignment, banning) ✅ Content moderation (snippets, comments) ✅ Report queue with resolution actions ✅ Customizable editor preferences (theme, font, keymap, etc.) ✅ Privacy settings (show/hide email, likes, comments) ✅ Protected and admin-only routes ✅ Swagger/OpenAPI documentation ✅ Tiered rate limiting ✅ Security hardening (Helmet, sanitize, CORS, etc.)

Future Features

  • 🔮 Email verification and password reset flow
  • 🔮 OAuth integration (GitHub, Google)
  • 🔮 Real-time notifications via WebSocket
  • 🔮 Snippet version history and diff view
  • 🔮 Room chat sidebar
  • 🔮 File-based projects (multi-file editor)
  • 🔮 Embedded snippet sharing (iframe/embed code)
  • 🔮 AI-powered code suggestions
  • 🔮 Dark/light theme toggle with system preference sync

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/amazing-feature
  3. Commit your changes following the convention below
  4. Push to the branch: git push origin feat/amazing-feature
  5. Open a Pull Request using the provided PR template

Commit Message Convention

Prefix Description
feat: New feature
fix: Bug fix
refactor: Code refactoring
docs: Documentation changes
style: Code style (formatting, no logic change)
chore: Maintenance and dependency updates
test: Adding or updating tests

License

This project is licensed under the MIT License — see the LICENSE file for details.


Developer

Serkan Bayraktar


Acknowledgments

  • Monaco Editor — VS Code's powerful editor component
  • Yjs — CRDT framework for real-time collaboration
  • Piston — Sandboxed code execution engine
  • Socket.io — Real-time bidirectional event-based communication
  • Tailwind CSS — Utility-first CSS framework
  • Express.js — Fast, unopinionated web framework
  • Cloudinary — Image upload and optimization service

Contact


⭐ If you like this project, don't forget to give it a star!

About

CodeNest is a full-stack online code editor with realtime collaboration, snippet sharing, secure code execution, and a modern MERN-style architecture. Built with React 19, Express 5, MongoDB, Socket.io, Yjs, and Monaco Editor.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages