The code editor you can take apart. A familiar VS Code experience on top of a Rust core that ships as libraries β swap the editor, replace the terminal, or embed the whole session in your own app.
Ecosystem
| If you want to⦠| DSCode gives you |
|---|---|
| Edit code, fast | A VS Code-like desktop app with sub-second startup and ~60% less memory |
| Keep your existing extensions | A full Node.js extension host with the vscode.* API, sandboxed by default |
| Build your own tool on top | Six Rust crates β text buffer, LSP, DAP, terminal, extension host, session β that compose any way you like |
| Run an editor headlessly | The same session, workspace, and extension layer with no UI attached |
- Sub-second startup. Native Rust binary, no Electron boot.
- ~60% less memory than VS Code on the same workspace.
- Your extensions still work. ESLint, Prettier, GitLens, Python β they run unchanged on the bundled Node.js host.
- Secure by default. Every extension starts with zero permissions, isolated by an OS-native sandbox (macOS
sandbox-exec, Linuxbubblewrap, Windows Job Objects). - Familiar UI. Monaco editor, xterm.js terminal, VS Code theme compatibility, ARIA-correct components.
- Cross-platform. macOS, Linux, and Windows.
Download a prebuilt release from the Releases page, or build from source β see Quickstart.
Every subsystem is a separate crate with a clean API. cargo add what you need, ignore the rest. The desktop app itself is just one composition of these crates β yours can be different.
[dependencies]
dscode-core = "0.3" # rope text buffer, app directories
dscode-lsp = "0.3" # LSP client, manager, pool
dscode-dap = "0.3" # Debug Adapter Protocol
dscode-terminal = "0.3" # PTY lifecycle, event sender trait
dscode-extension-host = "0.3" # sandbox, IPC, permissions, rate limiter
dscode-session = "0.3" # workspace, configuration, lifecycleBeyond Rust: npm i @dscode/monaco-wasm, pip install dscode-core.
use dscode_core::{TextBuffer, AppDirectories};
let buffer = TextBuffer::new("Hello, world!");
println!("{} chars", buffer.len_chars());
let dirs = AppDirectories::resolve(None);
println!("Config dir: {:?}", dirs.config_dir);use dscode_lsp::{LspManager, LspServerPool, LspServerStrategy};
let pool = LspServerPool::new(LspServerStrategy::OnePerLanguage);
let manager = LspManager::new(pool);
manager.register_server("rust", "rust-analyzer", vec!["--stdio".into()]);Each crate has optional Tauri integration via a feature flag, so the same crate works in a desktop app or a headless CI runner:
dscode-terminal = { version = "0.3", features = ["tauri"] }See the Library Guide for the full tour.
| Crate | What it gives you | Install |
|---|---|---|
dscode-core |
Rope-based TextBuffer, AppDirectories, CoreError |
cargo add dscode-core |
dscode-lsp |
LSP client, manager, connection pool | cargo add dscode-lsp |
dscode-dap |
Debug Adapter Protocol client, manager, pool | cargo add dscode-dap |
dscode-extension-host |
Host manager, IPC, sandbox, permissions, rate limiter, secrets | cargo add dscode-extension-host |
dscode-terminal |
Terminal manager, PTY lifecycle, TerminalEventSender trait |
cargo add dscode-terminal |
dscode-session |
Session manager, extension lifecycle, workspace, configuration | cargo add dscode-session |
| Subsystem | Default | Swap for |
|---|---|---|
| Editor | Monaco (via monaco-wasm) |
A WebGL renderer, a Vim core, or a plain textarea |
| Extension host | Node.js + NNG IPC | A Wasm runtime, a Lua engine, or nothing at all |
| Terminal | xterm.js + portable-pty |
Alacritty, your own ANSI parser, or a remote SSH session |
| UI framework | Svelte 4 | React, Solid, Vue, or raw DOM |
| Session state | dscode-session with Tauri |
The same crate without Tauri, for headless CI |
| Text storage | ropey (dscode-core::TextBuffer) |
A gap buffer, a piece table, or a CRDT |
| LSP client | dscode-lsp::LspManager |
Direct LspClient use, or a custom protocol handler |
- Headless CI runner β use
dscode-sessionwithout thetaurifeature to scan workspaces, run extensions, and emit diagnostics as JSON. - Custom terminal UI β implement
TerminalEventSenderfromdscode-terminaland forward PTY output to a websocket, a log file, or your own renderer. - Embed in your own Tauri app β pull in
dscode-sessionwith thetaurifeature and you have the full IDE session inside your application. - Write a different LSP client β
dscode-lspexposesLspClientdirectly if you'd rather build a bespoke manager. - Build a live theme editor β combine
dscode-core::AppDirectorieswith the CSS-custom-property theme layer to preview themes in real time.
Code examples for each are in docs/library-guide.md.
- Everything is a library. The application is a thin composition layer; the real value is in the crates.
- APIs over implementations. We standardise on interfaces (
TerminalEventSender,LspClient,TextBuffer) so you can swap implementations without touching the rest of the system. - VS Code compatibility is a feature, not a constraint. We support VS Code extensions because they're useful β but their limitations don't dictate our architecture.
- Security by default. Extensions can't read your SSH keys by accident. Deny-by-default sandboxing is non-negotiable.
- Performance is table stakes. Sub-second startup and low memory aren't traded for convenience.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tauri Window (WebKit/Chromium) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Frontend (Svelte 4 + TypeScript) β β
β β - Monaco Editor β β
β β - Svelte Components (38 components) β β
β β - CSS Custom Properties (VS Code theme compat) β β
β β - ARIA accessibility, focus traps β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β Tauri IPC (invoke/emit) β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β Rust Binary (src-tauri) β β
β β - SessionManager (central coordinator) β β
β β - Tauri Command Handlers (45 modules) β β
β β - Bootstrap, Logging, Monitoring, File Watcher β β
β ββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ
β depends on
βββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ
β Cargo Workspace Library Crates β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β dscode-core β β dscode-lsp β β dscode-dap β β
β β TextBuffer β β LspClient β β DebugAdapter β β
β β AppDirs β β LspManager β β DebugManager β β
β β CoreError β β LspPool β β DapPool β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β ββββββββββββββββββββββββ ββββββββββββββββ β
β β dscode-extension-hostβ β dscode-term β β
β β HostManager β β TermManager β β
β β IPC + Sandbox β β PTY β β
β β Permissions + Rate β β EventSender β β
β β Secrets + Validator β β TermError β β
β ββββββββββββββββββββββββ ββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β dscode-session ββ
β β ConfigStore, ExtensionLifecycle, Workspace, Documents, ββ
β β Contributions, EventEmitter, SessionState ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NNG IPC (nanomsg, serde_json)
ββββββββββββ΄βββββββββββββ¬ββββββββββββββ
β β β
βββΌββββββββββ ββββββββΌβββββ ββββββΌβββββ
β Extension β β LSP β β Debug β
β Host β β Server β β DAP β
β (Node.js) β β β β Server β
βββββββββββββ βββββββββββββ βββββββββββ
Frontend β Svelte 4, Monaco Editor, xterm.js, lucide-svelte, CSS custom properties for VS Code theme compatibility.
Backend (Rust) β Tauri 2.1, Tauri Commands + NNG for out-of-process IPC, ropey text buffers, tree-sitter parsing, tower-lsp, git2, portable-pty, tracing, thiserror, ripgrep-based search.
Extension runtime β a real Node.js process, NNG REQ/REP IPC with worker threads, full vscode.* API surface, OS-keyring-backed SecretStorage, deny-by-default sandbox.
- Rust 1.75+ with
cargo - Node.js 20+ and
npm - Platform-specific dependencies:
- Linux:
libwebkit2gtk-4.1-dev,libssl-dev,libgtk-3-dev,librsvg2-dev,patchelf - macOS: Xcode Command Line Tools
- Windows: Microsoft Visual C++ Build Tools
- Linux:
git clone https://github.com/dipankar/dscode.git
cd dscode
npm install
npm run tauri:dev # development with hot reload
npm run tauri:build # production bundleProduction artefacts land in:
- macOS:
src-tauri/target/release/bundle/macos/DSCode.app - Linux:
src-tauri/target/release/bundle/deb/dscode_*_amd64.deb - Windows:
src-tauri/target/release/bundle/msi/DSCode_*_x64.msi
cargo test --workspace # all crate tests
cargo test -p dscode-core # one crate
cargo clippy --workspace -- -D warnings # lintdscode/
βββ Cargo.toml # workspace root
βββ crates/
β βββ dscode-core/ # TextBuffer, AppDirectories
β βββ dscode-lsp/ # LSP client, manager, pool
β βββ dscode-dap/ # Debug Adapter Protocol
β βββ dscode-extension-host/# Extension host management
β βββ dscode-terminal/ # Terminal manager
β βββ dscode-session/ # Session management
βββ src-tauri/ # Tauri binary (the default app)
β βββ src/
β βββ main.rs
β βββ bootstrap.rs
β βββ session/ # SessionManager + IPC
β βββ commands/ # 45 Tauri command modules
βββ monaco-wasm/ # Monaco WASM bindings
βββ extension-host/ # Node.js extension runtime
βββ src/ # Svelte frontend (38 components)
βββ packages/ # npm and pypi bindings
βββ docs/ # Documentation
DSCode's extension host isn't a compatibility shim β it's a full Node.js runtime speaking the same IPC protocol as VS Code. Extensions are first-class citizens, but they're also sandboxed and observable.
| Extension type | Compatibility | Notes |
|---|---|---|
| Pure JavaScript / TypeScript | Full | ESLint, Prettier, GitLens, etc. |
| Native Node modules | Full | Python extension, C/C++ tools |
| Language providers | Full | 18+ provider types via IPC |
| Webview extensions | Partial | Tauri webview API |
| Electron API users | Partial | Shim layer for common APIs |
| Proprietary (Microsoft) | Reimplement | Copilot, IntelliCode |
Language providers supported with full two-way IPC: Hover, Completion, Diagnostics, SignatureHelp, Rename, CodeLens, CodeActions, Formatting, DocumentHighlights, FoldingRanges, SemanticTokens, DocumentSymbols, WorkspaceSymbols, Definitions, References, DocumentLinks, ColorPresentations, InlineCompletions.
Extras DSCode adds on top of the VS Code API:
- Sandbox declarations β extensions declare filesystem, network, and shell permissions in
package.json. Denied by default. - Rate limiting β built-in per-extension quota.
- OS keyring access β
vscode.SecretStorageis backed by the OS-native keyring. - Hot reload β extensions reload without restarting the editor.
- Deny-by-default sandbox β extensions start with no permissions.
- Platform sandboxes β macOS
sandbox-exec, Linuxbubblewrap, Windows Job Objects. - Path validation β all filesystem access is checked against the workspace allowlist.
- VSIX hardening β Zip-Slip prevention, SHA256 hash check,
package.jsoncross-validation. - OS keyring β extension secrets are stored via the OS-native keyring.
- Crash recovery β extension host restarts with exponential backoff (max 3 attempts).
- Stale IPC cleanup β orphaned socket files and pending requests are reaped automatically.
- Node.js verification β bundled Node binary is hash-verified on startup.
See SECURITY.md for the disclosure process.
DSCode is a community project. Contributions are welcome β whether you're fixing a bug, adding a feature, or replacing an entire subsystem.
Adding a new crate
- Create
crates/my-crate/with aCargo.tomlthat inherits[workspace.package]. - Add
"crates/my-crate"to[workspace].membersin the rootCargo.toml. - Write a
README.mdwith badges, install instructions, and a usage example. - Add an
examples/directory with at least one runnable example. - Open a PR. CI checks formatting, clippy, tests, docs, and
cargo publish --dry-run.
Replacing a subsystem
- Open an issue describing your use case.
- We'll help you identify the minimal API surface to implement.
- Submit a PR. Hackability beats backwards compatibility in pre-1.0 releases.
Full guidelines in CONTRIBUTING.md.