esm.do
v0.0.7
Published
Living ESM module system for AI agents - types, modules, tests, and scripts in one place
Maintainers
Readme
esm.do
Living ESM modules for AI agents - types, code, tests, and scripts in one place.
Vision
esm.do is a programmable module system where AI agents can create, evolve, test, and execute ESM modules through a unified interface. Every module is a living entity with four synchronized files:
@scope/module/
├── index.d.ts # Types - the contract
├── index.mjs # Module - the implementation
├── index.test.js # Tests - the verification
└── index.script.js # Script - the executionWhy esm.do?
Traditional module registries separate storage from execution. esm.do unifies them:
- Write once, verify everywhere - Types, code, and tests committed atomically
- AI-native - MCP tools let agents create modules programmatically
- Version everything - Full git history via gitx.do
- Execute anywhere - Sandboxed execution via ai-evaluate
- Simple mental model - Module = types + code + tests + script
Quick Start
SDK
import { esm } from 'esm.do'
// Create a module
const result = await esm.write({
name: '@math/add',
types: `export declare function add(a: number, b: number): number`,
module: `export function add(a, b) { return a + b }`,
tests: `
describe('add', () => {
it('adds positive numbers', () => expect(add(2, 3)).toBe(5))
it('adds negative numbers', () => expect(add(-1, -2)).toBe(-3))
it('adds zero', () => expect(add(0, 5)).toBe(5))
})
`,
script: `return add(10, 20)`
})
console.log(result.testResults) // { passed: 3, failed: 0 }
console.log(result.value) // 30
console.log(result.version) // 'a3f2dd1...'CLI
# Initialize a new module
esm init @math/add
# Write module files
esm write @math/add --types="..." --module="..." --tests="..." --script="..."
# Run tests
esm test @math/add
# ✓ adds positive numbers (2ms)
# ✓ adds negative numbers (1ms)
# ✓ adds zero (1ms)
# 3 passed, 0 failed
# Execute script
esm run @math/add
# 30
# View history
esm log @math/add
# a3f2dd1 Initial implementation
# b7c4ee2 Add edge case testsExpression Mode (REPL)
Evaluate TypeScript expressions directly from the command line:
# Evaluate expressions
esm '1 + 2 * 3'
# 7
esm 'const sum = (a, b) => a + b; sum(10, 20)'
# 30
# Use local execution (Miniflare, no network required)
esm --local '1 + 2'
# Enter interactive REPL
esm --repl
# Combine: evaluate then enter REPL
esm --repl 'const x = 10'
> x * 2
20Expression Mode Flags:
| Flag | Description |
|------|-------------|
| --local, -l | Use local Miniflare instead of remote workers |
| --repl, -i | Enter interactive REPL after evaluation |
| --theme, -t | Syntax highlighting theme |
| --timeout | Evaluation timeout in milliseconds |
Requirements for local mode:
npm install @dotdo/cli ai-evaluate miniflareAPI
# Get module info
GET https://esm.do/@math/add
# Get specific file
GET https://esm.do/@math/add.d.ts
GET https://esm.do/@math/add.mjs
GET https://esm.do/@math/add.test.js
GET https://esm.do/@math/add.script.js
# Get specific version
GET https://esm.do/@math/add@a3f2dd1
# Create/update module
POST https://esm.do/@math/add
{
"types": "...",
"module": "...",
"tests": "...",
"script": "..."
}
# Run tests
POST https://esm.do/@math/add/test
# Execute script
POST https://esm.do/@math/add/runMCP Tools
// Available tools for AI agents
esm_list // List modules matching pattern
esm_read // Read module contents
esm_write // Create or update module
esm_test // Run module tests
esm_run // Execute module script
esm_versions // Get version history
esm_diff // Compare versions
esm_delete // Remove moduleThe Four Files
Types (.d.ts)
The module's contract. Declares what the module exports without implementation details.
// @math/calculator.d.ts
export declare function add(a: number, b: number): number
export declare function subtract(a: number, b: number): number
export declare function multiply(a: number, b: number): number
export declare function divide(a: number, b: number): numberModule (.mjs)
The implementation. ESM code that fulfills the type contract.
// @math/calculator.mjs
export function add(a, b) { return a + b }
export function subtract(a, b) { return a - b }
export function multiply(a, b) { return a * b }
export function divide(a, b) {
if (b === 0) throw new Error('Division by zero')
return a / b
}Tests (.test.js)
Verification using vitest-compatible API. Module exports are automatically in scope.
// @math/calculator.test.js
describe('calculator', () => {
describe('add', () => {
it('adds positive numbers', () => expect(add(2, 3)).toBe(5))
it('adds negative numbers', () => expect(add(-1, -2)).toBe(-3))
})
describe('divide', () => {
it('divides numbers', () => expect(divide(10, 2)).toBe(5))
it('throws on division by zero', () => {
expect(() => divide(1, 0)).toThrow('Division by zero')
})
})
})Script (.script.js)
An executable entry point. Module exports are in scope. Return value is captured.
// @math/calculator.script.js
// All exports available: add, subtract, multiply, divide
const a = 100
const b = 25
console.log(`${a} + ${b} = ${add(a, b)}`)
console.log(`${a} - ${b} = ${subtract(a, b)}`)
console.log(`${a} * ${b} = ${multiply(a, b)}`)
console.log(`${a} / ${b} = ${divide(a, b)}`)
return { sum: add(a, b), product: multiply(a, b) }Dependencies
Modules can import other esm.do modules:
// @math/stats.mjs
import { add, divide } from 'esm.do/@math/calculator'
export function mean(numbers) {
const sum = numbers.reduce((acc, n) => add(acc, n), 0)
return divide(sum, numbers.length)
}
export function sum(numbers) {
return numbers.reduce((acc, n) => add(acc, n), 0)
}Architecture
┌─────────────────────────────────────────────────────────────┐
│ Access Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ API │ │ CLI │ │ MCP │ │ SDK │ │
│ │ esm.do/* │ │ esm cmd │ │ Tools │ │ import esm │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┴─────────────────────────────────┐
│ Module Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ESM Module Manager │ │
│ │ - Module CRUD (create, read, update, delete) │ │
│ │ - Version management (branch, tag, history) │ │
│ │ - Dependency resolution │ │
│ │ - Import graph analysis │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┴─────────────────────────────────┐
│ Execution Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ai-evaluate Sandbox │ │
│ │ - Isolated V8 contexts via worker_loaders │ │
│ │ - Vitest-compatible test framework │ │
│ │ - SDK globals (db, ai, api) │ │
│ │ - Configurable network access │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┴─────────────────────────────────┐
│ Storage Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ gitx.do │ │
│ │ - Content-addressed blobs (SHA-1) │ │
│ │ - Trees (module structure) │ │
│ │ - Commits (versions) │ │
│ │ - Refs (branches, tags) │ │
│ │ - Tiered storage (DO → R2 → Analytics) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘Built On
- gitx.do - Git reimplementation for Cloudflare Durable Objects
- ai-evaluate - Sandboxed code execution
- Cap'n Web - JavaScript RPC system
- Cloudflare Workers - Edge compute platform
Installation
Quick Install (Recommended)
# Universal installer - auto-detects your system
curl -fsSL https://esm.do/install | bashVia npm
# Global installation
npm install -g esm.do
# Or as a project dependency
npm install esm.doVia Homebrew (macOS/Linux)
# Add the tap and install
brew tap dot-do/esm https://github.com/dot-do/esm
brew install esm-do
# Or install directly
brew install dot-do/esm/esm-doVia pnpm
pnpm add -g esm.doVia yarn
yarn global add esm.doVerify Installation
esm --version
esm --helpUninstall
# Via installer script
curl -fsSL https://esm.do/uninstall | bash
# Or manually
npm uninstall -g esm.do # if installed via npm
brew uninstall esm-do # if installed via HomebrewRequirements
- Node.js 18 or later
- npm, pnpm, or yarn (for package manager installation)
- Homebrew (for macOS/Linux Homebrew installation)
License
MIT
