Skip to main content
GitHub Desktop supports launching your favorite external editor to work with repository files. Editors can be launched from the top-level Repository menu or by right-clicking a repository in the sidebar.

Requirements

For an editor to be supported by GitHub Desktop, it must satisfy these requirements:
1

Directory support

The editor must support opening a directory, not just individual files.
2

Discoverable installation

The editor must be installed in a reliable, discoverable location on the user’s machine.
3

Command-line interface

The editor must provide a command-line interface that GitHub Desktop can launch.

Supported Editors

Windows

GitHub Desktop supports these editors on Windows:
  • Atom (Stable, Beta, and Nightly)
  • Visual Studio Code (Stable and Insiders)
  • VSCodium
  • Sublime Text
  • Notepad++
  • Typora
  • SlickEdit
  • Brackets
  • JetBrains IDEs:
    • IntelliJ IDEA
    • WebStorm
    • PhpStorm
    • PyCharm
    • RubyMine
    • CLion
    • GoLand
    • RustRover
    • Fleet
    • DataSpell
  • Android Studio
  • RStudio
  • Aptana Studio
  • ColdFusion Builder
  • Zed (Stable and Preview)
  • Pulsar
  • Cursor
  • Windsurf

macOS

Supported editors on macOS include:
  • Atom
  • Visual Studio Code (Stable and Insiders)
  • VSCodium
  • Sublime Text
  • BBEdit
  • TextMate
  • Brackets
  • MacVim
  • Neovide
  • VimR
  • Typora
  • CodeRunner
  • SlickEdit
  • Xcode
  • Emacs
  • Nova
  • Lite XL
  • JetBrains IDEs (All major IDEs)
  • Android Studio
  • RStudio
  • Aptana Studio
  • Eclipse (All IDE variants)
  • Pulsar
  • Cursor
  • Zed

Linux

Linux users can use these editors:
  • Atom
  • Visual Studio Code (Stable and Insiders)
  • VSCodium
  • Sublime Text
  • Typora
  • SlickEdit
  • Neovim
  • Neovide
  • Notepadqq
  • Mousepad
  • GNOME Builder
  • Code (elementary OS)
  • Lite XL
  • Kate
  • Emacs
  • Pluma
  • JetBrains IDEs (All major IDEs)
  • Android Studio
  • Pulsar
  • Zed

How Editor Detection Works

Windows Registry Lookup

On Windows, GitHub Desktop finds editors using registry keys:
app/src/lib/editors/win32.ts
const editors: WindowsExternalEditor[] = [
  {
    name: 'Visual Studio Code',
    registryKeys: [
      // 64-bit version (user scope)
      CurrentUserUninstallKey('{771FD6B0-FA20-440A-A002-3B3BAC16DC50}_is1'),
      // 32-bit version (user scope)
      CurrentUserUninstallKey('{D628A17A-9713-46BF-8D57-E671B46A741E}_is1'),
      // ARM64 version (user scope)
      CurrentUserUninstallKey('{D9E514E7-1A56-452D-9337-2990C0DC4310}_is1'),
      // 64-bit version (system scope)
      LocalMachineUninstallKey('{EA457B21-F73E-494C-ACAB-524FDE069978}_is1'),
    ],
    displayNamePrefix: 'Microsoft Visual Studio Code',
    publisher: 'Microsoft Corporation',
    executableShimPaths: [['bin', 'code.cmd']],
  },
]
Registry keys are checked in multiple locations:
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

macOS Bundle Identifiers

On macOS, editors are located using their bundle identifiers:
app/src/lib/editors/darwin.ts
const editors: IDarwinExternalEditor[] = [
  {
    name: 'Visual Studio Code',
    bundleIdentifiers: ['com.microsoft.VSCode'],
  },
  {
    name: 'Visual Studio Code (Insiders)',
    bundleIdentifiers: ['com.microsoft.VSCodeInsiders'],
  },
  {
    name: 'Sublime Text',
    bundleIdentifiers: [
      'com.sublimetext.4',
      'com.sublimetext.3',
      'com.sublimetext.2',
    ],
  },
]
To find an editor’s bundle identifier, run:
defaults read /Applications/YourEditor.app/Contents/Info CFBundleIdentifier

Linux Executable Paths

