Open-source project
vitejs/launch-editor avatar
vitejs/launch-editor

launch-editor opens a file at a line and column from Node

Open file in editor from Node.js.

720 stars99 forksJavaScriptMIT

At a glance

What is it?
launch-editor is a small MIT package that spawns your editor on a given file and position, guessing which editor you are running from the processes on the machine before falling back to environment variables. It also ships an express style middleware, and it refuses UNC paths on Windows so that a hostile file parameter cannot leak your NTLM credentials.
Who is it for?
Adopt launch-editor when you want a dev server error overlay or a CLI to open the offending file at the right line, and when your team does not agree on a single EDITOR environment variable. Do not adopt it to spawn arbitrary programs, since the editor list is fixed and the custom script path is an environment variable you control.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A dev server convenience pulled out of create-react-app

The package does one thing: it opens a file with line numbers in an editor from Node.js. Its origin explains the shape of the API. The README says the main functionality is extracted from `react-dev-utils`, specifically the `launchEditor.js` module, with slight modifications so that it can be used as a standalone package, and that the original source code is licensed under MIT.

The `react-dev-utils` extraction matters because that package is what a create-react-app dev server uses to turn a stack trace frame into a clickable link that opens your editor at the right place. The problem with using it directly, as the README puts it, is that it includes many other utilities and dependencies and is thus not suitable for standalone usage.

So the value here is a small, focused dependency with a history of running inside the exact situation it is meant for. One feature was added on top of the extraction: column number support. The repository is MIT licensed, is not archived, and the last push was on 2026-10-14.

The editor is guessed from running processes first

This is the part that distinguishes the package from its alternatives, and the README is explicit about it. It names two existing packages with the same purpose, `lahmatiy/open-in-editor` and `sindresorhus/open-editor`, and says that both expect environment variables like `EDITOR` to be set in order to open files. This package infers the editor to open by checking current running processes before falling back to environment variables.

The reasoning is practical. On a developer machine, the editor you are already using is usually running, and the process list is a more accurate signal than a shell variable that was set once and never updated. `EDITOR` and `VISUAL` remain as the fallback, and the middleware documentation makes the same order explicit: a specific editor bin to try first, defaulting to inferring from running processes, then a fallback to env variables like `EDITOR` and `VISUAL`.

The trade-off is that process inspection is a heuristic. Two editors running at once, an editor started from a terminal, or a remote session can all produce a guess you did not intend, and there is no documented way to see what was chosen before it opens.

One call, one position, one optional callback

The API is a single function, and the README's example shows the whole contract:

js
const launch = require('launch-editor')

launch(
  // filename:line:column
  // both line and column are optional
  // `file://` URIs are also supported
  'foo.js:12:34',
  // try specific editor bin first (optional)
  'code',
  // callback if failed to launch (optional)
  (fileName, errorMsg) => {
    // log error if any
  },
)

The first argument is the target, encoded as `filename:line:column`, with both the line and the column optional and `file://` URIs accepted. The second argument names an editor binary to try before anything is inferred. The third is a callback that receives the file name and an error message if the launch failed.

The callback is what makes this usable in a server rather than a script. A dev server that cannot open an editor still has to render its error page, so a failed launch has to be recoverable rather than fatal, and the callback is where that decision lives.

The supported editors are listed in a table with columns for Linux, Windows and macOS, and the list includes the common members of the JetBrains family, `code` and `code-insiders`, `codium`, `cursor`, `zed`, `sublime`, `atom`, `vim` and `emacs`, alongside entries such as `appcode`, `atom-beta` and `visualstudio` that only apply to one platform. The table is long enough to read as a list of what existed over the years rather than a curated set, which is worth knowing before you rely on a specific name.

The middleware turns a URL into an editor window

There is a second entry point for servers, shipped as `launch-editor-middleware` and described as express, connect and webpack-dev-server compatible:

js
const launchMiddleware = require('launch-editor-middleware')

app.use('/__open-in-editor', launchMiddleware())

The factory accepts optional arguments, and the README notes the callback can be in any position as long as it is the last one. The first is a specific editor bin to try first, defaulting to inference from running processes and then the environment fallback. The second is the root directory of source files, in case the file path is relative, defaulting to `process.cwd()`. The third is a callback for when it fails to launch.

Files are then opened by sending requests to the server:

bash
/__open-in-editor?file=src/main.js:13:24

The `file` parameter carries the same `filename:line:column` string, and the root directory option exists because the path in the parameter is often relative to the project rather than to the process.

This is the entry point with a security dimension, and the README treats it as such. Because the file path frequently originates from untrusted input, the example parameter handled by `launch-editor-middleware`, the package does not accept every path a client can send.

UNC paths are refused so a path cannot steal NTLM

On Windows, `launch-editor` refuses to open files whose resolved path is a UNC path, that is, a path that starts with `\\`, such as `\\server\share\file.js`. The README explains the reasoning in detail, and it is a good example of a small library taking a security boundary seriously.

