We've all seen them: sites like CodePen or LeetCode where you can write code and see the output instantly. As a developer, I wondered: "How hard is it to build one from scratch?"
It turns out, integrating an editor is easy, but making it actually run code (especially languages like Java or C++) is where the real fun begins.
Today, Iβm sharing how I built Next.js Monaco Editor, a platform that doesn't just edit codeβit breathes life into it.
π The Stack
- Framework: Next.js (App Router)
-
Editor:
@monaco-editor/react(The engine behind VS Code) - Styling: Tailwind CSS
- Code Execution: Local (for JS) + Piston API (for Java, C#, C++)
π The Problem: "Where does the code run?"
When I started, I faced a dilemma:
- Running locally (eval): Great for JavaScript, but what about Java or C++? You can't run those in a standard browser environment.
- Building a backend: Setting up Docker containers to safely execute untrusted code is a nightmare for a frontend-focused project.
β The Solution: A Hybrid Approach
I decided to split the execution logic to get the best of both worlds:
1. The Local Speed (JavaScript & HTML)
For JavaScript, I used a clean new Function() approach to capture console logs without re-rendering the whole app. For HTML, I implemented a Live Preview using an iframe with strict sandbox attributes to keep the main site secure.
2. The Remote Power (Java, C#, C++)
To support compiled languages, I integrated the Piston API. Itβs a high-performance code execution engine that allowed me to send code snippets and receive execution results instantly, without managing a single server.
π Clean Code vs. Spagetti
As the features grew, the page.tsx became a mess. One of my favorite parts of this project was the Refactoring Phase.
I decoupled the project into logical modules:
-
lib/api.ts: Pure logic for Piston communication. -
lib/funcs.ts: Dedicated logic for JS execution. -
lib/constants.ts: A single source of truth for language versions and starter templates.
This made the codebase so clean that adding a new language like Python or Go now takes literally 30 seconds.
π Security First
One big question was: "Can users hack my site?"
Since it's a frontend-only app, the risk is minimal, but I still implemented:
-
Iframe Sandboxing:
sandbox="allow-scripts"prevents executed HTML from stealing cookies or accessing local storage. - Client-Side Execution: Everything runs either in the user's browser or an isolated remote container.
π Takeaways
Building this project taught me that you don't always need a complex backend to create powerful tools. By leveraging great APIs and robust libraries like Monaco, you can build pro-grade developer tools right in the browser.
π Check out the Project!
I've open-sourced the entire codebase. If you find this helpful or want to use it as a template for your next project, please give it a star on GitHub! β
π GitHub Repository: next-monaco-editor
What should I add next? Python support? A dark mode toggle? Let me know in the comments!
Top comments (0)