{"id":15410,"library":"with-server","title":"Server Orchestration for E2E Tests","description":"The `with-server` package is a command-line utility and programmatic API designed to orchestrate local server startup, command execution (typically end-to-end tests), and server shutdown. It automatically handles port allocation via the `$PORT` environment variable, waits for the server to become ready, and exposes `$SERVER_URL` to the executed command. It offers options to specify the server's start script and control output redirection. The current stable version is 2.1.0, with releases appearing infrequently, driven by feature additions or critical maintenance, such as the major Node.js version bump in v2.0.0. It's a focused tool for e2e testing workflows, abstracting away the complexities of server lifecycle management during test runs, differentiating itself by its simplicity and direct integration with npm scripts.","status":"active","version":"2.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/cellular/with-server","tags":["javascript"],"install":[{"cmd":"npm install with-server","lang":"bash","label":"npm"},{"cmd":"yarn add with-server","lang":"bash","label":"yarn"},{"cmd":"pnpm add with-server","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The package is primarily CommonJS (`type: commonjs`). Direct ESM imports might require specific import paths or bundler configuration to resolve correctly.","wrong":"import withServer from 'with-server';","symbol":"withServer","correct":"const withServer = require(\"with-server\");"}],"quickstart":{"code":"const withServer = require(\"with-server\");\n\nasync function runTests() {\n  console.log('Starting server and running tests...');\n  try {\n    const exitCode = await withServer(\"cypress run\", {\n      run: \"start\", // Assuming 'npm start' is the command to launch your server\n      redirect: \"stderr\", // Redirect server logs to stderr to keep test output clean\n      // Additional options like 'port' can be specified if you need a fixed port\n    });\n    console.log(`Test command exited with code: ${exitCode}`);\n    process.exit(exitCode);\n  } catch (error) {\n    console.error('An error occurred:', error.message);\n    process.exit(1);\n  }\n}\n\n// Example package.json script for demonstration:\n// \"scripts\": {\n//   \"start\": \"node server.js\",\n//   \"test:e2e\": \"node run-tests.js\"\n// }\n// Where server.js might look like:\n// const http = require('http');\n// const port = process.env.PORT || 3000;\n// http.createServer((req, res) => res.end('Hello from server')).listen(port, () => console.log(`Server listening on port ${port}`));\n\nrunTests();","lang":"javascript","description":"Demonstrates programmatic usage of `with-server` to run a test command (e.g., Cypress) against a local server, specifying the server start script and output redirection, and handling the exit code."},"warnings":[{"fix":"Upgrade your Node.js environment to version 16 or later. Check your `package.json` `engines` field and CI/CD configurations.","message":"Version 2.0.0 dropped support for Node.js 12 and 14. The package now requires Node.js version 16 or newer.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure your server script reads from `process.env.PORT` (e.g., `app.listen(process.env.PORT || 3000)`) or, if using a fixed port, pass it via the programmatic API or environment variable before `with-server` execution.","message":"The server process started by `with-server` *must* listen on the TCP port specified by the `$PORT` environment variable. If `$PORT` is not explicitly set, `with-server` will pick a free random port and expose it.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use the `--redirect stdout` command-line option or `redirect: 'stdout'` in the programmatic API to write server output to stdout. Alternatively, use `--redirect null` or `redirect: 'null'` to silence server output completely.","message":"By default, the standard output (stdout) of the server process is redirected to stderr to prevent it from mixing with test output. This can make debugging server logs challenging if you're not aware of it.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Verify your server's start script, ensure it's listening on `process.env.PORT`, and check for any startup errors in the server's output (redirect to stdout for debugging). Increase timeout if server takes long to start.","cause":"The server process failed to start or did not listen on the expected port before the timeout, preventing `with-server` from establishing a connection.","error":"Error: connect ECONNREFUSED 127.0.0.1:XXXX"},{"fix":"Ensure the test command is installed as a `devDependency` (e.g., `npm install cypress --save-dev`) and either run `with-server` via `npm scripts` or directly reference the local binary (e.g., `node_modules/.bin/cypress`).","cause":"The test command specified (e.g., 'cypress') is not installed globally, not available in the local `node_modules/.bin` directory, or not properly configured in your `package.json` scripts.","error":"command not found: <your-test-command>"},{"fix":"Run `npm install with-server --save-dev` to install the package. If using ESM, ensure your setup correctly handles CJS module imports or consider bundling your code.","cause":"The `with-server` package is not installed in your project's `node_modules` directory, or there's an issue with how it's being imported (e.g., trying to use `import` syntax in a CommonJS-only context without a bundler).","error":"Error: Cannot find module 'with-server'"}],"ecosystem":"npm"}