How to Create Custom Themes for AI Coding Assistants (With Automated Injection Guide)
This tutorial explains the underlying principles of customizing themes for Electron-based AI coding assistants. It covers two main approaches—modifying the app.asar archive and utilizing the Chrome DevTools Protocol (CDP) for dynamic CSS injection—and provides a step-by-step guide to creating, debugging, and automating custom theme injection using a Python script.
As AI coding tools become increasingly popular, developers are looking for ways to personalize their user experience beyond standard model capabilities. Customizing the “skins” or themes of these AI coding assistants has recently become a popular trend in the developer community. In reality, the technical principles behind this are straightforward and entirely achievable through DIY efforts. This article breaks through the information gap, starting from the underlying architecture, to guide you in creating custom themes for Electron-based AI coding assistants, complete with a convenient automated injection solution.
1. Why Can AI Coding Assistants Be Re-skinned?
To understand how theming works, we must first look at the technical foundation of these desktop applications. The majority of mainstream AI coding assistant clients available today (on both Windows and Mac) are desktop applications built on the Electron framework.
The core of Electron technology lies in its use of the Chromium browser engine for UI rendering and Node.js for underlying system capabilities. This means these applications are essentially “web pages dressed up as desktop apps.” Since the underlying engine is a browser, the debugging capabilities native to browsers—specifically, Developer Tools—are equally applicable to these applications.
For example, on macOS, if you open any Electron-based AI coding assistant and press Command + Option + I simultaneously within the application interface, the Chromium Developer Tools panel will appear. This panel allows you to inspect the DOM structure and CSS styles in real-time, and even modify and preview effects directly. This is the “key” to customizing your theme.
2. Two Main Approaches to Theme Customization
Understanding the underlying principle, there are two primary ways to alter the application’s appearance:
Approach 1: Modifying the Packaged Archive Files Directly
This method is the most straightforward, similar to installing a game MOD. When an Electron application is packaged, its frontend resources (HTML, CSS, JavaScript) are bundled into an archive file named app.asar.
- Steps: First, locate the application’s installation directory and find the
app.asarfile. Then, use a specialized tool (like theasarcommand-line utility) to unpack it. Modify the stylesheet (usually a.cssfile) inside, and finally repack and replace the original file. - Pros: The modification is thorough. The theme applies to all interfaces and does not rely on external scripts.
- Cons: The technical barrier is higher, requiring familiarity with command-line operations and packaging tools. Crucially, this operation breaks the application’s original code signature. Modifying the archive file may cause the application to fail signature verification upon launch, preventing it from opening or being blocked by certain OS versions. Additionally, subsequent automatic software updates may overwrite your modifications, requiring you to repeat the process.
Approach 2: Injecting Custom CSS via the DevTools Protocol (CDP)
This is a more elegant and safer alternative. Since the application has a built-in Chromium browser, we can leverage its powerful Chrome DevTools Protocol (CDP) to control it.
- Steps: By calling CDP interfaces such as
CSS.addStyleSheetorPage.addScriptToEvaluateOnNewDocument, you can dynamically inject custom CSS code into the running application to override default styles. - Pros: No need to modify application installation files; code signatures remain intact, and it offers better compatibility with updates.
- Cons: The injection is “temporary.” Once the application restarts, the injected code disappears. You must manually re-inject it after each launch or write an external script to automate the process.
3. Hands-On Practice: Building Your Theme from Scratch
Now that we understand the basics, let’s move to the practical phase. The following demonstration covers the entire customization process using the second approach. Note: The example below uses the placeholder “an AI coding assistant” instead of a specific software name. The modification logic applies to almost all Electron applications.
Step 1: Open Developer Tools and Locate Targets
- Launch “an AI coding assistant” client.
- Press
Command + Option + I(Mac) orF12(Windows) to open Developer Tools. - In the “Elements” panel of Developer Tools, click the “Selector” icon (arrow icon) in the top left corner, then click the element you want to modify on the main interface—for example, the sidebar background, the font color in the code editor, or button border-radius.
- The Styles pane in Developer Tools will display the CSS class names and style rules for that element. Remember these class names; they are crucial for the subsequent modifications.
Step 2: Write and Debug Custom CSS
While you can write styles directly in the “Console,” it is highly recommended to create a temporary Snippet in the “Sources” panel for debugging.
For instance, if you want to change the main interface background color to dark gray (#1e1e1e) and adjust the code font to “JetBrains Mono,” you can try entering the following in the console:
// Execute the following code in the console to see immediate effectsdocument.documentElement.style.setProperty('--background-primary', '#1e1e1e');document.documentElement.style.setProperty('--font-family-code', 'JetBrains Mono, monospace');
If the application supports CSS variables, modifying them is the fastest approach. If not, you will need to directly manipulate the DOM node styles via JavaScript:
// Assuming the sidebar class name is .app-sidebardocument.querySelector('.app-sidebar').style.backgroundColor = '#1e1e1e';
After testing in the console and confirming the results are satisfactory, organize these CSS or JS codes into a standalone .css (or .js) file.
Step 3: Implementation and Upgrade — The Script Launcher
Directly modifying the app.asar file carries high risks and is easily overwritten by updates. To balance “persistence” and “safety,” a recommended alternative is to write a script launcher.
This launcher acts as a “middleman.” The implementation logic is as follows:
- Wait for App Launch: The script first launches the “AI coding assistant” application and waits a few seconds for the interface to render.
- Establish Debugging Connection: The application can enable a remote debugging port upon startup. You need to append
--remote-debugging-port=9222to the application’s launch parameters (by passing this argument when launching via the script). - Execute Injection: The script accesses
http://localhost:9222/jsonvia HTTP to retrieve the application’s debugging target list. It then connects to the corresponding page via WebSocket and finally executes the CSS injection code we prepared earlier.
Here is a minimal automated injection script example (Python):
import timeimport requestsimport websocketimport jsondef inject_css():# 1. Get debugging targetstargets = requests.get('http://localhost:9222/json').json()# 2. Filter for page type targets (usually type: 'page')page_target = [t for t in targets if t['type'] == 'page'][0]ws_url = page_target['webSocketDebuggerUrl']# 3. Establish WebSocket connectionws = websocket.create_connection(ws_url)# 4. Construct the CDP command to inject CSScss_code = "document.body.style.backgroundColor = '#1e1e1e';"command = {"id": 1,"method": "Runtime.evaluate","params": {"expression": css_code}}ws.send(json.dumps(command))ws.close()if __name__ == '__main__':# Assuming the app has been launched via script with the specific porttime.sleep(5) # Wait for the app interface to finish loadinginject_css()print("Theme injection complete!")
Advantages of this approach:
- No App Cracking Required: It does not alter any files in the installation directory, passing system integrity checks.
- Update-Proof: The app is opened via the script every time. Even if the software updates, as long as the underlying architecture remains unchanged, the script remains effective.
- High Programmability: You can dynamically switch between different themes based on time, weather, or even the type of file currently open.
4. Advanced Tips and Considerations
- Leverage CSS Variables: Modern applications heavily utilize CSS custom properties (variables) during development. Running
getComputedStyle(document.documentElement).getPropertyValue('--color-primary')in the console allows you to view common color palette variables. Modifying just these variables can change the entire application’s theme color scheme with minimal effort. - Mind Selector Specificity: When injecting CSS, you might encounter issues where the application’s native style weights are too high. You can appropriately add
!importantdeclarations, but use them sparingly to avoid confusion in subsequent customizations. - Performance Considerations: The injected CSS should not contain complex, time-consuming large-scale filters or shadows, as this can impact the smoothness of the development tool itself, especially when scrolling through large code files.
- Identifying Electron Apps: If you are unsure whether a tool is an Electron application, check “Help” -> “About” in the menu bar, or simply try the Developer Tools shortcut. If it opens successfully, it is highly likely built on this framework.
5. Conclusion: The Joy of Creation
With the tutorial above, you can say goodbye to uniform default interfaces and tailor a unique “skin” for your daily AI coding assistant based on your aesthetics and usage habits. This process not only provides visual satisfaction but also deepens your understanding of frontend rendering mechanisms, the Electron architecture, and debugging protocols. Once you master this methodology, you will find that any Electron-based tool software can be rejuvenated by your hands. Give it a try—this is just the beginning.