On Linux, GitHub Desktop searches for executables in common installation paths:
app/src/lib/editors/linux.ts
const editors: ILinuxExternalEditor[] = [
  {
    name: 'Visual Studio Code',
    paths: [
      '/usr/share/code/bin/code',
      '/snap/bin/code',
      '/usr/bin/code',
    ],
  },
  {
    name: 'Sublime Text',
    paths: ['/usr/bin/subl'],
  },
]

Launching Editors

The launchExternalEditor function handles launching editors across all platforms:
app/src/lib/editors/launch.ts
export const launchExternalEditor = (
  fullPath: string,
  editor: FoundEditor
) => launchEditor(editor.path, [fullPath], `'${editor.editor}'`, __DARWIN__)

Launch Process

1

Verify editor exists

const exists = await pathExists(editorPath)
if (!exists) {
  throw new ExternalEditorError(
    `Could not find executable for ${editorName} at path '${editorPath}'.`,
    { openPreferences: true }
  )
}
2

Spawn editor process

const opts: SpawnOptions = {
  detached: true,  // Detach from GitHub Desktop
  stdio: 'ignore', // Don't capture output
}

const child = spawnAsDarwinApp
  ? spawn('open', ['-a', editorPath, ...args], opts)
  : spawn(editorPath, args, opts)

child.unref() // Don't wait for editor to exit
3

Handle errors

child.on('error', reject)
child.on('spawn', resolve)
Editors are spawned as detached processes so they continue running even if GitHub Desktop is closed.

JetBrains Toolbox Support

GitHub Desktop supports editors installed through JetBrains Toolbox:
{
  name: 'JetBrains PyCharm',
  registryKeys: [...],
  jetBrainsToolboxScriptName: 'pycharm',
}
The integration checks for scripts in the default JetBrains Toolbox scripts directory.
Only add jetBrainsToolboxScriptName to the main edition of a product. JetBrains Toolbox generates scripts with the same name for different editions (Community vs Professional), so only one can be detected reliably.

Custom Editor Integration

You can configure custom editors that aren’t in the default list:
app/src/lib/editors/launch.ts
export const launchCustomExternalEditor = (
  fullPath: string,
  customEditor: ICustomIntegration
) => {
  const argv = parseCustomIntegrationArguments(customEditor.arguments)
  const args = expandTargetPathArgument(argv, fullPath)

  const spawnAsDarwinApp = __DARWIN__ && customEditor.bundleID !== undefined
  const editorName = `custom editor at path '${customEditor.path}'`

  return launchEditor(customEditor.path, args, editorName, spawnAsDarwinApp)
}

Custom Integration Interface

interface ICustomIntegration {
  path: string           // Path to editor executable
  arguments: string      // Command-line arguments
  bundleID?: string      // macOS bundle ID (optional)
}

Error Handling

Editor integration includes comprehensive error handling:
throw new ExternalEditorError(
  `Could not find executable for ${editorName} at path '${editorPath}'.`,
  { openPreferences: true }
)
The openPreferences flag prompts users to check their editor settings when an error occurs.

Adding a New Editor

To add support for a new editor, follow these steps:
1

Add editor definition

Add an entry to the appropriate platform-specific file:
  • Windows: app/src/lib/editors/win32.ts
  • macOS: app/src/lib/editors/darwin.ts
  • Linux: app/src/lib/editors/linux.ts
2

Provide discovery information

Windows: Registry keys and validation:
{
  name: 'My Editor',
  registryKeys: [CurrentUserUninstallKey('{GUID}')],
  displayNamePrefix: 'My Editor',
  publisher: 'My Company',
  executableShimPaths: [['bin', 'myeditor.exe']],
}
macOS: Bundle identifier:
{
  name: 'My Editor',
  bundleIdentifiers: ['com.example.myeditor'],
}
Linux: Executable paths:
{
  name: 'My Editor',
  paths: ['/usr/bin/myeditor', '/snap/bin/myeditor'],
}
3

Test the integration

  1. Install the editor
  2. Build GitHub Desktop
  3. Check that the editor appears in Settings
  4. Test launching the editor with a repository

Contributing

Want to add support for your favorite editor? Contributions are welcome! See the editor integration technical docs for detailed instructions.

Build docs developers (and LLMs) love