Frequently Asked Questions
Relevant source files
The following files were used as context for generating this wiki page:This document answers common questions about the Ghostbird project, covering general usage, project-specific details, and technical architecture. Ghostbird is a Thunderbird add-on that enables editing email text in an external text editor using the GhostText protocol. It works by establishing a WebSocket connection to a GhostText server (running as a plugin in your editor) and relaying text between the Thunderbird compose window and the editor.
For more in-depth information, please refer to the design documentation and contribution guidelines.
Sources: doc/faq.md:3-8, CONTRIBUTING.md:10-12
General
What is Ghostbird?
Ghostbird is a Thunderbird add-on that allows you to compose emails in your preferred text editor. It implements the GhostText protocol to connect to a GhostText server running in your editor via a WebSocket on port 4001 by default. This connection facilitates real-time text synchronization between the editor and the Thunderbird compose window.
Sources: doc/faq.md:5-8, README.md:10-12
Is it safe to use?
Yes. The add-on does not collect any personal data and is restricted by Thunderbird's security model to only connect to localhost. Any attempts to send data to external servers are blocked. While the add-on is in beta and may contain bugs, you can verify its source code by inspecting the released .xpi file, which is a standard zip archive. For maximum assurance, you can wait for version 1.0.0, which will have undergone a full manual review by Mozilla.
Sources: README.md:213-218, doc/faq.md:10-11
Usage
Which Thunderbird versions are supported?
Ghostbird supports Thunderbird 128 and newer, with a focus on the latest Extended Support Release (ESR).
Sources: doc/faq.md:15-16, README.md:40
What text editors are supported?
Any text editor with a GhostText server plugin should work. Known compatible editors include:
| Editor | Plugin/Link |
|---|---|
| Sublime Text | GhostText for Sublime Text |
| VS Code / VSCodium | GhostText for VS Code |
| GNU Emacs | atomic-chrome |
| Vim | vim-ghost |
| Neovim | nvim-ghost.nvim |
| Acme | Ghost for Acme |
| Helix | helix-ghost |
| Any Editor | GhostText-Any |
Sources: README.md:41-52, doc/faq.md:18-21
How do I troubleshoot connection issues?
If the Ghostbird button turns red, it indicates a connection failure. The most common reason is that the GhostText server is not running in your text editor. Ensure the server is started (e.g., with :GhostTextStart in Vim) and listening for connections. For more details, refer to the GhostText troubleshooting guide.
Sources: README.md:65-66, doc/faq.md:29-30
How do I switch between HTML and Plain Text mode?
The composition format (HTML vs. Plain Text) must be set before you start composing a new message, as it cannot be changed mid-edit in recent Thunderbird versions. This setting is configured on a per-account basis.
- Go to
Account Settings>Composition & Addressing. - In the
Compositionsection, check or uncheck theCompose messages in HTML formatcheckbox. - Start a new message for the change to take effect.
Note that this is different from the profile-wide "Sending Format" setting, which determines the format the recipient sees, not the format you compose in.
Sources: doc/faq.md:38-59
Project
Why not fork the original GhostText or External Editor?
- GhostText: The original browser add-on is designed for simplicity. Ghostbird requires Thunderbird-specific features (e.g., handling compose windows, address lines) and plans to extend the GhostText protocol, which would complicate the original codebase.
- External Editor: The classic
External Editoradd-on is no longer compatible with modern Thunderbird versions (>68) because the current API prohibits launching arbitrary external applications for security reasons. Ghostbird uses the WebSocket-based approach of GhostText as a modern workaround. - External Editor Revived (ERR): This well-maintained alternative uses Native Messaging, which requires a companion app. Ghostbird was started without knowledge of ERR's existence and continues development to leverage GhostText's live-updating capabilities.
Sources: doc/faq.md:69-97
How do I contribute?
Contributions are welcome via issues and pull requests on GitHub. The general workflow for code changes is:
- Fork and clone the repository.
- Install dependencies with
yarn. - Run tests with
yarn test. - Make changes, using
yarn buildto build andyarn startto launch Thunderbird for debugging. - Format and lint your code with
yarn fix. - Commit your changes and create a pull request.
For documentation-only changes, the build and test steps can be skipped.
Sources: CONTRIBUTING.md:4-5, 29-50
Developer & Architectural
How does the add-on work?
Ghostbird operates with three main components: a background script (background.js), a compose script (compose.js), and the GhostText server in your text editor.
The following diagram illustrates the interaction when a user initiates a session.
This sequence diagram shows the flow of events from the user clicking the button to the establishment of the WebSocket connection and subsequent text synchronization.
Sources: doc/design.md:21-65
What is the project's code structure?
The codebase is organized following the Ports and Adapters architecture to promote modularity and testability. Key directories include:
src/root/: Entry points (background.ts,compose.ts,options.ts).src/ghosttext-session/: Core logic implementing the GhostText protocol. This module has no other internal dependencies.src/ghosttext-runner/&src/ghosttext-adaptor/: Modules that facilitate communication between the core session logic and the Thunderbird-specific parts.src/thunderbird/: A wrapper around the Thunderbird MailExtension API.src/app-*: Infrastructure for the background, compose, and options pages.
The dependency flow is designed to isolate the core logic from the Thunderbird API.
This diagram shows the module dependency hierarchy, with root/ at the top and the core ghosttext-session/ at the bottom, independent of platform-specific details.
Sources: doc/design.md:120-161
What is the purpose of static isSingleton?
This static property is part of a custom, lightweight dependency injection (DI) system used in the project. The startup scripts (e.g., src/root/startup/startup_compose.ts) scan for classes with this property and automatically instantiate them, resolving their dependencies based on constructor parameters.
isSingleton: true: A single instance of the class is created and shared.isSingleton: false: A new instance is created for each dependency request.
This approach is intended to reduce boilerplate code for object instantiation and enforce the Dependency Inversion Principle, making the code more maintainable and testable, especially when adapting to breaking changes in the Thunderbird API. While it sacrifices some compile-time type safety, this is mitigated by sanity tests (yarn test sanity) that verify the entire dependency graph can be resolved at build time.
Sources: doc/faq-architectural.md:3-36, doc/design.md:200-226, src/test/startup.test.ts:38-46
How can I see the dependency tree?
After running yarn test, a file named build/test/dependency_tree.md is generated. This file contains a Mermaid diagram visualizing the complete dependency graph of all auto-instantiated classes, providing a clear overview of the application's structure.
Sources: doc/faq-architectural.md:18-20, src/test/util/dependency_reporter.ts:16-20, src/test/startup.test.ts:54-56
Why are index.ts files not in the repository?
The index.ts files, which act as barrel files to re-export modules from a directory, are generated automatically during the build process by the barrelsby tool. They are intentionally excluded from the repository to avoid manual maintenance. Running yarn install or yarn build will generate them.
Sources: doc/faq.md:113-117