A VS Code-inspired, fully browser-based code editor.
Zero backend. Real file system access. Monaco power.
Get Started · Features · Architecture · Browser Support · Contributing
|
Monaco at the Core |
Auto Language Detection |
|
Real Folder Explorer |
Multi-Tab Workflow |
|
True Save -- Back to Disk |
Dark and Light Theme |
|
Graceful Fallbacks |
Toast Notifications |
Prerequisites: Node.js 18+ and npm. For full folder access use Chrome or Edge.
# 1 -- Clone
git clone https://github.com/your-org/code-editor.git
cd code-editor
# 2 -- Install
npm install
# 3 -- Develop
npm run devOpen the printed URL (typically http://localhost:5173) in Chrome or Edge for the full experience.
npm run build # TypeScript check + Vite bundle
npm run preview # Preview production output locally
npm run lint # oxlint -- fast Rust-based linterState is held in a single flat Zustand store (useEditorStore). Components subscribe only to the slices they need, keeping re-renders minimal and updates predictable.
+-------------------------------------------------------+
| App.tsx |
| TitleBar . ActivityBar . Sidebar . TabBar . Editor |
| StatusBar |
+------------------------+------------------------------+
| reads / dispatches
v
+---------------------+
| useEditorStore | Zustand
| tabs[] |
| activeTabId |
| rootNode |
| theme |
| toast |
+----------+----------+
| calls
+-------------+-------------+
v v
lib/fileSystem.ts lib/languageDetect.ts
FSAA wrapper + fallbacks ext -> Monaco language ID
code-editor/
+-- public/
| +-- favicon.svg App icon
| +-- icons.svg SVG sprite sheet
|
+-- src/
| +-- components/
| | +-- ActivityBar/ Left icon strip (explorer toggle, theme toggle)
| | +-- Sidebar/ Folder explorer + lazy file tree
| | +-- Tabs/ Open-file tab bar with dirty indicators
| | +-- Editor/ Monaco wrapper + Ctrl+S save logic
| | +-- StatusBar/ Bottom bar (language, cursor position)
| | +-- Toast/ Auto-dismiss notification toasts
| | +-- TitleBar.tsx Top title bar
| |
| +-- lib/
| | +-- fileSystem.ts File System Access API wrapper + fallbacks
| | +-- languageDetect.ts Extension to Monaco language ID (30+ langs)
| | +-- monacoSetup.ts Monaco initialization and worker config
| |
| +-- store/
| | +-- useEditorStore.ts Zustand store: tabs, tree, theme, toasts
| |
| +-- types/
| | +-- index.ts Shared TypeScript types + FSAA augmentations
| |
| +-- App.tsx Root layout, theme sync, beforeunload guard
| +-- main.tsx React 19 entry point
| +-- index.css Global CSS reset + design tokens
|
+-- vite.config.ts
+-- tsconfig.json
+-- package.json
+-- README.md
| Browser | Open Folder | In-Place Save | Open File | Save (Download) |
|---|---|---|---|---|
| Chrome | yes | yes | yes | yes |
| Edge | yes | yes | yes | yes |
| Brave | yes | yes | yes | yes |
| Firefox | -- | -- | yes (upload) | yes |
| Safari | -- | -- | yes (upload) | yes |
Open Folder and direct Save require the File System Access API, a Chromium-only capability. The editor detects support at runtime and adjusts automatically; Firefox and Safari users get a seamless upload/download flow.
JavaScript · TypeScript · JSX / TSX · JSON / JSONC · HTML · CSS · SCSS · Less · Markdown · Python · Ruby · PHP · Java · C · C++ · C# · Go · Rust · Swift · Kotlin · SQL · Shell / Bash · YAML · XML · SVG · TOML · INI · Dockerfile · GraphQL · Vue · Lua · R
Language is inferred from the file extension automatically. No manual picker, no configuration.
| Shortcut | Action |
|---|---|
Ctrl+S / Cmd+S |
Save to disk (in-place if opened via handle) |
Ctrl+Shift+S / Cmd+Shift+S |
Save As, choose a new location |
Ctrl+W / Cmd+W |
Close active tab |
Ctrl+Tab |
Cycle to next tab |
| `Ctrl+`` | Toggle sidebar |
| All standard Monaco bindings | Multi-cursor, find / replace, fold, format, ... |
| Layer | Technology |
|---|---|
| UI Framework | React 19 |
| Language | TypeScript 6 |
| Build | Vite 8 |
| Editor Engine | Monaco Editor 0.55 via @monaco-editor/react |
| State | Zustand 5 |
| Linter | oxlint |
| Styling | CSS Modules + CSS custom properties |
| File I/O | File System Access API with fallback |
Bug reports, feature requests, and pull requests are welcome.
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Commit:
git commit -m 'feat: add my feature' - Push:
git push origin feat/my-feature - Open a Pull Request
Run npm run lint before submitting and keep PRs focused on a single concern.
MIT -- see LICENSE.
Abyssal Liturgy · built with React, Monaco, and the Web Platform