Sandbox
Project, 2024
SandboxSandbox
Timeline
5 Weeks, April - May 2024
Tools
Next.js
Typescript
Socket.io
Express
Cloudflare Workers
SQLite
Drizzle ORM
Overview
Sandbox is an open source, AI-powered, collaborative code editing environment.
The project has 1300 GitHub stars to date. It's been used by startups to build new products, and by coding educators to teach students.
The complete demo video is at the bottom of this page in the results section!
Check out the Github to self-host the project.

Background

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:

Code Editing
A fully-featured text editor with syntax highlighting and tabs for working with multiple files.
Terminal
Support for running and managing terminals in parallel, just like in a local environment.
Live Preview
A reloadable, collapsible panel to view the output of your code for frontend development.
Collaboration
Real-time collaboration with multiple cursors and access management options.
AI Copilot
A promptable code generation tool embedded in the editor, accessible via keyboard shortcut.
File Management
Draggable, collapsible folders, with context menu options for renaming and deleting.

Architecture

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.

Sandbox project architecture

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.

Designing the Backend

The requirements of the backend server were to:

  • Be a communication layer between the client and microservices
  • Serve project files to the client on request (caching the storage service)
  • Handle terminal I/O data

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

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.

Code Execution

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!

User Interface

Building the frontend was a fun challenge, with the app being a seamless combination of various complex sections. Primitives are from shadcn/ui.

Parts of the UI

The Editor

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.

Close-up screenshots of the AI copilot in the editor

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.

Terminal

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.

Limitations

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!

GitHub issues for open-source contributors

Why Wasn't Sandbox Deployed?

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.

Result & Takeaways

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!

Code Editing UX
The challenge of building custom functionality into the editor was really rewarding. It was also interesting to build the overall interface around the editor to create a complete code editing workspace.
Designing Systems
Designing an effective system architecture was key to the success of this project. I enjoyed working comprehensively with WebSockets, exploring Cloudflare Workers, and bringing everything together.
Container Orchestration
It was a great learning experience diving deep into containerization, AWS, and Kubernetes. Implementing auto-scaling and seeing server instances spin up and down in testing was very cool to see working.
Making Compromises
Not deploying the project was a difficult decision, but ultimately taking the approach of prioritizing self-hosting still worked great. Open mindedness to changing project requirements was important here.

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!

Ishaan Dey
Updated 1/1/2025