├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public └── vite.svg ├── src ├── App.jsx ├── api.js ├── components │ ├── CodeEditor.jsx │ ├── LanguageSelector.jsx │ └── Output.jsx ├── constants.js ├── main.jsx └── theme.js └── vite.config.js /README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | An in-browser code editor that allows you to write and execute your code in the browser. 4 | 5 | ## Run Locally 6 | 7 | ```bash 8 | # install dependencies 9 | 10 | npm install 11 | 12 | # start the dev server 13 | 14 | npm run dev 15 | ``` 16 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-code-editor", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@chakra-ui/react": "^2.8.2", 14 | "@emotion/react": "^11.11.3", 15 | "@emotion/styled": "^11.11.0", 16 | "@monaco-editor/react": "^4.6.0", 17 | "axios": "^1.6.7", 18 | "framer-motion": "^11.0.3", 19 | "react": "^18.2.0", 20 | "react-dom": "^18.2.0" 21 | }, 22 | "devDependencies": { 23 | "@types/react": "^18.2.43", 24 | "@types/react-dom": "^18.2.17", 25 | "@vitejs/plugin-react": "^4.2.1", 26 | "eslint": "^8.55.0", 27 | "eslint-plugin-react": "^7.33.2", 28 | "eslint-plugin-react-hooks": "^4.6.0", 29 | "eslint-plugin-react-refresh": "^0.4.5", 30 | "vite": "^5.0.8" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react"; 2 | import CodeEditor from "./components/CodeEditor"; 3 | 4 | function App() { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /src/api.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { LANGUAGE_VERSIONS } from "./constants"; 3 | 4 | const API = axios.create({ 5 | baseURL: "https://emkc.org/api/v2/piston", 6 | }); 7 | 8 | export const executeCode = async (language, sourceCode) => { 9 | const response = await API.post("/execute", { 10 | language: language, 11 | version: LANGUAGE_VERSIONS[language], 12 | files: [ 13 | { 14 | content: sourceCode, 15 | }, 16 | ], 17 | }); 18 | return response.data; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/CodeEditor.jsx: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from "react"; 2 | import { Box, HStack } from "@chakra-ui/react"; 3 | import { Editor } from "@monaco-editor/react"; 4 | import LanguageSelector from "./LanguageSelector"; 5 | import { CODE_SNIPPETS } from "../constants"; 6 | import Output from "./Output"; 7 | 8 | const CodeEditor = () => { 9 | const editorRef = useRef(); 10 | const [value, setValue] = useState(""); 11 | const [language, setLanguage] = useState("javascript"); 12 | 13 | const onMount = (editor) => { 14 | editorRef.current = editor; 15 | editor.focus(); 16 | }; 17 | 18 | const onSelect = (language) => { 19 | setLanguage(language); 20 | setValue(CODE_SNIPPETS[language]); 21 | }; 22 | 23 | return ( 24 | 25 | 26 | 27 | 28 | setValue(value)} 41 | /> 42 | 43 | 44 | 45 | 46 | ); 47 | }; 48 | export default CodeEditor; 49 | -------------------------------------------------------------------------------- /src/components/LanguageSelector.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Box, 3 | Button, 4 | Menu, 5 | MenuButton, 6 | MenuItem, 7 | MenuList, 8 | Text, 9 | } from "@chakra-ui/react"; 10 | import { LANGUAGE_VERSIONS } from "../constants"; 11 | 12 | const languages = Object.entries(LANGUAGE_VERSIONS); 13 | const ACTIVE_COLOR = "blue.400"; 14 | 15 | const LanguageSelector = ({ language, onSelect }) => { 16 | return ( 17 | 18 | 19 | Language: 20 | 21 | 22 | {language} 23 | 24 | {languages.map(([lang, version]) => ( 25 | onSelect(lang)} 34 | > 35 | {lang} 36 |   37 | 38 | ({version}) 39 | 40 | 41 | ))} 42 | 43 | 44 | 45 | ); 46 | }; 47 | export default LanguageSelector; 48 | -------------------------------------------------------------------------------- /src/components/Output.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import { Box, Button, Text, useToast } from "@chakra-ui/react"; 3 | import { executeCode } from "../api"; 4 | 5 | const Output = ({ editorRef, language }) => { 6 | const toast = useToast(); 7 | const [output, setOutput] = useState(null); 8 | const [isLoading, setIsLoading] = useState(false); 9 | const [isError, setIsError] = useState(false); 10 | 11 | const runCode = async () => { 12 | const sourceCode = editorRef.current.getValue(); 13 | if (!sourceCode) return; 14 | try { 15 | setIsLoading(true); 16 | const { run: result } = await executeCode(language, sourceCode); 17 | setOutput(result.output.split("\n")); 18 | result.stderr ? setIsError(true) : setIsError(false); 19 | } catch (error) { 20 | console.log(error); 21 | toast({ 22 | title: "An error occurred.", 23 | description: error.message || "Unable to run code", 24 | status: "error", 25 | duration: 6000, 26 | }); 27 | } finally { 28 | setIsLoading(false); 29 | } 30 | }; 31 | 32 | return ( 33 | 34 | 35 | Output 36 | 37 | 46 | 54 | {output 55 | ? output.map((line, i) => {line}) 56 | : 'Click "Run Code" to see the output here'} 57 | 58 | 59 | ); 60 | }; 61 | export default Output; 62 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | export const LANGUAGE_VERSIONS = { 2 | javascript: "18.15.0", 3 | typescript: "5.0.3", 4 | python: "3.10.0", 5 | java: "15.0.2", 6 | csharp: "6.12.0", 7 | php: "8.2.3", 8 | }; 9 | 10 | export const CODE_SNIPPETS = { 11 | javascript: `\nfunction greet(name) {\n\tconsole.log("Hello, " + name + "!");\n}\n\ngreet("Alex");\n`, 12 | typescript: `\ntype Params = {\n\tname: string;\n}\n\nfunction greet(data: Params) {\n\tconsole.log("Hello, " + data.name + "!");\n}\n\ngreet({ name: "Alex" });\n`, 13 | python: `\ndef greet(name):\n\tprint("Hello, " + name + "!")\n\ngreet("Alex")\n`, 14 | java: `\npublic class HelloWorld {\n\tpublic static void main(String[] args) {\n\t\tSystem.out.println("Hello World");\n\t}\n}\n`, 15 | csharp: 16 | 'using System;\n\nnamespace HelloWorld\n{\n\tclass Hello { \n\t\tstatic void Main(string[] args) {\n\t\t\tConsole.WriteLine("Hello World in C#");\n\t\t}\n\t}\n}\n', 17 | php: " 9 | 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | import { extendTheme } from "@chakra-ui/react"; 2 | 3 | const theme = extendTheme({ 4 | config: { 5 | initialColorMode: "dark", 6 | useSystemColorMode: false, 7 | }, 8 | }); 9 | export default theme; 10 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------