{"id":17221,"library":"esmoduleserve","title":"ES Module Serve","description":"esmoduleserve is a lightweight, shim HTTP development server designed for serving ES modules directly in the browser without requiring a bundling step. Currently at version 0.3.1, it focuses on providing a direct ES module development experience by rewriting import specifiers on-the-fly to precise, resolved paths. It implements a Node-like module resolution algorithm, prioritizing `\"module\"` or `\"jsnext\"` fields in `package.json` over `\"main\"`. This differentiates it from more comprehensive dev servers (e.g., Vite, Webpack dev server) that typically integrate bundling, transpilation, and hot module reloading, by offering a simpler, unbundled approach for native ES module workflows. Its release cadence is likely infrequent, as it serves a specific, focused niche for rapid development and testing of native ES modules.","status":"active","version":"0.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/marijnh/esmoduleserve","tags":["javascript","module","es module","http","development","dev server"],"install":[{"cmd":"npm install esmoduleserve","lang":"bash","label":"npm"},{"cmd":"yarn add esmoduleserve","lang":"bash","label":"yarn"},{"cmd":"pnpm add esmoduleserve","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library itself is distributed as a CommonJS module. Attempting to use ES Module `import` syntax will result in an error or `undefined` as `ModuleServer` will not be correctly exposed.","wrong":"import { ModuleServer } from 'esmoduleserve/moduleserver'","symbol":"ModuleServer","correct":"const { ModuleServer } = require('esmoduleserve/moduleserver')"}],"quickstart":{"code":"const http = require('http');\nconst { ModuleServer } = require('esmoduleserve/moduleserver');\nconst path = require('path');\nconst fs = require('fs');\n\n// Create a 'demo' directory and place an 'index.html' and 'my-module.js' inside for testing.\n// Example index.html: <script type=\"module\" src=\"/_m/my-module.js\"></script>\n// Example my-module.js: export const message = 'Hello from ES module!'; console.log(message);\nconst rootDir = path.join(__dirname, 'demo'); \n\nconst moduleServer = new ModuleServer({\n  root: rootDir,\n  maxDepth: 2, // Allow access to modules one parent directory deep (e.g., for monorepos)\n  prefix: '_m' // The URL prefix for rewritten module scripts\n});\n\nconst server = http.createServer((req, res) => {\n  console.log(`Request: ${req.method} ${req.url}`);\n\n  // First, try to handle the request as a module through esmoduleserve\n  if (moduleServer.handleRequest(req, res)) {\n    return; // Request was handled\n  }\n\n  // If not a module request, serve static files (e.g., index.html)\n  const requestedPath = req.url === '/' ? '/index.html' : req.url;\n  const filePath = path.join(rootDir, requestedPath);\n\n  fs.readFile(filePath, (err, data) => {\n    if (err) {\n      res.writeHead(404, { 'Content-Type': 'text/plain' });\n      res.end('Not Found: ' + requestedPath);\n      console.error(`File not found: ${filePath}`);\n      return;\n    }\n\n    let contentType = 'text/plain';\n    if (filePath.endsWith('.html')) contentType = 'text/html';\n    else if (filePath.endsWith('.js')) contentType = 'application/javascript';\n    else if (filePath.endsWith('.css')) contentType = 'text/css';\n\n    res.writeHead(200, { 'Content-Type': contentType });\n    res.end(data);\n  });\n});\n\nconst port = process.env.PORT ?? 8080;\nconst host = process.env.HOST ?? 'localhost';\n\nserver.listen(port, host, () => {\n  console.log(`esmoduleserve server running at http://${host}:${port}/`);\n  console.log(`Serving static files from: ${rootDir}`);\n  console.log(`Module scripts are available under the /_m/ prefix (e.g., http://${host}:${port}/_m/my-module.js)`);\n});\n","lang":"javascript","description":"This quickstart demonstrates how to integrate `esmoduleserve` as HTTP middleware into a basic Node.js server. It sets up a server that serves static files from a 'demo' directory and uses `ModuleServer` to rewrite and serve ES modules from the same directory under the `/_m/` path. This setup is ideal for local development and testing of native ES modules in the browser without a separate bundling step."},"warnings":[{"fix":"Ensure all direct and transitive dependencies provide native ES module builds. Check their `package.json` for a `module` or `exports` field pointing to an ES module entry. If CJS dependencies are unavoidable, consider using a traditional bundler (e.g., Vite, Rollup) instead.","message":"esmoduleserve is a shim for ES module resolution, not a bundler or transpiler. It will not process or convert CommonJS (CJS) modules, nor will it transpile modern JavaScript features for older browsers. If your dependencies are not distributed as native ES modules, they will likely fail to load, resulting in 'missing import' or 'module not found' errors in the browser console.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"If you explicitly need to access modules multiple levels up from the root, increase the `--depth` command-line option or the `maxDepth` configuration for `ModuleServer` (e.g., `{ maxDepth: 3 }`). Exercise caution when increasing this value, especially in shared development environments.","message":"The server's `--depth` option (or `maxDepth` in the `ModuleServer` constructor) defaults to `1`. This means it can only resolve modules one directory level above its configured `root` directory. This is a security measure to prevent accidental exposure of arbitrary files higher up the file system. Attempting to import modules from further parent directories will fail.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always use CommonJS `require` syntax: `const { ModuleServer } = require('esmoduleserve/moduleserver')` when integrating the server programmatically into a Node.js environment.","message":"The `esmoduleserve` library itself (specifically the `esmoduleserve/moduleserver` entry point) is packaged as a CommonJS module. Using direct ES Module `import` syntax (`import { ModuleServer } from 'esmoduleserve/moduleserver'`) in an ES module context will not work as expected and will typically lead to `TypeError: Cannot destructure property 'ModuleServer' of require(...) as it is undefined` or similar runtime errors.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Verify that all your project's dependencies are ES module compatible. Check their `package.json` for a `module` or `exports` field pointing to an ES module entry. If not, you may need to find an ES module alternative or use a bundler.","cause":"A dependency referenced by your project (or one of its transitive dependencies) does not provide a native ES module build, or its `package.json` does not correctly specify its ES module entry point (e.g., the `module` or `exports` field is missing or points incorrectly).","error":"Uncaught TypeError: Failed to resolve module specifier \"some-package\". Relative references must start with \"./\", \"../\", or \"/\"."},{"fix":"Change your import statement to use CommonJS `require` syntax: `const { ModuleServer } = require('esmoduleserve/moduleserver')`.","cause":"This error occurs when attempting to use ES Module `import` syntax (`import { ModuleServer } from ...`) to import a CommonJS module. The `esmoduleserve/moduleserver` entry point is a CommonJS module.","error":"TypeError: Cannot destructure property 'ModuleServer' of require(...) as it is undefined."},{"fix":"If intentional, increase the `maxDepth` option in your `ModuleServer` configuration (e.g., `{ maxDepth: 2 }`) or the `--depth` flag if using the CLI, to allow access to more parent directories. Consider the security implications before increasing this value.","cause":"This typically indicates that the module server tried to resolve a module path that traverses beyond its configured `maxDepth` (defaulting to 1), preventing access to files in higher-level directories for security reasons.","error":"Error: ENOTDIR: not a directory, open '/path/to/project/../some-module.js'"}],"ecosystem":"npm","meta_description":null}