## 1. Project Overview & Quickstart (eclipse-theia/theia)

## File: README.md

- [Website](#website)
- [Repositories](#repositories)
- [Releases](#releases)
- [Scope](#scope)
- [Roadmap](#roadmap)
- [Getting Started](#getting-started)
- [Contributing](#contributing)
- [Feedback](#feedback)
- [Documentation](#documentation)
- [License](#license)
- [Trademark](#trademark)







## Website

[Visit the Eclipse Theia website](http://www.theia-ide.org) for more information and [the Theia documentation](http://www.theia-ide.org/docs).

## Repositories

This is the main repository for the Eclipse Theia project, containing the sources of the Theia Platform. Please open generic discussions, bug reports and feature requests about Theia on this repository. The Theia project also includes additional repositories, e.g. for the [artifacts building the Theia IDE](https://github.com/eclipse-theia/theia-blueprint) and the [Theia website](https://github.com/eclipse-theia/theia-website). Please also see the [overview of all Theia project repositories](https://github.com/eclipse-theia).

## Releases

- [All available releases](https://github.com/eclipse-theia/theia/releases) are available on GitHub including changelogs.
- [Detailed release announcements](https://theia-ide.org/resources/) are linked on the Theia website.
- [Community Releases](https://theia-ide.org/releases/) are listed on the Theia website.
- [Visit the release website](https://theia-ide.org/releases/) for more information.

## Scope

- Support building browser-based and desktop IDEs and tools
- Provide a highly flexible architecture for adopters
- Support VS Code Extension protocol
- Develop under vendor-neutral open-source governance

[More details on the project goals](https://theia-ide.org/docs/project_goals/) are available on the Theia website.

## Roadmap

See [our roadmap](https://github.com/eclipse-theia/theia/wiki/Eclipse-Theia-Roadmap) for an overview about the current project goals and the upcoming releases.

## Getting Started

Here you can find guides and examples for common scenarios to adopt Theia:

- [Get an overview of how to get started](https://theia-ide.org/#gettingstarted) on the Theia website
- [Develop a Theia application - your own IDE/Tool](https://theia-ide.org/docs/composing_applications/)
- [Learn about Theia's extension mechanisms](https://theia-ide.org/docs/extensions/)
- [Develop a VS Code like extension](https://theia-ide.org/docs/authoring_vscode_extensions/)
- [Develop a Theia extension](https://theia-ide.org/docs/authoring_extensions/)
- [Test a VS Code extension in Theia](https://github.com/eclipse-theia/theia/wiki/Testing-VS-Code-extensions)
- [Package a desktop Theia application with Electron](https://theia-ide.org/docs/blueprint_documentation/)

## Contributing

Read below to learn how to take part in improving Theia:

- Fork the repository and [run the examples from source](doc/Developing.md#quick-start)
- Get familiar with [the development workflow](doc/Developing.md), [Coding Guidelines](doc/coding-guidelines.md), [Code of Conduct](CODE_OF_CONDUCT.md) and [sign the Eclipse contributor agreement](CONTRIBUTING.md#eclipse-contributor-agreement)
- Find an issue to work on and submit a pull request
  - First time contributing to open source? Pick a [good first issue](https://github.com/eclipse-theia/theia/labels/good%20first%20issue) to get you familiar with GitHub contributing process.
  - First time contributing to Theia? Pick a [beginner friendly issue](https://github.com/eclipse-theia/theia/labels/beginners) to get you familiar with codebase and our contributing process.
  - Want to become a Committer? Solve an issue showing that you understand Theia objectives and architecture. [Here](https://github.com/eclipse-theia/theia/labels/help%20wanted) is a good list to start. Further, have a look at our [roadmap](https://github.com/eclipse-theia/theia/wiki/Eclipse-Theia-Roadmap) to align your contributions with the current project goals.
- Could not find an issue? Look for bugs, typos, and missing features.

## Feedback

Read below how to engage with Theia community:

- Join the discussion on [GitHub](https://github.com/eclipse-theia/theia/discussions).
- Ask a question, request a new feature and file a bug with [GitHub issues](https://github.com/eclipse-theia/theia/issues/new/choose).
- Vote on existing GitHub issues by reacting with a 👍. We regularly check issues with votes!
- Star the repository to show your support.
- Follow Theia on [X](https://x.com/theia_ide).
- Join the [weekly developer call](https://github.com/eclipse-theia/theia/wiki/Dev-Meetings)

## Documentation

- [API Documentation](https://eclipse-theia.github.io/theia/docs/next/index.html)
- [General Documentation](https://theia-ide.org/docs/)
- [VS Code API Compatibility Report](https://eclipse-theia.github.io/vscode-theia-comparator/status.html)
- Useful Links:
  - [Developing](doc/Developing.md)
  - [Testing](doc/Testing.md)
  - [Migration Guide](doc/Migration.md)
  - [API Integration Testing](doc/api-testing.md)
  - [Coding Guidelines](doc/coding-guidelines.md)
  - [Code Organization](doc/code-organization.md)
  - [Plugin and VSCode API](doc/Plugin-API.md)

## SBOM

To enhance supply chain security and offer users clear insight into project  components, Eclipse Theia now generates a Software Bill of Materials (SBOM) for every release. These are published to the Eclipse Foundation SBOM registry, with access instructions and usage details available in this [documentation](https://eclipse-csi.github.io/security-handbook/sbom/registry.html).

## License

- [Eclipse Public License 2.0](LICENSE-EPL)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](LICENSE-GPL-2.0-ONLY-CLASSPATH-EXCEPTION)

## Trademark

"Theia" is a **trademark of the Eclipse Foundation**. [Learn More](https://www.eclipse.org/theia)

---

## File: dev-packages/request/README.md

## Description

The `@theia/request` package is used to send proxy-aware http requests to other services.

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.org/theia>

---

## File: dev-packages/private-test-setup/README.md

## Description

The `@theia/test-setup` contributes a setup script for mocha executed tests in Theia.
This setup script is executed before any test file is loaded or compiled.
This is for example useful for globals which must exist before dependencies are loaded.

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

-   [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
-   [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
https://www.eclipse.org/theia

---

## File: dev-packages/private-re-exports/README.md

# `@theia/re-export`

Utility package to re-export dependencies.

This is useful when you use and expose some APIs from a dependency and want
your dependent to get access to the exact same symbols as you did.

## `package.json`

You can configure how the `theia-re-export` CLI will generate re-exports
through your `package.json` file with a `theiaReExports` key:

```json
{
    "theiaReExports": {
        "destination": {
            "export *": [
                "packages that export via *"
            ],
            "export =": [
                "packages that export via ="
            ],
            "copy": "other-package#destination"
        }
    }
}
```

### `transitive`

If you want to re-export packages from another package that also re-exports
its dependencies. We use this in `@theia/core` to simplify the consumption
of some optional Electron-specific dependencies.

### `export *`

Packages that export their symbols as `export const x = ...`.

### `export =`

Packages that export their symbols as a namespace like `export = ...`.

---

## File: dev-packages/private-ext-scripts/README.md

## Description

`theiaext` is a command line tool to run shared npm scripts in Theia packages.\
For instance, if you want add a new `hello` script that prints `Hello World`:

- add a new script to [./package.json](./package.json) with the `ext:` prefix.

```json
{
    "name": "@theia/ext-scripts",
    "theia-monorepo-scripts": {
        "ext:hello": "echo 'Hello World'"
    }
}
```

- install `theiaext` in your package (the actual version can be different)

```json
{
    "name": "@theia/myextension",
    "devDependencies": {
        "@theia/ext-scripts": "^0.1.1"
    }
}
```

- you should be able to call `hello` script in the context of your package:

```shell
    npx theiaext hello
````

- and from npm scripts of your package:

```json
{
    "name": "@theia/myextension",
    "scripts": {
        "hello": "theiaext hello"
    }
}
```

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.org/theia>

---

## File: dev-packages/private-eslint-plugin/README.md

## Description

The `@theia/eslint-plugin` contributes rules useful for Eclipse Theia development.
The plugin helps identify problems during development through static analysis including code quality, potential issues and code smells.

## Rules

### `annotation-check`

Inversify >=6.1 requires to annotate all constructor parameters of injectable classes as otherwise runtime errors are thrown.
The rule checks that all constructor parameters of injectable classes are annotated with `@inject`, `@unmanaged` or `@multiInject`.

### `localization-check`

The rule prevents the following localization related issues:

- incorrect usage of the `nls.localizeByDefault` function by using an incorrect default value.
- unnecessary call to `nls.localize` which could be replaced by `nls.localizeByDefault`.

### `no-src-import`

The rule prevents imports using `/src/` rather than `/lib/` as it causes build failures.
The rule helps developers more easily identify the cause of build errors caused by the incorrect import.

#### `runtime-import-check`

The rule prevents imports from folders meant for incompatible runtimes.
The check enforces the [code organization guidelines](https://github.com/eclipse-theia/theia/wiki/Code-Organization) of the framework and guards against invalid imports which may cause unforeseen issues downstream.

#### `shared-dependencies`

The rule prevents the following:

- prevents the implicit use of a shared dependency from `@theia/core`.
- prevents extensions from depending on a shared dependency without re-using it from `@theia/core`.

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.org/theia>

---

## File: dev-packages/ovsx-client/README.md

## Description

The `@theia/ovsx-client` package is used to interact with `open-vsx` through its REST APIs.
The package allows clients to fetch extensions and their metadata, search the registry, and
includes the necessary logic to determine compatibility based on a provided supported API version.

Note that this client only supports a subset of the whole OpenVSX API, only what's relevant to
clients like Theia applications.

### `OVSXRouterClient`

This class is an `OVSXClient` that can delegate requests to sub-clients based on some configuration (`OVSXRouterConfig`).

```jsonc
{
    "registries": {
        // `[Alias]: URL` pairs to avoid copy pasting URLs down the config
    },
    "use": [
        // List of aliases/URLs to use when no filtering was applied.
    ],
    "rules": [
        {
            "ifRequestContains": "regex matched against various fields in requests",
            "ifExtensionIdMatches": "regex matched against the extension id (without version)",
            "use": [/*
                List of registries to forward the request to when all the
                conditions are matched.

                `null` or `[]` means to not forward the request anywhere.
            */]
        }
    ]
}
```

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.org/theia>

---

## File: dev-packages/localization-manager/README.md

## Description

The `@theia/localization-manager` package is used easily create localizations of Theia and Theia extensions for different languages. It has two main use cases.

First, it allows to extract localization keys and default values from `nls.localize` calls within the codebase using the `nls-extract` Theia-CLI command. Take this code for example:

```ts
const hi = nls.localize('greetings/hi', 'Hello');
const bye = nls.localize('greetings/bye', 'Bye');
```

It will be converted into this JSON file (`nls.json`):

```json
{
  "greetings": {
    "hi": "Hello",
    "bye": "Bye"
  }
}
```

Afterwards, any manual or automatic translation approach can be used to translate this file into other languages. These JSON files are supposed to be picked up by `LocalizationContribution`s.

Additionally, Theia provides a simple way to translate the generated JSON files out of the box using the [DeepL API](https://www.deepl.com/docs-api). For this, a [DeepL free or pro account](https://www.deepl.com/pro) is needed. Using the `nls-localize` command of the Theia-CLI, a target file can be translated into different languages. For example, when calling the command using the previous JSON file with the `fr` (french) language, the following `nls.fr.json` file will be created in the same directory as the translation source:

```json
{
  "greetings": {
    "hi": "Bonjour",
    "bye": "Au revoir"
  }
}
```

Only JSON entries without corresponding translations are translated using DeepL. This ensures that manual changes to the translated files aren't overwritten and only new translation entries are actually sent to DeepL.

Use `theia nls-localize --help` for more information on how to use the command and supply DeepL API keys.

For more information, see the [internationalization documentation](https://theia-ide.org/docs/i18n/).

## Additional Information

- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.org/theia>

---

## File: dev-packages/ffmpeg/README.md

# `ffmeg.node`

This is a [Node Native Addon](https://nodejs.org/docs/latest-v14.x/api/n-api.html) to dynamically link to Electron's `ffmpeg.dll` and fetch a list of included codecs.

## 2. Official Technical Reference & Guides (eclipse-theia/theia-website)

## File: README.md

# Theia's Website

The source for the [website](https://theia-ide.org) and [online documentation](https://theia-ide.org/docs/) for the [Theia IDE Framework](https://github.com/eclipse-theia/theia).

## Work locally

Building locally requires node 14.x. Alternatively, you can use `npm i --legacy-peer-deps` to ignore conflicting peer dependencies.

```bash
npm install && npm run start
```

To build for production and serve, run:

```bash
npm run build
npm run serve
```

## CI

The website is automatically built with [Github workflows](.github/workflows/) and deployed on Github pages, which are reachable via [theia-ide.org](https://theia-ide.org/).

A preview of every pull request is published at [eclipse-theia/theia-website-previews](https://github.com/eclipse-theia/theia-website-previews). You'll see a comment with the link to the preview once the build is finished.
For more information, see [`publish.yml`](.github/workflows/publish.yml) and [`preview.yml`](.github/workflows/preview.yml).

## License

- [Eclipse Public License 2.0](LICENSE)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](LICENSE)

## Trademark

"Theia" is a trademark of the Eclipse Foundation
<https://www.eclipse.dev/theia>

---

## File: src/docs/architecture.md

---
title: Architecture Overview
---

# Architecture Overview

This section describes the overall architecture of the Theia Platform.

Theia is designed to work as a native desktop application as well as in the
context of a browser and a remote server. To support both situations with a
single source, Theia runs in two separate processes. Those processes are called
_frontend_ and _backend_ respectively, and they communicate through JSON-RPC
messages over WebSockets or REST APIs over HTTP. In the case of Electron, the
backend, as well as the frontend, run locally, while in a remote context the
backend would run on a remote host.

Both the frontend and backend processes have their dependency injection (DI)
container (see below) to which extensions can contribute.

## Frontend

The frontend process represents the client and renders the UI. In the browser,
it simply runs in the rendering loop, while in Electron it runs in an Electron
Window, which basically is a browser with additional Electron and Node.js APIs.
Therefore, any frontend code may assume browser as a platform but not Node.js.

The startup of the frontend process will first load the DI modules of all
contributing extensions before it obtains an instance of `FrontendApplication`
and call `start()` on it.

## Backend

The backend process runs on Node.js. We use _express_ as the HTTP server. It
may not use any code that requires a browser (DOM API) as the platform.

The startup of the backend application will first load the DI modules of all
contributing extensions before it obtains an instance of `BackendApplication`
and calls `start(portNumber)` on it.

By default, the backend's express server also serves the code for the frontend.

## Separation By Platform

In an extension's top folder we have an additional layer of folders to separate
by platform:

- The `common` folder contains code that doesn't depend on any runtime.
- The `browser` folder contains code requiring a modern browser as a platform
   (DOM API).
- The `electron-browser` folder contains frontend code that requires DOM API
   as well as Electron renderer-process specific APIs.
- The `node` folder contains (backend) code requiring Node.js as a platform.
- The `node-electron` folder contains (backend) code specific for Electron.

## See also

For a high level overview of Theia's Architecture, see this document:

[Multi-Language IDE Implemented in JS - Scope and Architecture](https://docs.google.com/document/d/1aodR1LJEF_zu7xBis2MjpHRyv7JKJzW7EWI9XRYCt48)

---

## File: src/docs/authoring_extensions.md

---
title: Authoring an Extension
---

# Authoring Theia Extensions

This guide will walk you through the process of creating Theia extensions and deploying them in your Theia-based application. Please make sure to be aware of [how to create a Theia based application](/docs/composing_applications/) and the [different available extension mechanisms](/docs/extensions/) of Theia (Plugins vs. Extensions) before you continue reading.

As an example, we are going to add a menu item _Say hello_ that displays a notification "Hello world!". This article is guiding you through all the necessary steps.

## Prerequisites

Prerequisites information are available from the [Theia repository](https://github.com/eclipse-theia/theia/blob/master/doc/Developing.md#prerequisites).

## Project Layout

Please refer to the [guide to create Theia applications](/docs/composing_applications/) to get familiar with the default project layout and generate a Theia project with the example 'hello world' extension using our [Yeoman Generator](https://github.com/eclipse-theia/generator-theia-extension)

## A Custom Theia Extension

Let's look at the generated code for our extension in the `hello-world` folder. Let’s start with the `package.json`. It specifies the package’s metadata, its dependencies to the  Theia core package, a few scripts and dev dependencies, and the theia-extension itself. Please note that the following listing might be outdated, please always refer to the generated examples from our [Yeoman Generator](https://github.com/eclipse-theia/generator-theia-extension)

The keyword `theia-extension` is important: It allows a Theia app to identify and install Theia extensions from `npm`.

```json
{
  "name": "hello-world",
  "keywords": [
    "theia-extension"
  ],
  "version": "0.0.0",
  "files": [
    "lib",
    "src"
  ],
  "dependencies": {
    "@theia/core": "latest"
  },
  "devDependencies": {
    "rimraf": "latest",
    "typescript": "~5.4.5"
  },
  "scripts": {
    "prepare": "yarn run clean && yarn run build",
    "clean": "rimraf lib",
    "build": "tsc",
    "watch": "tsc -w"
  },
  "theiaExtensions": [
    {
      "frontend": "lib/browser/hello-world-frontend-module"
    }
  ]
}
```
As you can see, the extension is a dedicated package that just depends on Theia. However, as the extension contributes features to our application, it needs to be wired a runtime. To achive this in a modular way, in Theia, everything is wired up via [dependency injection](/docs/services_and_contributions#dependency-injection-di). An extension defines one or more dependency injection modules. This is where it binds its contribution implementations to the respective contribution interface. The modules are listed in the `package.json` of the extension package. An extension can contribute to the frontend, e.g. providing a UI extension, as well as to the backend, e.g. contributing a language server. When the application starts, the union of all these modules is used to configure a single, global dependency injection container on each, the frontend and the backend. The runtime will then collect all contributions of a specific kind by means of a multi-inject.

The last property `theiaExtensions` in the `package.json` above is where we list the JavaScript modules that export the DI modules defining the contribution bindings of our extension. In our case, we only provide a frontend capability (a command and a menu entry). Analogously, you could also define contributions to the backend, e.g. a language contribution with a language server.

Theia defines a plethora of contribution interfaces that allow extensions to add their behaviour to various aspects of the application. Browse the documentation section 'Platform Concepts & APIs' or search for interfaces with the name `*Contribution` to get an idea. An extension implements the contribution interfaces belonging to the functionality it wants to deliver. In this example, we are going to implement a `CommandContribution` and a `MenuContribution`. Other ways for extensions to interact with a Theia application are via one of the various _services_ or _managers_.

In the frontend module we export a default object that is a [InversifyJS `ContainerModule`](https://github.com/inversify/InversifyJS/blob/master/wiki/container_modules.md) with bindings for a command contribution and a menu contribution. Please see our [dependency injection guide](/docs/services_and_contributions/) for more details.

```typescript
export default new ContainerModule(bind => {
    // add your contribution bindings here
    bind(CommandContribution).to(HelloWorldCommandContribution);
    bind(MenuContribution).to(HelloWorldMenuContribution);
});
```

A command is a plain data structure defining an ID and a label. The behaviour of a command is implemented by registering a handler to its ID in a command contribution. The generator has already added a command and a handler that shows a "Hello World!" message.

```typescript
export const HelloWorldCommand = {
    id: 'HelloWorld.command',
    label: "Shows a message"
};

@injectable()
export class HelloWorldCommandContribution implements CommandContribution {

    constructor(
        @inject(MessageService) private readonly messageService: MessageService,
    ) { }

    registerCommands(registry: CommandRegistry): void {
        registry.registerCommand(HelloWorldCommand, {
            execute: () => this.messageService.info('Hello World!')
        });
    }
}
...
```

Note how we use `@inject` in the constructor to get the `MessageService` as a property, and how we use that later in the implementation of the handler. This is the elegance of dependency injection: As a client, we neither care where these dependencies come from nor what their lifecycle is.

To make it accessible by the UI, we implement a `MenuContribution`, adding an item to the Search/Replace section of the edit menu in the menu bar.

```typescript
...
@injectable()
export class HelloWorldMenuContribution implements MenuContribution {

    registerMenus(menus: MenuModelRegistry): void {
        menus.registerMenuAction(CommonMenus.EDIT_FIND, {
                commandId: HelloWorldCommand.id,
                label: 'Say Hello'
            });
    }
}
```

## Adding Extensions to a Theia application

To make sure your extension is included in your Theia application, list it as a dependency in your browser or electron app, e.g. like this:

```json
{
  "private": true,
  "name": "browser-app",
  "version": "0.0.0",
  "dependencies": {
    "@theia/core": "latest",
    ...
    "hello-world": "0.0.0"
  },
  "devDependencies": {
    "@theia/cli": "latest"
  },
  "scripts": {
    "bundle": "yarn rebuild && theia build --mode development",
    "rebuild": "theia rebuild:browser --cacheRoot ..",
    "start": "theia start",
    "watch": "yarn rebuild && theia build --watch --mode development"
  },
  "theia": {
    "target": "browser"
  }
}
```

## Deploying the Extension

To run the extension, you have two options:
1. Have your extension as part of a monorepo containing a Theia-based application importing your extension (like the structure created by the Yeoman Generator)
2. Publish the extension with `yarn publish` and consume it from your Theia-based application

See [*Executing the Browser Application*](/docs/composing_applications/#executing-the-browser-application) and [*Executing the Extension in Electron* for more details*](/docs/composing_applications/#executing-the-extension-in-electron) for adding extensions to the dependencies of a Theia-based application and running it.

---

## File: src/docs/authoring_plugins.md

---
title: Authoring Plug-ins
---

# Authoring Theia Plug-ins

This documentation is deprecated and needs to be updated. We currently recommend using VS Code extensions or Theia extensions instead of Theia Plugins. See the [extension overview](/docs/extensions/) for more details.

---

## File: src/docs/authoring_vscode_extensions.md

---
title: Authoring VS Code Extensions
---

# Authoring VS Code Extensions

Alongside [Theia extensions](/docs/extensions#theia-extensions), VS Code extensions can also be used to enhance Theia applications with additional functionality, such as language support, commands, or tree views.
VS Code extensions contribute functionality through the dedicated VS Code API, which the Theia framework also supports.
This means that extensions that have been developed for VS Code are also compatible with Theia, and vice versa.
The [coverage report](https://eclipse-theia.github.io/vscode-theia-comparator/status.html) provides more details on the extent to which the VS Code API is supported by each Theia version.

While there are certain overlaps in which types of functionality can be contributed to a Theia application with a Theia extension or a VS Code extension, both have their unique advantages and disadvantages.
Please refer to the overview on [extensions and plugins](/docs/extensions) and an [in-depth comparison](https://eclipsesource.com/blogs/2021/03/24/vs-code-extensions-vs-theia-extensions/) for a more detailed discussion.

In the remainder of this page, we guide you through the process of creating VS Code extensions and deploying them in Theia.
The steps for deploying VS Code extensions apply not only to VS Code extensions you develop yourself, but also to third-party VS Code extensions from the [Theia marketplace](https://open-vsx.org/). If you use a third-party VS Code extension, you can skip the section "Creating VS Code Extensions" and "Developing VS Code Extensions in a Theia Project".

## Creating VS Code Extensions

As VS Code extensions can be used in Theia without further modification, you can refer to the [documentation on extending VS Code](https://code.visualstudio.com/api) to learn more about creating extensions for VS Code as well as for Theia.
The easiest way to get started is to use the [VS Code Extension Generator](https://www.npmjs.com/package/generator-code) and follow the [Getting Started Guide](https://code.visualstudio.com/api/get-started/your-first-extension).

Since Theia 1.72, VS Code extensions delivered as **ECMAScript Modules** (ESM) are supported. Extensions whose entry point ends in `.mjs`, or whose `package.json` declares `"type": "module"`, are loaded via dynamic `import()`. The `import 'vscode'` resolution is wired up by an internal Node loader hook, so both CommonJS and named ESM imports (`import { commands, window } from 'vscode'`) work without any changes on the extension side. ESM-based built-ins such as the GitHub authentication extension load correctly out of the box.

As an example, let's generate the hello world extension.

```bash
npm install yo generator-code # install the VS Code Extension Generator
npm install vsce # install VS Code Extension CLI tooling

yo code # generate an extension
# take a look at the generated package.json defining a command "Hello World"
# take a look at the src/extension.ts registering a command handler
# make changes to the README and the code, if you like
vsce package # package your VS Code extension
```

As a result, a `vsix` file is generated, which can be used directly in VS Code. For Theia, the extension can be installed at runtime by users (see [Installing VS Code Extensions at Runtime](#installing-vs-code-extensions-at-runtime)), downloaded automatically at build time from a registry (see [Pre-installing VS Code Extensions](#pre-installing-vs-code-extensions)), or manually unpacked for pre-installation.
Please note that you can also create so-called extension packs with the VS Code extension generator that defines a collection of extensions.

### Conditional View Containers via `when` Clauses

VS Code's `contributes.viewsContainers` entries support an optional `when` clause that controls visibility based on context keys. Theia honors this field: a container with a `when` clause that evaluates to `false` is not attached, does not appear in the View menu or the *Open View* quick pick, and is automatically created or disposed as the underlying context keys change. This is useful for extensions that contribute mutually exclusive containers (for example one for the primary sidebar and one for the secondary sidebar guarded by negated context keys), so that only the active one is shown.

```jsonc
{
    "contributes": {
        "viewsContainers": {
            "activitybar": [
                {
                    "id": "my-sidebar",
                    "title": "My View",
                    "icon": "resources/icon.svg",
                    "when": "!myExtension.useSecondarySidebar"
                }
            ],
            "panel": [
                {
                    "id": "my-sidebar-secondary",
                    "title": "My View",
                    "icon": "resources/icon.svg",
                    "when": "myExtension.useSecondarySidebar"
                }
            ]
        }
    }
}
```

### Language Model Tools

VS Code extensions can contribute tools for AI agents through the language model tools API (`vscode.lm.registerTool` and `vscode.lm.invokeTool`). Theia supports this API and integrates the registered tools with Theia AI: a tool registered by an extension can be referenced in a user or system prompt via the `~{toolId}` syntax and is then invoked by the language model like any built-in tool. The tool id is also offered in the chat input auto-completion.

This lets VS Code extensions extend the AI features of a Theia-based product with custom tools, without depending on Theia-specific APIs.

## Prerequisites for Running VS Code Extensions in Theia

To enable Theia's support for VS Code extensions in order to use your own extensions or third-party VS Code extensions in your Theia application, you'll need to add `@theia/plugin-ext-vscode` as a dependency.
Typically, this is done in your browser or electron application package.

```json
{
  ...
  "name": "browser-app",
  "dependencies": {
    "@theia/core": "latest",
    ...
    "@theia/plugin-ext-vscode": "latest"
  },
  "theia": {
    "target": "browser"
  }
}
```

Next, you need to specify a *plugins location*, which is a disk location containing your VS Code extensions.
Theia will load all VS Code extensions from this location on initialization of a new user session automatically.
This location can be set either with an environment variable:

```bash
export THEIA_DEFAULT_PLUGINS=local-dir://absolute-path-to-plugins-folder
```

Or it can be provided in the command line option `--plugins` when starting Theia.

```bash
theia start --plugins=local-dir:../plugins
```

A common approach for Theia applications that include VS Code extensions is to add this command line parameter to the startup script in the browser or electron application package.

```json
{
  ...
  "name": "browser-app",
  ...
  "scripts": {
    ...
    "start": "theia start --plugins=local-dir:../plugins",
  },
  "theia": {
    "target": "browser"
  }
}
```

## Consuming VS Code Extensions

Once you've enabled VS Code extension support in your Theia application as described above and made available your or any third-party VS Code extensions that you'd like to use in your Theia application, you have two options on how to consume them:

  1. Pre-installing the VS Code extension in your Theia application
  2. Enabling your users to install your VS Code extensions at runtime

In the following, we'll provide more details on each of those options.

### Pre-installing VS Code Extensions

For pre-installing a certain set of VS Code extensions in your Theia application, you need to place them as **unpacked folders** into the *plugins location* (see [prerequisites](#prerequisites-for-running-vs-code-extensions-in-theia)).
On start-up of a user session, Theia will load all VS Code extensions from that location automatically.

**Note:** `.vsix` files placed in the plugins location will **not** be automatically unpacked and loaded. If you have a `.vsix` file, you must manually unpack it first before placing it in the plugins location. Attempting to use `.vsix` files directly will result in a warning message: `"Only user plugins will be handled by file handlers, please unpack the plugin manually."`

A more systematic approach, however, is to publish VS Code extensions, to [OpenVSX](https://open-vsx.org), GitHub Releases, or any other accessible location, and download them automatically at build time of the Theia application with the Theia CLI.
See [publishing extensions to OpenVSX](https://github.com/eclipse/openvsx/wiki/Publishing-Extensions) for more details.
This approach avoids having to manually distribute VS Code extensions or adding them in the form of a build artifact to your git repository.

Therefore, you need to extend your `package.json` to

  1. specify the *plugins location* to the Theia CLI
  2. define the VS Code extensions to be downloaded
  3. add a download script for convenience

```json
{
  ...
  "scripts": {
    "prepare": "yarn run clean && yarn build && yarn run download:plugins",
    "download:plugins": "theia download:plugins",
    ...
  },
  "theiaPluginsDir": "plugins",
  "theiaPlugins": {
      "my-hello-world-extension": "https://",
      "vscode.git": "https://open-vsx.org/api/vscode/git/1.52.1/file/vscode.git-1.52.1.vsix",
      ...
  }
}
```

As a result, running `yarn` will download any listed extensions (including `.vsix` files from URLs) and automatically unpack them into the folder specified in `theiaPluginsDir`.
For more details, see also the documentation on [composing Theia applications](/docs/composing_applications/#consuming-vs-code-extensions).

### Installing VS Code Extensions at Runtime

One of the unique advantages of VS Code extensions is that they can be installed and uninstalled by users at runtime.
To enable the users of your Theia application to install VS Code extensions at runtime, you have to add `@theia/vsx-registry` as a dependency to your `package.json`.

```json
{
  ...
  "name": "browser-app",
  "dependencies": {
    "@theia/core": "latest",
    ...
    "@theia/vsx-registry": "latest"
  },
  "theia": {
    "target": "browser"
  }
}
```

This dependency will add a view *Extensions* to your application, which allows searching and installing extensions from an OpenVSX registry.
By default, the public registry at <http://open-vsx.org> is used, the registry URL be configured via the environment variable `VSX_REGISTRY_URL`.
Please confer to the [OpenVSX extension documentation](https://www.npmjs.com/package/@theia/vsx-registry) for more details.

To make your VS Code extension available, you'll need to [publish](https://github.com/eclipse/openvsx/wiki/Publishing-Extensions) your extension to the configured registry.

## Developing VS Code Extensions in a Theia Project

In certain scenarios, you may not want to develop your VS Code extension in isolation from your Theia application, but instead you may prefer to develop both your extensions and your application in project to keep update cycles short and immediate.
This is particularly useful if you develop your extensions primarily to be part a specific Theia application, thus you want to develop, test and debug them directly in the context of your Theia app, potentially alongside other [Theia extensions](/docs/extensions#theia-extensions).

In those scenarios, you can also include VS Code extensions as part of your Theia application monorepo.
While there are several possible configuration options, probably the most straightforward approach is to follow the steps below.

Generate your VS Code extension as usual.
However, to make things easier and consistent, choose `TypeScript` as your language and `yarn` as a package manager for your VS Code extension to be aligned with a typical Theia application.

Put your VS Code extension package, let's say `your-vs-code-extension`, into your monorepo, alongside your other packages and make sure it is part of your yarn workspaces.
Let's assume, we eventually have the following a directory structure.

```text
monorepo
├── apps
│   ├── browser-app
│   └── electron-app
├── extensions
│   ├── your-theia-extension
│   └── your-vs-code-extension
├── plugins
└── package.json
```

In `your-vs-code-extension/package.json`, add `symlink` as a dev dependency to link your extension into the *plugins location* of your Theia application on each build.

```json
{
    ...
    "scripts": {
        "compile": "tsc -p ./",
        "watch": "tsc -watch -p ./",
        "prepare": "yarn run clean && yarn run build && yarn symlink",
        "symlink": "symlink-dir . ../../plugins/your-vs-code-extension",
        ...
    },
    "devDependencies": {
        "@types/vscode": "^1.32.0",
        "symlink-dir": "latest",
        ...
    }
}
```

With that, your VS Code extension will be built as part of your Theia application and directly added to the *plugins location* for automatic installation in your Theia application.
This leads to a consistent development experience, even if you have multiple VS Code extensions and Theia extensions combined in one Theia application.

If you aim at a consistent `tsconfig.json` across your VS Code extension and a typical Theia extension, you may want to change the `outDir` from `out` (default in VS Code) to `lib` (commonly used in Theia) and adjust the `package.json` accordingly.

To also enable debugging from your development IDE (VS Code), you need to setup `launch.json` to include the VS Code extension in the `outFiles` (if it is still building to the folder `out` and not `lib`) and enable source maps.

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Start Browser Backend",
            "program": "${workspaceRoot}/browser-app/src-gen/backend/main.js",
            "args": [
                "--loglevel=debug",
                "--port=3000",
                "--no-cluster",
                "--plugins=local-dir:${workspaceRoot}/plugins"
            ],
            "env": {
                "NODE_ENV": "development",
                "NODE_OPTIONS": "--enable-source-maps"
            },
            "sourceMaps": true,
            "outFiles": [
                "${workspaceRoot}/node_modules/@theia/*/lib/**/*.js",
                "${workspaceRoot}/extensions/*/lib/**/*.js",
                "${workspaceRoot}/extensions/*/out/**/*.js",
                "${workspaceRoot}/apps/*/src-gen/**/*.js"
            ],
            "smartStep": true,
            "internalConsoleOptions": "openOnSessionStart",
            "outputCapture": "std"
        },
        ...
    ]
}
```

## Troubleshooting

### Plugins not appearing

If no plugins are available in the running Theia instance, it may be that you need to tell Theia where to find the downloaded plugins.
The example above sets the `--plugins` switch in the `start` command which should be sufficient.
However, if running `theia start` directly, you can alternatively set an environment variable to achieve the same thing:

    export THEIA_DEFAULT_PLUGINS=local-dir:plugins

---

## File: src/docs/backend_application_contribution.md

---
title: Backend Application Contributions
---

# Backend Application Contributions

A backend application contribution allows Eclipse Theia extensions to hook into the lifecycle of the Theia backend. Backend application contributions are instantiated immediately after starting the backend application, which makes them a good place for initializing backend services that are required during the entire lifespan of the backend.

To register backend application contributions, an extension needs to bind an implementation of the interface `BackendApplicationContribution` in the backend module.

``` typescript
export default new ContainerModule(bind => {
   bind(MemoryTracker).toSelf().inSingletonScope();
   bind(BackendApplicationContribution).toService(MemoryTracker);
});
```

The interface `BackendApplicationContribution` provides hooks, which are all optional so that implementations can freely choose which of those hooks they are interested in, without having to implement the others.
For initialization of backend services, the most common hook is the `initialize()` method that is invoked as soon as the Theia backend is initialized.

As an example, let’s implement a backend service that shall run during the entire lifespan of the Theia backend to track its memory usage.
For the sake of simplicity it will just print the memory to the log, whenever it changes more than a certain threshold.

Therefore, a `BackendApplicationContribution` named `MemoryTracker` is bound in the dependency injection context as shown in the code above.
The implementation of `MemoryTracker` reacts to the hook `initialize()` and executes the method `logMemory()` periodically every two seconds.
This method obtains the currently used memory, compares it to the previous memory and prints a message to the log as soon as the difference to the previous memory is above 0.1 MB.

``` typescript
@injectable()
export class MemoryTracker implements BackendApplicationContribution {

   @inject(ILogger)
   protected readonly logger: ILogger;
   protected logTimer: NodeJS.Timer;
   protected memoryUsed = 0;

   initialize(): MaybePromise<void> {
       this.logTimer = setInterval(() => this.logMemory(), 2000);
   }

   protected logMemory(): void {
       const currentMemoryUsed = this.currentRoundedMemoryUsage();
       const diff = currentMemoryUsed - this.memoryUsed;
       if (Math.abs(diff) > 0.1) {
           const timestamp = new Date().toUTCString();
           this.logger.info(
               `[${timestamp}] PID ${process.pid} uses ${currentMemoryUsed} MB (${diff > 0 ? '+' : ''}${diff.toFixed(2)})`
           );
           this.memoryUsed = currentMemoryUsed;
       }
   }

   protected currentRoundedMemoryUsage() {
       return Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100;
   }

   onStop(): void {
       if (this.logTimer) {
           clearInterval(this.logTimer);
       }
   }
}
```

Once this backend application contribution is registered and the backend is started, it starts logging an output, similar to the following:

```
root INFO Theia app listening on http://localhost:3000.
root INFO Configuration directory URI: 'file:///home/foobar/.theia'
root INFO [Fri, 20 Aug 2021 12:20:43 GMT] PID 46590 uses 18.14 MB (+18.14)
root INFO [Fri, 20 Aug 2021 12:20:47 GMT] PID 46590 uses 18.94 MB (+0.80)
root INFO [Fri, 20 Aug 2021 12:20:51 GMT] PID 46590 uses 15.25 MB (-3.69)
root INFO [Fri, 20 Aug 2021 12:21:07 GMT] PID 46590 uses 15.36 MB (+0.11)
root INFO [Fri, 20 Aug 2021 12:21:21 GMT] PID 46590 uses 15.47 MB (+0.11)
root INFO [Fri, 20 Aug 2021 12:21:41 GMT] PID 46590 uses 15.6 MB (+0.13)
root INFO [Fri, 20 Aug 2021 12:21:59 GMT] PID 46590 uses 15.71 MB (+0.11)
```

Often such backend application contributions also provide methods that can be invoked by other backend services and, for instance, start external processes that need to be available as soon as the application is started.
Examples are database connections, REST services, etc.

In addition to initializing backend services as early as the backend is started, backend application contributions can also configure and extend the HTTP server used by the Theia backend.
Therefore, the `BackendApplicationContribution` interface provides the three methods `configure(app: express.Application)`, `onStart(app: express.Application)`, and `onStop(app: express.Application)`.
Thus, the HTTP server can be configured with custom settings and even extended with additional endpoints that need to be available for the respective Theia application.

An example for configuring an additional endpoint named `/myendpoint` is given below.

``` typescript
import { injectable } from '@theia/core/shared/inversify';
import { json } from 'body-parser';
import { Application, Router } from '@theia/core/shared/express';
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';

@injectable()
export class MyCustomEndpoint implements BackendApplicationContribution {
   configure(app: Application): void {
       app.get('/myendpoint', (request, response) => {
           …
       });
   }
}
```

For more information on how to configure HTTP endpoints and handle events requests, please refer to the [Express API](https://expressjs.com/en/4x/api.html).

---

## File: src/docs/blueprint_documentation.md

---
title: Extending/Adopting the Theia IDE
---

# Extending/Adopting the Theia IDE

This guide provides an overview on how to extend and customize the Theia IDE to your own custom IDE or tool. In this scenario, the Eclipse Theia IDE is an example product used as a reference on how to build desktop IDE-like products based on the Eclipse Theia framework. If you just want to use the Theia IDE, see the [user guide](/docs/user_getting_started)

Please note that adopting the Theia IDE as a basis is just one of several ways to get started with building a Theia-based application. We recommend reading the article "[Build your own IDE/Tool](/docs/composing_applications)" as a first step. Furthermore, this guide is focused on building a desktop app. We also provide an [experimental Docker version](https://github.com/eclipse-theia/theia-blueprint?tab=readme-ov-file#docker) of the Theia IDE as an alternative.

The Theia IDE assembles a selected subset of existing Theia features and extensions.
We provide installers for the Theia IDE to be downloaded (see links below).
In the [respective git repository](https://github.com/eclipse-theia/theia-blueprint) you can also find the [source code for the Theia IDE and its installers](https://github.com/eclipse-theia/theia-blueprint).

This documentation will use these sources as a template. We will explain
how to customize this template so that you can build your own custom Theia-based product including installers and packaging for installing the desktop-based version of your custom product on all major operating systems. Please note that the technical name (e.g. in the source code) for the Theia IDE is "Theia Blueprint" to avoid confusion with the generic term "IDE".

- [Building a product and installers](#building-a-product-and-installers)
- [Signing](#signing)
- [Adding/removing Features](#addingremoving-features)
- [Updating Bundled VS Code Extensions](#updating-bundled-vs-code-extensions)
- [Customizing Theia Extensions](#customizing-theia-extensions)
- [Branding](#branding)
- [Configure Publish and Update](#configure-publish-and-update)

## Building a product and installers

The Theia IDE build uses [electron-builder](https://www.electron.build/) to package the product as a desktop application.

The product can be built and packaged with [yarn](https://yarnpkg.com/).
Note that you usually can only package the product for the operating system you execute the build on.
For more information see the [electron-builder documentation on multi-platform builds](https://www.electron.build/multi-platform-build).

The following commands may be run from the root directory of the repository.

To install dependencies and build the application, simply execute `yarn`.

You can also directly run the unpackaged application, e.g. to test it during development with `yarn electron start`.

With `yarn electron package`, you package the application into an executable file for your current operating system.
The packaged application will be located in `applications/electron/dist`.
The folder `applications/electron/dist/<OS>-unpackaged` will contain the files that are bundled into the final packaged executable.
For Linux, this is an executable `.AppImage`, for Windows a `.exe` installer, and a `.dmg` disk image for macOS.

You can also just create the unpackaged content by running `yarn electron package:preview`.
This is useful to see the bundled files and saves time compared to a full package.
To publish the current version, the command `yarn electron deploy` can be used.
For more information on publishing also see section "Configure publish and update".

## Signing

[Electron-builder](https://www.electron.build/) supports signing the packaged application on Windows and macOS.
The current signing scripts for the Theia IDE are located in `applications/electron/scripts`.
The file `after-pack.js` is the current entry point for the configured signing via Eclipse infrastructure.

However, as signing is highly dependent on your setup, see the [electron builder’s signing documentation](https://www.electron.build/code-signing) on how to properly set up your own signing.

## Adding/Removing Features

The Theia IDE is based on the Theia platform, which is a flexible and adaptable platform for build tools and IDEs. Therefore, you can adapt the feature set and general appearance of the Theia IDE to your custom requirements with almost no limits. The Theia platform provides two mechanism to add your custom extensions: VS Code extensions and Theia extensions. Please have a look at the [overview about Theia extension capabilities](/docs/extensions/) for details. When assembling a product such as the Theia IDE, you can freely decide, which VS Code extensions and Theia extensions are part of it and thereby influence the feature set of your custom product. The following two sections describe how to modify which [VS Code Extensions](#updating-bundled-vs-code-extensions) and which [Theia extensions](#customizing-theia-extensions) are part of your product. Please also note that you can allow users of a Theia-based tool to [install VS Code extensions at runtime](/docs/user_install_vscode_extensions/).

## Updating Bundled VS Code Extensions

All VS Code extensions that are already included in the product at start-up ("built-ins"), are defined in `applications/electron/package.json`.
They are listed under the `theiaPlugins` property as key-value pairs.
The keys can be freely chosen as long as they represent a valid folder name and are unique within the `theiaPlugins` property.
We suggest using the extension’s unique identifier.
The value is the download URL of the extensions.
It will automatically be downloaded during the application’s build process.
Any new plugin will be automatically downloaded the next time one of the following npm scripts is executed:

- `install` (which is the same as just running `yarn`)
- `prepare`
- `download:plugins`

To remove an extension from the product, simply delete its entry.
If plugins were not already downloaded, no further steps are required as downloaded plugins are ignored via gitignore.
However, previously downloaded plugins are not automatically removed.
Therefore, you need to remove its folder from the `applications/electron/plugins` folder.
Alternatively, you can remove the whole `applications/electron/plugins` folder and execute `yarn electron download:plugins` to download all defined plugins.

### Extension sources

We use the [Open VSX Registry](https://open-vsx.org/) of the Eclipse Foundation to install extensions.
It is an open and community-driven VS Code extension marketplace.
More information can be found at [eclipse.org](https://www.eclipse.org/legal/open-vsx-registry-faq/).

## Customizing Theia Extensions

Eclipse Theia extensions can be added through `dependencies` in `applications/electron/package.json`.
Like any other dependency, it will be installed via yarn.
Similarly, removing an extension works by removing it from `dependencies`.
For extensions already published on npm (or your private npm registry) this is all you need to do.

An alternative approach is developing your extension inside Theia IDE's mono repo.
The advantage of doing this is that you don't need to publish the extension and can build the product with the local version of the extension.
This is facilitated by the lerna build already configured in the Theia IDEs's repository.
It links the product and all extensions in the repository together during the build.

### Adding Yeoman-Generated Extensions to Theia IDE

Many users start with the [Yeoman generator](https://www.npmjs.com/package/generator-theia-extension) as described in [Build your own IDE/Tool](/docs/composing_applications), and later want to integrate their extensions into the Theia IDE. This section explains how to add an existing Yeoman-generated extension to your custom Theia IDE.

#### Prerequisites

- You have a Yeoman-generated Theia extension (created with `yo theia-extension --standalone`)
- You have cloned the [Theia IDE repository](https://github.com/eclipse-theia/theia-blueprint)

#### Step-by-Step Integration

1. **Move your extension into the Theia IDE repository**

   Copy your extension folder into the `theia-extensions` directory of the Theia IDE repository. For example, if your extension is called `hello-world`, copy it so it becomes `theia-extensions/hello-world`.

2. **Verify workspace configuration**

   The Theia IDE's root `package.json` already includes `theia-extensions/*` in its workspaces configuration, so your extension is automatically recognized. No manual editing of the workspaces array is needed.

3. **Find your extension's name and version**

   Open your extension's `package.json` file (e.g., `theia-extensions/hello-world/package.json`) and look for the `name` and `version` fields:

   ```json
   {
     "name": "hello-world",
     "version": "0.0.0",
     ...
   }
   ```

   You will need these values in the next step.

4. **Add your extension as a dependency**

   Open `applications/electron/package.json` (for the desktop application) or `applications/browser/package.json` (for the browser application), or both if you want your extension in both versions.

   Add your extension to the `dependencies` section using the name and version from the previous step:

   ```json
   "dependencies": {
     ...
     "theia-ide-launcher-ext": "1.65.100",
     "theia-ide-product-ext": "1.65.100",
     "theia-ide-updater-ext": "1.65.100",
     "hello-world": "0.0.0"
   }
   ```

5. **Install dependencies and build**

   From the repository root, run:

   ```bash
   yarn && yarn build
   ```

   This will install all dependencies, link your extension with the Theia IDE, and build the application with your extension included.

6. **Run and test**

   Start the Theia IDE to test your extension:

   ```bash
   yarn (browser|electron) start
   ```

   Your extension's features should now be available in the Theia IDE.

#### Important Notes

- **Version Compatibility**: Check that your extension's `@theia/core` dependency version (in your extension's `package.json`) is compatible with the Theia version used by the Theia IDE. You may need to update the version if they differ significantly.
- **Browser and Electron**: Remember to add your extension to both `applications/browser/package.json` and `applications/electron/package.json` if you want it available in both versions.
- **Always Build**: Always run `yarn && yarn build` after adding new extensions before starting the application.
- **Monorepo Structure**: Once your extension is in the `theia-extensions` folder, it becomes part of the monorepo and will be built alongside other extensions.

## Branding

You can also add your own branding to the product by customizing the application icons and title, the welcome page and the About dialog.
In addition, some parts of the installer can be customized.

### Customizing the App

#### Application Window Title

The window title is the application’s name if no workspace is opened and `<workspace name> — <application name>` if a workspace is opened.
The application name can be adapted in `applications/electron/package.json` by navigating through the nested properties.

To change the application name, open the file and locate the following nested structure:

```json
  "theia": {
    "frontend": {
      "config": {
        "applicationName": "Theia IDE",
      },
    },
  },
```

Change the value of `applicationName` to the desired name.
Also see [the structure in the original file](https://github.com/eclipse-theia/theia-blueprint/blob/ed203687bad53fdbd22012926978ac40d7d8cd23/applications/electron/package.json#L26).

#### Application Icons

Application icons are located in `applications/electron/resources/`.
Simply replace them with your own icons.
Because each operating system handles icons differently, they should all be replaced to ensure proper use.
They map as follows:

- macOS: icons.icns
- Windows: icon.ico
- Linux: icons subfolder

### Customizing the Welcome Page

The Eclipse Theia welcome page can be customized by binding a custom `WidgetFactory` for Theia’s `GettingStartedWidget`.
This is done with the Theia IDE in the theia-blueprint-product extension.
The easiest way to customize the welcome page is to adapt the class `TheiaBlueprintGettingStartedWidget` in `theia-extensions/theia-blueprint-product/src/browser/theia-blueprint-getting-started-widget.tsx`.

The widget is bound in `theia-extensions/theia-blueprint-product/src/browser/theia-blueprint-frontend-module.ts` like this:

```typescript
    bind(TheiaBlueprintGettingStartedWidget).toSelf();
    bind(WidgetFactory).toDynamicValue(context => ({
        id: GettingStartedWidget.ID,
        createWidget: () => context.container.get(TheiaBlueprintGettingStartedWidget),
    })).inSingletonScope();
```

To use another custom widget, remove this code and bind your widget correspondingly.

### Customizing the About Dialog

The Eclipse Theia about dialog can be customized by binding a custom subclass of Theia’s `AboutDialog` class to `AboutDialog`.
This is done with Theia IDE in the theia-blueprint-product extension.
The easiest way to customize the about dialog is to adapt the class `TheiaBlueprintAboutDialog` in `theia-extensions/theia-blueprint-product/src/browser/theia-blueprint-about-dialog.tsx`.

The widget is bound in `theia-extensions/theia-blueprint-product/src/browser/theia-blueprint-frontend-module.ts` like this:

```typescript
isBound(AboutDialog) ? rebind(AboutDialog).to(TheiaBlueprintAboutDialog).inSingletonScope() : bind(AboutDialog).to(TheiaBlueprintAboutDialog).inSingletonScope();
```

To use another custom dialog widget, remove this code, extend Theia’s AboutDialog class, and (re)bind it as above.

### Customizing the Preferences

The default preferences directory in Eclipse Theia IDE is `.theia-blueprint` and is located as described in the [Preferences documentation](/docs/preferences/). You can customize this location by modifying [`theia-blueprint-variables-server.ts`](https://github.com/eclipse-theia/theia-blueprint/blob/master/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts).

### Customizing the Electron Splash Screen

Since Theia `1.49.0` Theia Electron applications support displaying a splash screen before showing the main window.

The splash screen can be enabled within the application `package.json`'s Theia options by providing an object at `theia.frontend.config.electron.splashScreenOptions` with the following properties:

```typescript
{
    content: string  // <mandatory> path to the content to render within the splash screen, resolved from application root
    width: number // default 640
    height: number // default 480
    minDuration: number // minimum amount of time in milliseconds to show the splash screen before main window is shown. default 0
    maxDuration: number // maximum amount of time in milliseconds before splash screen is removed and main window is shown. default 30000
}
```

If not configured otherwise via `minDuration`, the splash screen will be shown until the frontend is ready, i.e. when the loading spinner is gone.
Then the splash screen will be closed and the main window is shown.

### Showing Windows Early

The main window / splash screen can be configured to be shown "early", i.e. the window will be shown before it's ready to render content.
By default this is `true` to give the user visual feedback as early as possible.

If you prefer only showing the main window / splash screen once they are ready to render content, then you can configure `theia.frontend.config.electron.showWindowEarly: false` in your application's `package.json`.

### Customizing the Installer

The installers are created using [electron-builder](https://www.electron.build/).
The corresponding configuration file is located at `applications/electron/electron-builder.yml`.

#### Installer File Base Name

The installer files’ base names are defined by the `productName` property in `applications/electron/electron-builder.yml`.

#### Windows Installer

As is typical for Windows applications, there is an installation wizard for the Windows version of the Theia IDE.
The installer is configured in the nsis section of the configuration file.
Available customizations include settings such as:

- Icons
- Sidebar image
- License
- One click installation
- Automatic application start after installation
- Whether users can change the installation directory

More details on available options and how they can be customized can be found in the [official electron builder documentation](https://www.electron.build/configuration/nsis).
This documentation also includes information about more advanced features such as custom NSIS scripts.

## Configure Publish and Update

The Theia IDE uses [electron-builder](https://www.electron.build/) to create and publish installers.
It also uses [electron-updater](https://www.npmjs.com/package/electron-updater), developed by the electron-builder organization, to provide automatic updates of the installed application.

There are various deployment targets which can be configured in the `applications/electron/package.json` and `applications/electron/electron-builder.yml` as documented [here](https://www.electron.build/configuration/publish) in the Electron Builder documentation.
Multiple publish configurations can be configured.
Thereby, the first one is automatically used by the updater to look for available updates.
The currently used generic publishing method does not automatically publish to the specified server, but is just used as the lookup location for the updater.

---

## File: src/docs/blueprint_download.md

---
title: Eclipse Theia Blueprint
---

# Eclipse Theia Blueprint

Eclipse Theia Blueprint has been rebranded to "Theia IDE" and has moved to [this page](/#theiaide).

---

## File: src/docs/breadcrumbs.md

---
title: Breadcrumbs
---

# Breadcrumbs

If enabled via the preferences, Theia can show a navigation bar, often referred to as *breadcrumbs*, above the content of widgets that are located in the main area of the workbench.
This interactive navigation bar indicates the location of the widget's content in the context of an overall structure, such as the filesystem.
By default, Theia shows breadcrumbs for the location of files in the filesystem when a file is opened in the text editors.



However, Theia's breadcrumbs mechanism can also be used for any custom widget, too.
Moreover, Theia allows showing a widget's content location in an arbitrary custom logical structure, such as a custom project structure.
On this page, we describe how custom breadcrumbs work and how widgets declare their location within an overall structure.

## Breadcrumbs Contributions and Navigatable Widgets

What is being shown in the breadcrumbs of a widget is defined by breadcrumbs contributions.
Such contributions must implement the `BreadcrumbsContribution` interface and return an array of `Breadcrumbs` for a specific URI, which are then shown for any widget that specifies this URI as their content's location.
A widget declares the location of its content in the form of a URI by implementing the interface `NavigatableWidget`.

So let's look at an example widget that declares an arbitrary URI.

```typescript
@injectable()
export class CustomWidget extends ReactWidget implements NavigatableWidget {
    // ...
    getResourceUri(): URI | undefined {
        return new URI('resource://project-a/component-b/config-c');
    }
}
```

When this `CustomWidget` is opened, Theia will look for breadcrumbs contributions that return breadcrumbs for this URI.
By default, it won't find any and thus won't show any breadcrumbs.
So let's add a breadcrumbs contribution that reacts to URIs with the scheme `resource` as used by our widget above.

```typescript
export default new ContainerModule(bind => {
    bind(CustomBreadcrumbsContribution).toSelf().inSingletonScope();
    bind(BreadcrumbsContribution).toService(CustomBreadcrumbsContribution);
});

@injectable()
export class CustomBreadcrumbsContribution implements BreadcrumbsContribution {
    type: symbol = CustomBreadcrumbType;
    priority: number = 100;

    protected readonly onDidChangeBreadcrumbsEmitter = new Emitter();
    get onDidChangeBreadcrumbs(): Event {
        return this.onDidChangeBreadcrumbsEmitter.event;
    }

    computeBreadcrumbs(uri: URI): MaybePromise {
        if (uri.scheme !== 'resource') {
            return [];
        }
        // uri is 'resources://project-a/component-b/config-c' for our widget above
        // but let's just hard code breadcrumbs as an example for the sake of simplicity
        return [
            {
                id: 'project',
                label: 'Project A',
                longLabel: 'The project',
                iconClass: 'codicon codicon-folder default-folder-icon file-icon',
                type: CustomBreadcrumbType
            },
            {
                id: 'component',
                label: 'Component B',
                longLabel: 'A component within a project',
                iconClass: 'codicon codicon-file default-file-icon file-icon',
                type: CustomBreadcrumbType
            },
            {
                id: 'config',
                label: 'Configuration C',
                longLabel: 'A configuration within a component',
                iconClass: 'markdown-icon medium-blue theia-file-icons-js file-icon',
                type: CustomBreadcrumbType
            }
        ];
    }

    // ...
}
```

Once the breadcrumbs contribution is registered, Theia will show the following for our custom widget.



## Interactive Breadcrumbs

Breadcrumbs contributions also must implement the method `attachPopupContent`.
Theia invokes this method as soon as a user clicks on one of the breadcrumbs and passes a parent HTML element into which the breadcrumbs contribution can now add arbitrary HTML content, including trees, buttons, etc.
This content is consequently being shown as a popup below the clicked breadcrumbs element.
If this method returns a `Disposable`, Theia will call it, once the popup is closed, allowing to dispose resources that may have been allocated for the rendered content.

As an example, let's just return add some simple HTML to the popup, as shown below.

```typescript
@injectable()
export class CustomBreadcrumbsContribution implements BreadcrumbsContribution {
    // ...
    attachPopupContent(breadcrumb: Breadcrumb, parent: HTMLElement): Promise<Disposable | undefined> {
        parent.innerHTML = '<h3>'
                            + breadcrumb.label
                            + '</h3>We can show arbitrary content here and react to clicks.';
        return Promise.resolve(undefined);
    }
}
```



## Priority of Breadcrumbs Contributions

As defined by the `BreadcrumbsContribution` interface, a contribution must define a `priority`.
The property is used by Theia to properly order the breadcrumbs returned by all breadcrumbs contributions.
Thus, if you have for instance three breadcrumbs contributions that return a non-empty array of breadcrumbs for a particular URI, we'll end up with a final breadcrumbs list that contains all breadcrumbs of all three contributions ordered from lowest to highest priority.
The Theia text editor uses this mechanism to append logical structures of code to a source file, for instance.
Contributions that return an empty array for a specific URI are obviously ignored.

```text
Contribution A with a priority of 10 returns [a, b]
Contribution B with a priority of 20 returns [c, d]
Contribution C with a priority of 30 returns [e, f]
=> [a, b, c, d, e, f]
```

## File URIs

Theia's filesystem extension registers a breadcrumbs contribution that returns breadcrumbs according to the directory hierarchy for any file URI, such as `file://home/user/a/b/c.txt`.
The breadcrumbs returned by that contribution are also interactive by showing a file tree on click for navigating to adjacent files.

You can also make use of the filesystem breadcrumbs in custom widgets by just returning file URIs in your implementation of `NavigatableWidget#getResourceUri()`.
If needed, you can also register additional breadcrumbs contributions with a high number as priority to append to the file URI shown in the breadcrumbs, such as for navigating to specific sections in your custom widget.

Accordingly, however, if you want to avoid showing filesystem breadcrumbs altogether and only use custom breadcrumbs, your widget must return a URI that isn't a file URI, for instance `resource://a/b/c`.

---

## File: src/docs/commands_keybindings.md

---
title: Commands/Menus/Keybindings
---

# Commands, Menus and Keybindings

Commands are runnable actions defined by an ID and the function to be executed (plus some optional parameters like a name or an icon). Commands can be triggered via the command palette, they can be bound to keybindings or menu items, and they can be called programmatically. The action that commands trigger can be context-sensitive, so that they can only be called under certain conditions (window focus, current selection etc.).

The following sections provide details about how to contribute commands, keybindings and menu items. The sections will describe how to connect the different contributions and how to use the corresponding services for managing these items.

If you are not yet familiar with contribution points in Theia or the use of dependency injection, please consider this guide on [Services and Contributions](/docs/services_and_contributions/).

All the following code examples are from the [Theia extension generator](https://github.com/eclipse-theia/generator-theia-extension). You can get the same code set-up by installing the generator, selecting the “Hello World” example (see here) and choosing “helloworld” as the name.

## Contributing Commands

By contributing a command, you can add a custom action to Theia. A command can be triggered by the user via the command palette, a keybinding or a menu entry. It can also be called programmatically.

All commands of a Theia application are managed in the `CommandRegistry`. To contribute commands to the command registry, modules must implement the `CommandContribution` interface (see code example below).

A command is an object with an `id` and an optional, potentially user visible `label` (see HelloworldCommand in the example below). The command contribution receives the `CommandRegistry` in the `registerCommands` function as a parameter. The command can then be registered by calling `registerCommand` on this registry. Along with the command a callback needs to be provided which is executed whenever the command is triggered (`CommandHandler`). In the example, the command uses the MessageService to “say hello”.

**helloworld-contribution.ts**

```typescript
export const HelloworldCommand: Command = {
   id: 'Helloworld.command',
   label: "Say Hello"
};

@injectable()
export class HelloworldCommandContribution implements CommandContribution {

   constructor(
       @inject(MessageService) private readonly messageService: MessageService,
   ) { }

   registerCommands(registry: CommandRegistry): void {
       registry.registerCommand(HelloworldCommand, {
           execute: () => this.messageService.info('Hello World!')
       });
   }
}

```

To make the command execution context-sensitive, the `CommandHandler` can optionally implement `isEnabled` and `isVisible`. You can optionally register more than one `CommandHandler` and let the command execute one of them based on the current context. To register additional handlers for a command use the `registerHandler` function on the `CommandRegistry`
When a command is executed, the command registry checks all registered handlers. The first handler that returns true on `isEnabled` will be considered to be active, and it will be executed. Only one handler should be active (`isEnabled === true`) at the same time, though. `isVisible` controls the visibility of menu items and tool items that are connected to a command, as well as whether the command is shown in the command palette.  If the active handler returns true, the menu item will be visible and vice versa.
Finally, by implementing `isToggle` a handler can optionally specify, whether menu items connected to the commands should be toggled on or off.

### Binding the contribution to CommandContribution

To make our `CommandContribution` accessible to Theia, we need to bind the custom `HelloworldCommandContribution` to the respective contribution symbol `CommandContribution`. This is done in the `helloworld-frontend-module`, for more details see [Services and Contributions](/docs/services_and_contributions/).

**helloworld-frontend-module.ts**

```typescript
export default new ContainerModule(bind => {
   // add your contribution bindings here
   bind(CommandContribution).to(HelloworldCommandContribution);
...
});
```

The `CommandRegistry` used to register our contributed command above, also provides an API to interact with commands. As an example, you can programmatically execute commands, you can browse through all registered commands or you can access a list of recently executed commands. Please refer to the [TypeDoc for the CommandRegistry](https://eclipse-theia.github.io/theia/docs/next/classes/_theia_core.common_command.CommandRegistry.html) for more details. To use the `CommandRegistry` outside of a contribution, you can access it via dependency injection.

In the following sections, we describe how to bind commands to menu items and keybindings.

## Contributing Menu Items

Theia allows you to contribute menu items that will be displayed in specific menus within your Theia application. Menu items are bound to commands and therefore allow the user to trigger actions (please see the section about commands above).

All the following code examples are from the [Theia extension generator](https://github.com/eclipse-theia/generator-theia-extension). You can get the same code set-up by installing the generator, selecting the “Hello World” example (see [here](https://github.com/eclipse-theia/generator-theia-extension)) and choosing “helloworld” as the name.

All menu items of a Theia application are managed in the `MenuModelRegistry`. To contribute menu items to the registry, modules must implement the ´MenuContribution´ interface (see code example below).

The registration of the command can be done in the function `registerMenus`, which will be called by the Theia framework. The function provides the `MenuModelRegistry` as a parameter. On this registry we can call `registerMenuAction`. It expects a `MenuPath` and a `MenuAction`. The `MenuPath` specifies the menu (and submenu) to place the menu item into. Please see [here for the paths of some common menus](https://eclipse-theia.github.io/theia/docs/next/modules/_theia_core.browser_common-frontend-contribution.CommonMenus.html).

The `MenuAction` consists of a command id, specifying which command to trigger, and an optional label, specifying the label of the menu item.

**helloworld-contribution.ts**

```typescript
@injectable()
export class HelloworldMenuContribution implements MenuContribution {

   registerMenus(menus: MenuModelRegistry): void {
       menus.registerMenuAction(CommonMenus.EDIT_FIND, {
           commandId: HelloworldCommand.id,
           label: HelloworldCommand.label
       });
   }
}
```

To make our `MenuContribution` accessible to Theia, we need to bind the custom `HelloWorldMenuContribution` to the respective contribution symbol `MenuContribution`. This is done in the `helloworld-frontend-module`, for more details see [Services and Contributions](/docs/services_and_contributions/).

**helloworld-contribution.ts**

```typescript
export default new ContainerModule(bind => {
   bind(MenuContribution).to(HelloworldMenuContribution);
      ...
});

```

Please note that you also contribute menu items without a command which allows you to create custom top level menus and sub menus. To achieve this, contribute a menu item without a command and then reference the id of this menu item as a `MenuPath` in other contributes. This will add menu items to your custom menu.

## Contributing Keybindings

Keybindings allow the user to trigger commands using specific key combinations. Keybindings can define conditions, specifying when they are active. As an example, there can be keybindings that are only active when the text editor is focused.

Please note that the following code examples are not part of the generated template, so you will need to manually add them (see previous sections).

To contribute a keybinding, implement a `KeybindingContribution` (see code example below) with which you can access the `KeybindingRegistry`, allowing you to register a keybinding. Keybindings consist of:

* `keybinding`: The key combination
* `command`: The id of the command to be triggered
* `when`(optional): The condition when the keybinding should be active

**helloworld-keybinding-contribution.ts**

```typescript
export class HelloworldKeybindingContribution implements KeybindingContribution {
    registerKeybindings(keybindings: KeybindingRegistry): void {
        keybindings.registerKeybinding({
            keybinding: "alt+enter",
            command: 'Helloworld.command',
            when: 'editorFocus && editorIsOpen'
        });
    }
}
```

The syntax for the “when” clause follows the [VS Code terminology](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts). Modifiers are platform independent, so [`Modifier.M1`](https://eclipse-theia.github.io/theia/docs/next/enums/_theia_core.common_keys.KeyModifier.html#ctrlcmd) is Command on OS X and CTRL on Windows/Linux. Key string constants can be viewed in [`Key` documentation](https://eclipse-theia.github.io/theia/docs/next/enums/_theia_core.common_keys.KeyModifier.html).

Just as you needed to bind the contributions before, keybinding contributions also need to be bound to the symbol `KeybindingContribution` to make them accessible for Theia.

**editor-frontend-module.ts**

```typescript
export default new ContainerModule(bind => {
    bind(KeybindingContribution).to(HelloworldKeybindingContribution);
    ...
});

```