notjs-react
v0.6.0
Published
A React component for interactive code execution for C,C++,Java, Go and Rust
Maintainers
Readme
notjs-react
A React component for interactive code playgrounds with real-time WebSocket terminal support. Built with Monaco Editor and xterm.js.
NotJS is a backend (Spring Boot) and React library for code playgrounds for compiled languages. It's intended to be used mainly on blogs where you want to demo language features. This is the React library component that connects to a NotJS server.
Prerequisites
NotJS Server Required: This component requires a NotJS server to handle code execution. You can self-host the server by following the instructions at https://github.com/cholnhial/notjs
Supported Languages
- Java (versions 8, 11, 17, 21, 25)
- C (C89, C99, C11, C17, C23)
- C++ (C++98, C++11, C++14, C++17, C++20, C++23)
- Go (version 1.19.8)
- Rust (version 1.63.0)
Installation
npm install notjs-reactUsage
import { NotJS } from 'notjs-react'
import 'notjs-react/styles.css'
function App() {
return (
<NotJS
apiBaseUrl="http://localhost:8080/api"
websocketUrl="ws://localhost:8080/terminal"
initialLanguage="java"
initialVersion="25"
initialDarkMode={true}
/>
)
}Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| apiBaseUrl | string | "http://localhost:8080/api" | Base URL for the API |
| websocketUrl | string | "ws://localhost:8080/terminal" | WebSocket endpoint URL |
| initialLanguage | string | "java" | Initial programming language |
| initialVersion | string | "25" | Initial language version |
| initialDarkMode | boolean | true | Enable dark mode by default |
| initialCode | string | (language default) | Custom starting code |
| hideHeader | boolean | false | Hide header for embedding |
| editorWidthPercent | number | 50 | Initial editor width as percentage (20-80) |
Features
- 🎨 Monaco Editor integration for code editing
- 💻 Real-time terminal with xterm.js
- 🌓 Dark/Light mode support
- 📋 Copy code and console output
- ↔️ Resizable editor/console panels
- 🔌 WebSocket-based code execution
- 🎯 TypeScript support
- 📦 Zero configuration required
Examples
Basic Usage
import { NotJS } from 'notjs-react'
import 'notjs-react/styles.css'
function MyBlogPost() {
return (
<div>
<h1>Java Records Tutorial</h1>
<p>Here's an example of Java records:</p>
<NotJS
apiBaseUrl="https://your-notjs-api.com/api"
websocketUrl="wss://your-notjs-api.com/terminal"
initialLanguage="java"
initialVersion="21"
initialCode={`public record Person(String name, int age) {}
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println(person);
}
}`}
/>
</div>
)
}Embedding in MDX
Perfect for use in blog posts written with MDX:
import { NotJS } from 'notjs-react'
import 'notjs-react/styles.css'
# Learning Rust
Try out this Rust example:
<NotJS
apiBaseUrl="https://your-notjs-api.com/api"
websocketUrl="wss://your-notjs-api.com/terminal"
initialLanguage="rust"
initialCode={`fn main() {
println!("Hello from Rust!");
}`}
/>Minimal Embedded View
Hide the header for a cleaner embedded experience:
<NotJS
apiBaseUrl="https://your-notjs-api.com/api"
websocketUrl="wss://your-notjs-api.com/terminal"
initialLanguage="cpp"
hideHeader={true}
initialCode={`#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}`}
/>Troubleshooting
CSS Styling Issues in Frameworks (Astro, Next.js, etc.)
Although NotJS includes self-contained CSS, some frameworks may experience styling issues due to CSS purging/tree-shaking. The terminal styles (xterm.js) are added dynamically at runtime, so build tools may incorrectly remove them as "unused."
Symptoms
- Terminal appears with white/blank background
- Terminal resizing doesn't work
- Missing terminal UI elements
Solution: Wrapper Component (Recommended)
Create a wrapper component with explicit dimensions and always import the CSS in the wrapper:
// components/NotJSWrapper.tsx
import { NotJS } from 'notjs-react'
import 'notjs-react/styles.css' // Critical: Import styles here
export function NotJSWrapper({ width = '100%', height = '600px', ...props }) {
return (
<div style={{ width, height }}>
<NotJS {...props} />
</div>
)
}Then use the wrapper in your MDX/pages:
import { NotJSWrapper } from '@/components/NotJSWrapper'
# My Blog Post
<NotJSWrapper
width="100%"
height="500px"
apiBaseUrl="https://your-api.com/api"
websocketUrl="wss://your-api.com/terminal"
initialLanguage="java"
/>Important: The CSS import (import 'notjs-react/styles.css') must be in the wrapper component file, not just in your page/MDX file. This ensures the styles are properly bundled and not purged by the build process.
Development
To develop the library locally:
- Clone the repository:
git clone https://github.com/cholnhial/notjs
cd notjs/packages/notjs-react- Install dependencies:
npm install- Build the library in watch mode:
npm run dev- Link the library for local testing:
npm link- In your test project:
npm link notjs-reactAPI
Component Props
The NotJS component accepts the following props:
apiBaseUrl (optional)
- Type:
string - Default:
"http://localhost:8080/api" - Description: Base URL for the NotJS API server
websocketUrl (optional)
- Type:
string - Default:
"ws://localhost:8080/terminal" - Description: WebSocket endpoint URL for real-time communication
initialLanguage (optional)
- Type:
"java" | "c" | "cpp" | "go" | "rust" - Default:
"java" - Description: Programming language to start with
initialVersion (optional)
- Type:
string - Default:
"25"(for Java) - Description: Language version to use. Available versions depend on the language.
initialDarkMode (optional)
- Type:
boolean - Default:
true - Description: Whether to start in dark mode
initialCode (optional)
- Type:
string - Default: Language-specific default code
- Description: Code to display initially in the editor
hideHeader (optional)
- Type:
boolean - Default:
false - Description: Hide the header (language selector, version, theme toggle) for embedded views
editorWidthPercent (optional)
- Type:
number - Default:
50 - Description: Initial width of the editor panel as a percentage (constrained between 20-80). The console panel takes the remaining space. Users can still manually resize using the drag handle.
Architecture
The NotJS component architecture:
┌─────────────────────────────────────────────────────┐
│ NotJS React Component │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ Monaco Editor │ │ xterm.js │ │
│ │ (Code Input) │ │ (Terminal) │ │
│ └────────────────┘ └──────────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────┐ │
│ │ WebSocket Connection │ │
│ └─────────────────────────────────────────────┘ │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────┐
│ NotJS Server │
│ (Spring Boot) │
└─────────────────────┘Contributing
Contributions are welcome! Please visit the main repository to contribute.
License
MIT
Note: This component requires a running NotJS server. For setup instructions, visit https://github.com/cholnhial/notjs
