> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser-Based Code Editor

> Build a StackBlitz-style browser IDE with client-server architecture, file operations via API, hot reload patterns, and package management

Build a production-ready browser-based code editor that runs entirely in the browser with a backend API. This cookbook demonstrates how to create a platform similar to StackBlitz or CodeSandbox using HopX.

## Overview

Browser-based code editors provide a full IDE experience in the browser. The frontend handles editing, and the backend manages file operations, code execution, and package management through APIs.

## Prerequisites

* HopX API key ([Get one here](https://console.hopx.dev/api-keys))
* Python 3.8+ or Node.js 16+
* Understanding of client-server architecture
* Basic knowledge of web APIs

## Architecture

```
┌──────────────┐
│  Browser     │ Editor UI
└──────┬───────┘
       │ HTTP/WebSocket
       ▼
┌─────────────────┐
│  Editor Backend │ File ops, execution
└──────┬──────────┘
       │
       ▼
┌─────────────────┐
│  HopX Sandbox   │ Secure execution
└─────────────────┘
```

## Implementation

### Step 1: File Operations API

Provide file operations via API:

<CodeGroup>
  ```python Python theme={null}
  from hopx_ai import Sandbox
  import os
  from typing import Dict, Any

  class EditorBackend:
      def __init__(self, api_key: str):
          self.api_key = api_key
          self.sandbox = None
      
      def initialize_project(self, project_id: str) -> Dict[str, Any]:
          """Initialize editor project"""
          self.sandbox = Sandbox.create(
              template="code-interpreter",
              api_key=self.api_key,
              timeout_seconds=3600
          )
          
          self.sandbox.files.mkdir("/workspace/project")
          
          return {
              "success": True,
              "project_id": project_id,
              "sandbox_id": self.sandbox.sandbox_id
          }
      
      def handle_file_request(self, method: str, path: str, content: str = None) -> Dict[str, Any]:
          """Handle file operation requests"""
          full_path = f"/workspace/project{path}"
          
          if method == "GET":
              # Read file
              try:
                  content = self.sandbox.files.read(full_path)
                  return {"success": True, "content": content}
              except Exception as e:
                  return {"success": False, "error": str(e)}
          
          elif method == "PUT":
              # Write file
              try:
                  self.sandbox.files.write(full_path, content)
                  return {"success": True, "path": path}
              except Exception as e:
                  return {"success": False, "error": str(e)}
          
          elif method == "DELETE":
              # Delete file
              try:
                  self.sandbox.files.remove(full_path)
                  return {"success": True, "path": path}
              except Exception as e:
                  return {"success": False, "error": str(e)}
          
          elif method == "LIST":
              # List directory
              try:
                  files = self.sandbox.files.list(full_path)
                  return {
                      "success": True,
                      "files": [
                          {
                              "name": f.name,
                              "path": f.path,
                              "is_dir": f.is_dir,
                              "size": f.size
                          }
                          for f in files
                      ]
                  }
              except Exception as e:
                  return {"success": False, "error": str(e)}
          
          return {"success": False, "error": f"Unknown method: {method}"}
      
      def cleanup(self):
          """Clean up editor resources"""
          if self.sandbox:
              self.sandbox.kill()
              self.sandbox = None

  # Usage
  backend = EditorBackend(api_key=os.getenv("HOPX_API_KEY"))
  backend.initialize_project("my-project")

  # File operations
  result = backend.handle_file_request("PUT", "/app.js", "console.log('Hello');")
  print(result)

  result = backend.handle_file_request("GET", "/app.js")
  print(result)

  backend.cleanup()
  ```

  ```javascript JavaScript theme={null}
  import { Sandbox } from '@hopx-ai/sdk';

  class EditorBackend {
      constructor(apiKey) {
          this.apiKey = apiKey;
          this.sandbox = null;
      }
      
      async initializeProject(projectId) {
          this.sandbox = await Sandbox.create({
              template: 'code-interpreter',
              apiKey: this.apiKey,
              timeoutSeconds: 3600
          });
          
          await this.sandbox.files.mkdir('/workspace/project');
          
          return {
              success: true,
              projectId,
              sandboxId: this.sandbox.sandboxId
          };
      }
      
      async handleFileRequest(method, path, content = null) {
          const fullPath = `/workspace/project${path}`;
          
          if (method === 'GET') {
              try {
                  const fileContent = await this.sandbox.files.read(fullPath);
                  return { success: true, content: fileContent };
              } catch (error) {
                  return { success: false, error: error.message };
              }
          } else if (method === 'PUT') {
              try {
                  await this.sandbox.files.write(fullPath, content);
                  return { success: true, path };
              } catch (error) {
                  return { success: false, error: error.message };
              }
          } else if (method === 'DELETE') {
              try {
                  await this.sandbox.files.remove(fullPath);
                  return { success: true, path };
              } catch (error) {
                  return { success: false, error: error.message };
              }
          } else if (method === 'LIST') {
              try {
                  const files = await this.sandbox.files.list(fullPath);
                  return {
                      success: true,
                      files: files.map(f => ({
                          name: f.name,
                          path: f.path,
                          isDir: f.isDir,
                          size: f.size
                      }))
                  };
              } catch (error) {
                  return { success: false, error: error.message };
              }
          }
          
          return { success: false, error: `Unknown method: ${method}` };
      }
      
      async cleanup() {
          if (this.sandbox) {
              await this.sandbox.kill();
              this.sandbox = null;
          }
      }
  }

  // Usage
  const backend = new EditorBackend(process.env.HOPX_API_KEY);
  await backend.initializeProject('my-project');

  // File operations
  const result1 = await backend.handleFileRequest('PUT', '/app.js', "console.log('Hello');");
  console.log(result1);

  const result2 = await backend.handleFileRequest('GET', '/app.js');
  console.log(result2);

  await backend.cleanup();
  ```
</CodeGroup>

## Best Practices

1. **API Design**: Design RESTful APIs for file operations
2. **Hot Reload**: Implement file watching for live updates
3. **Package Management**: Support npm, pip, etc.
4. **Error Handling**: Provide clear error messages

## Related Cookbooks

* [Cloud-Based IDE Backend](/cookbooks/development/cloud-ide-backend) - Full IDE backend

## Next Steps

1. Implement WebSocket for real-time updates
2. Add package installation support
3. Create frontend editor interface
4. Implement hot reload functionality
5. Add collaboration features