When a UNC path points at a remote host, any filesystem operation the package performs on it causes Windows to connect to that host over SMB. The `fs.existsSync` check used to verify the file before launching the editor is enough to trigger that connection. An attacker who controls the requested file path could point it at a server they control and abuse this to leak the current user's NTLM credentials, since Windows attempts NTLM authentication against the remote host automatically, sending a challenge-response that can be captured for offline cracking or relayed to another service.

The fix is to reject the path before doing anything with it, so no filesystem operation is ever performed on a UNC path. The error callback is then invoked with a fixed message, "UNC paths are not supported on Windows to avoid security issues." The README also gives the way forward for anyone who genuinely needs to edit a file on a network share: map the share to a drive letter first and pass that path, such as `Z:\file.js`.

Note the ordering this implies for a server. The middleware accepts a path from the request, so it should never be mounted on an interface that untrusted clients can reach, whatever the package does about UNC paths.

LAUNCH_EDITOR can force a binary or run your own script

Beyond the per-call editor argument, the `LAUNCH_EDITOR` environment variable has two jobs. It can force one of the supported editors:

bash
LAUNCH_EDITOR=codium

And it can point at a custom launch script of your own:

bash
LAUNCH_EDITOR=my-editor-launcher.sh

The README then shows the contract for that script, which is called with three arguments, the filename, the line and the column:

shell
# gets called with 3 args: filename, line, column
filename=$1
line=$2
column=$3

# call your editor with whatever args it expects
my-editor -l $line -c $column -f $filename

This is the escape hatch for an editor that is not in the table, or one whose command line differs from the conventions the package assumes. The cost is that the script is chosen by an environment variable, so it inherits the trust of the environment it runs in. Anyone who can set `LAUNCH_EDITOR` for your process can choose what gets executed.

The script also has to handle the arguments sensibly on its own, because the package does not know what your editor wants. The example passes a line, a column and a file, but the flags are the script author's choice, and a script that ignores the line and column silently loses the position feature that is the point of the package.

A pnpm workspace with the tooling to release it

The repository is a pnpm workspace with the packages under `packages/`, and the root manifest is a private root that only carries tooling:

json
{
  "private": true,
  "scripts": {
    "test": "pnpm -r test",
    "release": "bumpp",
    "lint": "oxlint --fix",
    "format": "oxfmt"
  },

Versions are bumped with `bumpp`, the test script fans out across the workspace with `pnpm -r test`, and linting and formatting run on `oxlint` and `oxfmt`. A `lint-staged` configuration runs the formatter on every file and the linter on JavaScript files, and a `pre-commit` git hook calls `lint-staged`, with `yorkie` in the dev dependencies to install it. The package manager is pinned at `[email protected]`.

There is no GitHub release listed for the project, and the version bumps are done by the release script rather than by published tags, so the release channel is npm. The repository also carries a `MAINTENANCE.md` next to the README, a `LICENSE` file, a `bump.config.mjs`, an `.oxfmtrc.json` and an `.oxlintrc.json`.

One observation about the ecosystem context. The package names itself `launch-editor` and `launch-editor-middleware`, and the usage examples use `require`, so it is a CommonJS entry point in a repository otherwise written in ES modules and built with modern tooling. That combination works, but it is the kind of detail worth checking against your own module setup before you install it.

Editorial conclusion

Adopt launch-editor when you want a dev server error overlay or a CLI to open the offending file at the right line, and when your team does not agree on a single EDITOR environment variable. Do not adopt it to spawn arbitrary programs, since the editor list is fixed and the custom script path is an environment variable you control. Verify first that the editor you use appears in the supported table for your platform, that the middleware route is not exposed on a public interface, that the UNC path rejection is present in the version you install, and that your editor is the one inferred, since the fallback order is running processes first and EDITOR or VISUAL second.

Frequently asked questions

How do I open a file in my editor from Node.js with launch-editor?

Require the package and call it with a target string in the form filename:line:column, where the line and column are optional and file:// URIs are supported. You can pass an editor binary to try first and a callback that receives the file name and an error message if the launch fails.

How does launch-editor decide which editor to open?

It infers the editor by checking current running processes, and falls back to environment variables such as EDITOR and VISUAL. Other packages with the same purpose, open-in-editor and open-editor, expect EDITOR to be set instead.

Why does launch-editor reject UNC paths on Windows?

Any filesystem operation on a UNC path makes Windows connect to the remote host over SMB and attempt NTLM authentication, which could leak the current user's credentials to a host chosen by an attacker. The package therefore rejects paths that start with a double backslash before performing any filesystem operation, and advises mapping a share to a drive letter instead.

Can I use my own editor with launch-editor?

Yes. Set the LAUNCH_EDITOR environment variable to the path of your own script, which is then called with three arguments, the filename, the line and the column. You can also set LAUNCH_EDITOR to the name of one of the supported editors to force it.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. vitejs/launch-editor on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vitejs-launch-editor.svg)](https://hysenlabs.com/projects/vitejs-launch-editor)

Was this useful?