I find building projects to challenge myself and learn new technologies super interesting. I've been doing this for a few years now, and Sandbox is a great representation of my accumulated experience and passion.
Taking inspiration from Replit and similar tools, I wanted to create a complete code editing platform:
The backend server is an Express.js app running a WebSockets server for real-time communication, built with Socket.io. It interfaces with the client for actions on the code editor, terminal I/O, filesystem management, and AI code generation. It also connects to the Cloudflare Workers microservices.
The frontend is a Next.js app running a WebSockets client to communicate with the backend server. Authentication is handled with Clerk, and collaborative editing is powered by Y.js and Liveblocks.
The requirements of the backend server were to:
WebSockets enable real-time two-way communication, which was perfect for this use case. After user authentication, event listeners handle operations like file fetching, folder creation, and terminal data transmission. Rate limiting is also applied to individual events.
Cloudflare Workers are serverless applications with a lot of useful features & benefits. The backend server communicates with three microservices built with this.
The database service is a SQLite database built with Cloudflare D1 and Drizzle ORM, the storage service is Cloudflare R2, and the AI service is Cloudflare Workers AI. These components are linked with service bindings, allowing workers to communicate with each other.
The project currently uses E2B for code execution, which provides a secure and isolated environment for running terminal processes; however, the project did not use this external service on initial release.
At first, the backend server ran pseudo-terminals using node-pty. It pulled project files from the storage service, and stored them in a local directory where the terminal processes were initialized. This worked, but there were some issues with isolation and security. Read more about this in the challenges section!
Building the frontend was a fun challenge, with the app being a seamless combination of various complex sections. Primitives are from shadcn/ui.
I used Monaco for the text editor, which provides a powerful and customizable code editing experience that feels just like VSCode.
A challenging feature to implement was the AI copilot, as I wanted it to be directly embedded into the editor (similar to Copilot or Cursor) and accessible via a keyboard shortcut. I also wanted a keyboard shortcut hint to display when an empty line is selected.
The Monaco Editor API documentation can be unclear, but I eventually found the solution using a combination of ViewZone and ContentWidget. The result is an inter-line space where I could add any React Component, as desired.
To display the keyboard shortcut hint, I used a DecorationsCollection with a cursor position listener attached on editor mount.
The frontend uses xterm.js for terminal rendering, supporting multiple parallel instances. User input is processed by the backend and returned immediatelyto the frontend, ensuring synchronization and enabling features like arrow keys and shortcuts.
I built the project fairly quickly, so there was naturally a lot of room for improvement on launch. Capitalizing on this, I created a bunch of GitHub issues for open-source contributors to tackle!
Unlike my other projects, Sandbox wasn't publicly deployed because of the nature of the backend server. The initial setup stored project files locally and ran pseudo-terminals, requiring a separate backend instance per user session. While scalable, this approach could get expensive.
I explored containerization with Docker and orchestration tools like ECS and Kubernetes. Though effective, security risks persisted with running pseudo-terminals locally and exposing them to clients without proper isolation. “Jailing” processes in project folders was challenging within Docker, and I chose not to continue due to time constraints.
Ultimately, the potential costs and security risks led to the decision not to deploy Sandbox publicly. Instead, I created a detailed self-hosting guide in the GitHub repository, allowing users to set up and run the project on their own.
This project was super fun to work on; I'm really proud of the craft and effort I put into it. I also spent a lot of time working on the demo video below, as well as the X thread!
P.S. Shoutout to James for contributing after the launch and making a guide for self-hosting. The concerns I had about deployment are gone since the project now uses E2B for code execution, so you can check out his forked & deployed version here!