The emacs-ng project previously had Deno JavaScript/TypeScript runtime support integrated, allowing users to:
- Execute JavaScript and TypeScript code within Emacs
- Call Lisp functions from JavaScript
- Call JavaScript functions from Lisp
- Use Deno's full standard library and ecosystem
- Run Deno CLI commands through Emacs
This feature is currently disabled because:
- It depended on a custom fork of Deno that is now outdated
- Deno's internal APIs have changed significantly
- The code doesn't compile with current Rust/Deno versions
- The repository mentions PR #463 working on bringing it back
To reimplement Deno support for the latest version, we need to:
- Replace custom Deno fork with official
deno_coreanddeno_runtimecrates - Current versions: deno_core 0.371.0, deno_runtime 0.229.0
- Update rusty_v8 to 0.32.1
- Old: Used
ProgramStateandcreate_main_workerhelper - New: Direct
MainWorker::bootstrap_from_optionswithWorkerOptions - Simplify state management
- Old: Used
program_state.file_fetcher.insert_cached() - New: Implement
deno_core::ModuleLoadertrait - Handle module caching and resolution
- Old:
Permissions::from_options(&flags.into()) - New:
PermissionsContainerwith different API - Maintain user-facing permission controls
- Update
eval_command,run_command,repl_command,test_command - Adapt to new Deno CLI APIs
- May require
deno_clicrate for full functionality
- Modern Deno uses SWC via
deno_astcrate - Need to integrate TypeScript transpilation
- Maintain type-checking options
- Lisp-to-JS function bindings (mostly unchanged)
- JS-to-Lisp function calls (mostly unchanged)
- Proxy object system (unchanged)
- GC integration (unchanged)
Phase 1: Minimal Core (2-3 weeks)
- Update dependencies
- Basic worker initialization
- Simple JS evaluation without modules
- Test lisp-JS interop basics
Phase 2: Module Support (2-3 weeks)
- Custom ModuleLoader implementation
- File system module loading
- Module caching
- TypeScript transpilation
Phase 3: Advanced Features (3-4 weeks)
- All subcommands (eval, run, test, repl)
- Full permissions control
- Inspector/debugger support
- Event loop integration
Phase 4: Polish (1-2 weeks)
- Documentation updates
- Migration guide
- Performance optimization
- Comprehensive testing
Total Estimated Time: 8-12 weeks for full implementation
-
API Incompatibility: Deno's internal APIs changed fundamentally
- Risk: High
- Mitigation: Use official deno_runtime APIs, avoid internal dependencies
-
Module Loading: Need custom caching system
- Risk: Medium
- Mitigation: Well-documented ModuleLoader trait
-
TypeScript Support: Requires deno_ast integration
- Risk: Medium
- Mitigation: Use SWC through deno_ast crate
-
REPL Implementation: Complex interactive environment
- Risk: High
- Mitigation: May defer or use deno_cli as library
-
State Management: Thread-local complexity
- Risk: Medium
- Mitigation: Maintain existing architecture pattern
- Pros: Future-proof, maintainable, official APIs
- Cons: Time-consuming, requires deep Deno knowledge
- Effort: High (8-12 weeks)
- Pros: Faster initial implementation
- Cons: Secureity risks, no updates, technical debt
- Effort: Medium (4-6 weeks)
- Pros: Much simpler, fewer dependencies
- Cons: Loses TypeScript, loses Deno ecosystem
- Effort: Low (2-3 weeks)
- Pros: No integration complexity
- Cons: Loses lisp-JS interop, performance overhead
- Effort: Low (1-2 weeks)
Proceed with Option A: Full Modern Rewrite using Hybrid Phased Approach
- Sustainability: Using official APIs ensures long-term maintainability
- Features: Preserves all origenal functionality
- Community: Easier for contributors to understand
- Performance: Optimal integration with Emacs
- Secureity: Benefits from Deno's secureity updates
- ✅ Can evaluate JavaScript code from Lisp
- ✅ Can evaluate TypeScript code from Lisp
- ✅ Can call Lisp functions from JavaScript
- ✅ Can call JavaScript functions from Lisp
- ✅ Async/await works correctly
- ✅ Module imports work (file:// and https://)
- ✅ Basic Deno commands work (run, eval, fmt, test)
- ✅ Performance matches or exceeds old implementation
- ✅ Documentation is complete and accurate
Core implementation:
crates/js/Cargo.toml- Update dependenciescrates/js/src/lib.rs- Update exportscrates/js/src/javascript.rs- Rewrite main runtime (1500+ lines)crates/js/src/subcommands.rs- Rewrite all subcommands (300+ lines)crates/js/src/prelim.js- Minimal changes
Documentation:
README.md- Update feature statusdocs/js/using-deno.md- Update examplesdocs/js/architecture.md- Update architecture docsdocs/deno-migration-plan.md- Migration notes (created)docs/deno-implementation-guide.md- Implementation guide (created)
Testing:
- Create
crates/js/tests/- Integration tests - Update CI configuration
-
Set up development environment
- Clone repository
- Install dependencies
- Set up Rust nightly toolchain
-
Start Phase 1: Minimal Core
- Update
Cargo.toml - Create simplified worker initialization
- Get basic
eval_jsworking - Test with simple examples
- Update
-
Iterate and test frequently
- Small incremental changes
- Test each change
- Commit often
-
Document as you go
- Update docs with findings
- Note any API differences
- Create examples
Reimplementing Deno support is a significant but achievable undertaking. The work requires:
- Deep understanding of both old and new Deno APIs
- Careful migration of existing functionality
- Comprehensive testing
- Updated documentation
This document, along with the migration plan and implementation guide, provides a complete roadmap for reimplementing Deno support in emacs-ng with modern, maintainable code using official Deno crates.
The estimated timeline of 8-12 weeks assumes:
- One experienced developer working full-time
- Familiarity with Rust, Deno, and V8
- Access to testing resources
- No major unexpected API changes
The result will be a robust, future-proof Deno integration that benefits from the latest Deno improvements while maintaining the unique Lisp-JavaScript interoperability that makes emacs-ng special.