DEV Community

Mohamed Ibrahim
Mohamed Ibrahim

Posted on

How I Built a Multi-Language Code Playground with Next.js πŸš€

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:

  1. Running locally (eval): Great for JavaScript, but what about Java or C++? You can't run those in a standard browser environment.
  2. 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)