React Terminal Emulator
Build immersive, realistic command-line interface experiences in the browser using React. Create draggable, resizable terminal windows with command history, theming, and simulated command execution.
What This Skill Does
Guides you through building a React-based terminal emulator with:
Realistic terminal UI with common CLI featuresDraggable and resizable terminal windowsCommand history navigation (up/down arrows)Simulated command output (npm, node, custom commands)Terminal window controls (minimize, maximize, close)Configurable prompts and themesCopy/paste supportProper state management and persistenceInstructions
1. Project Setup
Set up a new React project with the required tech stack:
```bash
npm create vite@latest terminal-emulator -- --template react-ts
cd terminal-emulator
npm install
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
npm install lucide-react
npm install -D vitest
```
Configure Tailwind CSS in `tailwind.config.js` to scan component files.
2. Architecture Guidelines
**Code Style:**
Write concise, technical JavaScript/TypeScript with accurate examplesUse functional and declarative programming patterns; avoid classesPrefer iteration and modularization over code duplicationUse descriptive variable names with auxiliary verbsUse "function" keyword for pure functionsAvoid unnecessary curly braces in conditionalsUse declarative JSX**Naming Conventions:**
Use lowercase with dashes for directories (e.g., `components/terminal-window`)Use PascalCase for component files (e.g., `TerminalWindow.tsx`)Use camelCase for utility files (e.g., `terminalUtils.ts`)Favor named exports for components and utilities**File Structure:**
```
src/
├── components/
│ ├── terminal-window/
│ │ ├── TerminalWindow.tsx
│ │ └── TerminalHeader.tsx
│ ├── terminal-output/
│ │ └── TerminalOutput.tsx
│ └── terminal-input/
│ └── TerminalInput.tsx
├── hooks/
│ ├── useTerminalHistory.ts
│ └── useTerminalCommands.ts
├── utils/
│ ├── terminalUtils.ts
│ └── commandParser.ts
└── context/
└── TerminalContext.tsx
```
3. Implement Core Terminal Components
**Terminal Window Component:**
Implement draggable functionality using mouse eventsAdd resize handles (corners and edges)Include window controls (minimize, maximize, close)Handle window dimensions and constraintsPersist window state to localStorage**Terminal Output Component:**
Render command history with proper formattingStyle output to match realistic terminal appearanceSupport different output types (stdout, stderr, info)Implement auto-scroll to latest output**Terminal Input Component:**
Handle command input with contentEditable or input elementImplement command history navigation (up/down arrows)Support multi-line input if neededDisplay configurable prompt (e.g., `user@host:~$`)4. State Management
Use React Context for global terminal state:
Current command inputCommand historyOutput historyTerminal configuration (theme, prompt)Window state (position, size, minimized)Implement proper state persistence:
```typescript
// Save to localStorage on state changes
useEffect(() => {
localStorage.setItem('terminalState', JSON.stringify(state));
}, [state]);
// Load from localStorage on mount
useEffect(() => {
const saved = localStorage.getItem('terminalState');
if (saved) setState(JSON.parse(saved));
}, []);
```
Implement proper cleanup in useEffect hooks to prevent memory leaks.
5. Command Simulation
Create a command parser that handles:
Built-in commands (`npm -v`, `node -v`, `npm run dev`, `clear`, `help`)Custom commands with simulated outputError messages for unknown commandsAsync command execution with loading statesExample command handler structure:
```typescript
const commands = {
'npm -v': () => '10.2.4',
'node -v': () => 'v20.11.0',
'npm run dev': () => simulateDevServer(),
clear: () => clearTerminal(),
help: () => showAvailableCommands(),
};
```
6. UI and Styling
Use Tailwind CSS for styling with these principles:
Implement realistic terminal UI (dark background, monospace font)Use common terminal color schemes (green/amber text, dark bg)Support theming (configurable colors, fonts)Implement proper focus states and accessibilityFollow Material Design guidelines for browser applicationsEnsure responsive design for different screen sizesKey styling considerations:
Monospace font family (e.g., `font-mono`)Proper text color contrastTerminal-style cursor animationSelection highlightingWindow shadow and borders7. Copy/Paste Support
Implement clipboard operations:
```typescript
// Copy selected text
const handleCopy = (e: ClipboardEvent) => {
e.preventDefault();
const selection = window.getSelection()?.toString();
if (selection) {
navigator.clipboard.writeText(selection);
}
};
// Paste text into input
const handlePaste = (e: ClipboardEvent) => {
e.preventDefault();
const text = e.clipboardData?.getData('text/plain');
if (text) insertTextAtCursor(text);
};
```
8. Performance Optimization
Minimize bundle size using code splitting and dynamic importsImplement lazy loading for non-critical componentsOptimize terminal rendering (virtualize long output if needed)Use proper caching strategiesImplement proper cleanup for event listeners and observersDebounce resize and drag events9. Error Handling and Testing
**Error Handling:**
Implement proper error boundaries around terminal componentsLog errors appropriately for debuggingProvide user-friendly error messages in terminal outputHandle edge cases (invalid commands, permission errors)**Testing:**
Write unit tests for utilities (command parser, history manager)Write component tests using Vitest and React Testing LibraryTest command execution and output renderingTest drag/resize functionalityTest keyboard navigation and shortcutsTest state persistence10. Security Best Practices
Implement Content Security Policy headersSanitize all user inputs before renderingAvoid executing arbitrary code (simulate commands only)Handle sensitive data properly (don't log secrets)Implement proper CORS handling if making API calls11. Git Commit Conventions
Use these commit message prefixes:
`feat:` for new features (e.g., "feat: add command history navigation")`fix:` for bug fixes (e.g., "fix: prevent window from moving outside viewport")`perf:` for performance improvements`docs:` for documentation changes`style:` for formatting changes`refactor:` for code refactoring`test:` for adding tests`chore:` for maintenance tasksRules:
Use lowercase for commit messagesKeep summary line concise (<72 characters)Include description for non-obvious changesReference issue numbers when applicable12. Documentation
Create and maintain:
`.cursorrules` file documenting coding standards and best practicesREADME.md with setup instructions and feature documentationCHANGELOG.md following semantic versioningInline code comments for complex logicComponent prop documentation using TypeScript interfacesExample Usage
```typescript
// Basic terminal implementation
import { TerminalProvider } from './context/TerminalContext';
import TerminalWindow from './components/terminal-window/TerminalWindow';
function App() {
return (
<TerminalProvider>
<div className="min-h-screen bg-gray-900 p-8">
<TerminalWindow />
</div>
</TerminalProvider>
);
}
```
Key Considerations
Test across different browsers (Chrome, Firefox, Safari, Edge)Ensure proper memory cleanup to prevent leaksHandle window resize and viewport constraintsSupport keyboard shortcuts (Ctrl+C, Ctrl+L, etc.)Consider accessibility (ARIA labels, keyboard navigation)Implement proper loading states for async commandsHandle network failures gracefully if making API callsDevelopment Workflow
1. Use proper version control (Git with feature branches)
2. Implement code review process before merging
3. Test in multiple environments and browsers
4. Follow semantic versioning for releases
5. Maintain changelog for all notable changes
6. Document breaking changes clearly