A person works at a desk in front of multiple monitors in a bright, modern office.

Building with the GitHub Copilot SDK, Part 2 – Wiring Up an Electron + Angular Desktop App

In my previous post, we discussed the initial setup of the new Copilot SDK. This post will cover how we actually hook up the official @github/copilot-sdk inside an Electron and Angular application.

Why is this structure necessary?

When building a desktop application, we want a clean separation of concerns. We need to run the SDK securely in the background while keeping the user interface fast and responsive. This implementation provides a solid foundation for real-time chat with streaming.

The Core Architecture

Our implementation focuses on four main behaviors:

  • Running the SDK in the Electron main process, which operates in a Node context.
  • Supporting both native GitHub Copilot authentication and bring-your-own-key (BYOK) setups for providers like OpenAI, Anthropic, or Azure.
  • Streaming assistant deltas directly to the Angular UI as they arrive.
  • Keeping separate Copilot sessions per workspace or folder. This ensures you can have multiple chats open without them interfering with each other.

You can get started quickly by running npm install @github/copilot-sdk. We keep most of the Copilot logic contained inside a single service file: electron/copilot.service.ts.

Handling Authentication

Authentication can be tricky, but we handle it in two distinct ways. A buildSessionConfig() function inside the service decides which path to take.

  • Native GitHub Copilot Auth – This is the default setup. If you just don’t set a COPILOT_API_KEY, the system will try to use whatever Copilot credentials are already on the machine, such as a CLI login or VS Code auth.
  • Bring Your Own Key (BYOK) – If you want to use a different provider, you can set specific environment variables. You will need to define COPILOT_PROVIDER (as openai, anthropic, or azure) and COPILOT_API_KEY. You can also optionally set COPILOT_BASE_URL and COPILOT_MODEL.

What the Copilot Service Actually Does

The CopilotService does the heavy lifting. It lazy-creates a single CopilotClient and then creates a new session per workspace using client.createSession({ ... }). It wires up the streaming events so we can push deltas straight to the renderer.

It also has a sendMessage(prompt, workspaceId, workingDir) method. This method returns a promise but also gives you the deltas along the way. Finally, it exposes a getAuthStatus() method so the UI can show a connected or disconnected status.

Here is a rough shape of the core logic inside that service:

We also use a preload script. This script exposes a clean API so Angular doesn’t have to know about the ipcRenderer.

That is basically it.

A chat interface showing a user request to describe a project and an AI response explaining a full‑stack system using Angular, NestJS, TypeScript, and related tools.

Practical Advice for Your Implementation

If you are building this yourself, there are a few things that actually matter in practice.

First, you MUST stream deltas. Waiting for the full response feels awful for the user. Second, keep one session per workspace using a Map<workspaceId, Session>.

If you are doing BYOK, let people pick the model. If you are using GitHub auth, just take whatever model they have enabled. Finally, you MUST call client.stop() when the application quits. If you don’t do this, you will leak background processes.

Wrap-Up

The whole architecture is intentionally contained. The logic lives in copilot.service.ts, the main process glue is in main.ts, secure exposure happens in preload.cts, and UI consumption occurs in normal Angular components.

Feel free to clone the repository and search for “copilot:” to see exactly how these channels are used.
Repo: https://github.com/chadmichel/chadscopilot

Have you tried wiring up the Copilot SDK in a desktop app yet? Feel free to reach out to me at @chadmichel on X with your thoughts.

author avatar
Chad Michel Chief Technology Officer
Chad is a lifelong Nebraskan. He grew up in rural Nebraska and now lives in Lincoln. Chad and his wife have a son and daughter.

Related posts