This file contains tips to help you take (and understand) your first steps in
the world of Theia development. Are you in a hurry? See the
[Quick Start](#quick-start).
# How to build Theia and the example applications
Theia is a framework to build IDEs, so you can't really "run" Theia itself.
However, you can run the example applications included in its repository. One
is a browser-based IDE and the other is the Electron-based equivalent.
The following instructions are for Linux and macOS.
For Windows instructions [click here](#building-on-windows).
- [**Prerequisites**](#prerequisites)
- [**Quick Start**](#quick-start)
- [Run with SSL](#run-the-browser-example-with-ssl)
- [Run with Gitpod](#run-the-browser-example-with-gitpod)
- [**Clone the repository**](#clone-the-repository)
- [**The repository structure**](#the-repository-structure)
- [**Build core, extensions and examples packages**](#build-core-extensions-and-examples-packages)
- [**Build extension packages individually**](#build-extension-packages-individually)
- [**Run the browser-based example application**](#run-the-browser-based-example-application)
- [**Run the Electron-based example application**](#run-the-electron-based-example-application)
- [**Rebuilding**](#rebuilding)
- [**Watching**](#watching)
- [Watch the core and extension packages](#watch-the-core-and-extension-packages)
- [Watch the examples](#watch-the-examples)
- [Watch a specific package](#watch-a-specific-package)
- [Watch a specific package and its local upstream dependencies](#watch-a-specific-package-and-its-local-upstream-dependencies)
- [**Debugging**](#debugging)
- [Debug the browser example's backend](#debug-the-browser-examples-backend)
- [Debug the browser example's frontend](#debug-the-browser-examples-frontend)
- [Debug the browser example's frontend and backend at the same time](#debug-the-browser-examples-frontend-and-backend-at-the-same-time)
- [Debug the Electron example's backend](#debug-the-electron-examples-backend)
- [Debug the Electron example's frontend](#debug-the-electron-examples-frontend)
- [Debug the Electron example's frontend and backend at the same time](#debug-the-electron-examples-frontend-and-backend-at-the-same-time)
- [Debug IPC servers](#debug-ipc-servers)
- [Debug the plugin host](#debug-the-plugin-host)
- [**Profiling**](#profiling)
- [Profile the frontend process](#profile-the-frontend-process)
- [Profile the backend process](#profile-the-backend-process)
- [Profile IPC servers](#profile-ipc-servers)
- [Profile the plugin host](#profile-the-plugin-host)
- [**Testing**](#testing)
- [**Code coverage**](#code-coverage)
- [**Building on Windows**](#building-on-windows)
- [**Troubleshooting**](#troubleshooting)
- [Linux](#linux)
- [Windows](#windows)
- [macOS](#macos)
- [Root privileges errors](#root-privileges-errors)
## Prerequisites
- Node.js `>= 18.17.0` and `< 21`.
- If you are interested in Theia's VS Code Extension support then you should use a Node version at least compatible with the one included in the version of Electron used by [VS Code](https://github.com/microsoft/vscode).
- [Yarn package manager](https://yarnpkg.com/en/docs/install) `>= 1.7.0` **AND** `< 2.x.x`.
- git (If you would like to use the Git-extension too, you will need to have git version 2.11.0 or higher.)
- Python3 is required for the build due to [`node-gyp@8.4.1`](https://github.com/nodejs/node-gyp/tree/v8.4.1#installation)
Some additional tools and libraries are needed depending on your platform:
- Linux
- [make](https://www.gnu.org/software/make/)
- [gcc](https://gcc.gnu.org/) (or another compiling toolchain)
- [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
- build-essential: `sudo apt-get install build-essential`
- [`native-keymap`](#prerequisite_native_keymap) native node module dependencies:
- Debian-based: `sudo apt-get install libx11-dev libxkbfile-dev`
- Red Hat-based: `sudo yum install libX11-devel.x86_64 libxkbfile-devel.x86_64 # or .i686`
- FreeBSD: `sudo pkg install libX11`
- [`keytar`](#prerequisite_keytar) native node module dependencies ([reference](https://github.com/atom/node-keytar#on-linux)):
- Debian/Ubuntu: `sudo apt-get install libsecret-1-dev`
- Red Hat-based: `sudo yum install libsecret-devel`
- Arch Linux: `sudo pacman -S libsecret`
- Alpine: `apk add libsecret-dev`
- Linux/MacOS
- [nvm](https://github.com/nvm-sh/nvm) is recommended to easily switch between Node.js versions.
- Windows
- We recommend using [`scoop`](https://scoop.sh/). The detailed steps are [here](#building-on-windows).
## Quick Start
To build and run the browser example:
```sh
git clone https://github.com/eclipse-theia/theia \
&& cd theia \
&& yarn \
&& yarn download:plugins \
&& yarn browser build \
&& yarn browser start
```
Start your browser on http://localhost:3000.
To build and run the Electron example:
```sh
git clone https://github.com/eclipse-theia/theia \
&& cd theia \
&& yarn \
&& yarn download:plugins \
&& yarn electron build \
&& yarn electron start
```
### Download plugins
You can download plugins to use with the examples applications by running:
```sh
yarn download:plugins
```
### Run the browser example with SSL
To run the browser example using SSL use:
```sh
git clone https://github.com/eclipse-theia/theia \
&& cd theia \
&& yarn \
&& yarn browser build \
&& yarn download:plugins \
&& yarn browser start --ssl --cert /path/to/cert.crt --certkey /path/to/certkey.key
```
Start your browser on https://localhost:3000.
### Run the browser example with Gitpod
[Gitpod](https://www.gitpod.io/) is a Theia-based IDE for GitHub.
You can start by prefixing any GitHub URL in the Theia repository with `gitpod.io/#`:
- Open https://gitpod.io/#https://github.com/eclipse-theia/theia to start development with the master branch.
- Gitpod will start a properly configured for Theia development workspace, clone and build the Theia repository.
- After the build is finished, run from the terminal in Gitpod:
```sh
yarn browser start ../.. --hostname 0.0.0.0
```
## Clone the repository
```sh
git clone https://github.com/eclipse-theia/theia
```
The directory containing the Theia repository will now be referred to as
`$THEIA`, so if you want to copy-paste the examples, you can set the `THEIA`
variable in your shell:
```sh
THEIA=$PWD/theia
```
## The repository structure
Theia repository has multiple folders:
- `packages` folder contains runtime packages, as the core package and extensions to it
- `dev-packages` folder contains devtime packages
- [@theia/cli](../dev-packages/cli/README.md) is a command line tool to manage Theia applications
- [@theia/ext-scripts](../dev-packages/private-ext-scripts/README.md) is a command line tool to share scripts between Theia runtime packages
- `examples` folder contains example applications, both Electron-based and browser-based
- `doc` folder provides documentation about how Theia works
- `scripts` folder contains JavaScript scripts used by npm scripts when
installing
- the root folder lists dev dependencies and wires everything together with [Lerna](https://lerna.js.org/)
## Build core, extensions and examples packages
You can download dependencies and build TypeScript packages using:
```sh
yarn
```
This command downloads dev dependencies, links and builds all TypeScript packages.
To build the example applications:
```sh
yarn browser build
yarn electron build
# build both example applications at once:
yarn build:examples
```
To learn more and understand precisely what's going on, please look at scripts in [package.json](../package.json).
## Build Everything
```sh
yarn all
```
This will install dependencies, link and build TypeScript packages, lint, and build the example applications.
## Build TypeScript sources
Dependencies must be installed before running this command.
```sh
yarn compile
```
## Linting
Linting takes a lot of time, this is a limitation from ESLint. We always lint in the GitHub Workflows, but if you want to lint locally you have to do it manually:
```sh
yarn # build TypeScript
yarn lint # lint TypeScript sources
```
Note that `yarn all` does linting.
## Build extension packages individually
From the root:
```sh
npx run compile @theia/package-name
```
From the package:
```sh
yarn compile
```
## Run the browser-based example application
We can start the application from the [examples/browser](../examples/browser) directory with:
```sh
yarn start
```
This command starts the backend application listening on port `3000`. The frontend application should be available on http://localhost:3000.
If you rebuild native Node.js packages for Electron then rollback these changes
before starting the browser example by running from the root directory:
```
yarn browser rebuild
```
## Run the Electron-based example application
```sh
yarn electron start
```
## Rebuilding
Rebuilds everything: TypeScript and example applications.
```sh
yarn build
```
## Watching
### Watch the TypeScript packages
To run TypeScript in watch-mode so that TypeScript files are compiled as you modify them:
```sh
yarn watch:compile
```
### Watch the core and extension packages
To rebuild _everything_ each time a change is detected run:
```sh
yarn watch:all
```
### Watch the examples
To rebuild each time a change is detected in frontend or backend you can run:
```sh
# either
yarn browser watch
# or
yarn electron watch
```
### Watch a specific package
You can use `npx` to watch a single package:
```sh
npx run watch @theia/the-package-name
```
### Watch a specific package and its local upstream dependencies
#### Using TypeScript build mode
Once you have built all TypeScript packages once, making a single change and recompiling should be rather quick.
Given this, you can efficiently watch the whole monorepo using TypeScript build mode and have it quickly compiled.
See [Watch the TypeScript packages](#watch-the-typescript-packages).
In this mode, TypeScript only compiles what changed along with its dependents.
#### Using Theia's `run` utility
Let assume you have to work for instance in the `@theia/navigator` extension. But you might have to apply changes in any of its upstream dependencies such as `@theia/filesystem` or `@theia/core`, you can either do `yarn watch` which could be super expensive, as it watches all the packages. Or you can do `npx run watch @theia/navigator` and `npx run watch @theia/filesystem` and `npx run watch @theia/core` in three individual shells. Or you can do the following single-liner:
```sh
npx run watch @theia/navigator --include-filtered-dependencies --parallel
```
## Debugging
### Debug the browser example's backend
- Open the debug view and run the `Launch Browser Backend` configuration.
### Debug the browser example's frontend
- Start the backend by using `yarn run start`.
- In a browser: Open http://localhost:3000/ and use the dev tools for debugging.
- Open the debug view and run the `Launch Browser Frontend` configuration.
### Debug the browser example's frontend and backend at the same time
- Open the debug view and run the `Launch Browser Backend` configuration.
- Then run the `Launch Browser Frontend` configuration.
### Debug the Electron example's backend
- Open the debug view and run the `Launch Electron Backend` configuration.
### Debug the Electron example's frontend
- Start the Electron backend
- Either open the debug view and run the `Launch Electron Backend` configuration
- Or use `yarn run start`.
- Attach to the Electron Frontend
- Either open the debug view and run the `Attach to Electron Frontend` configuration
- Or in Electron: Help -> Toggle Electron Developer Tools.
### Debug the Electron example's frontend and backend at the same time
- Open the debug view and run the `Launch Electron Backend & Frontend` configuration.
### Debug IPC servers
- Pass `--${server-name}-inspect` arg to the backend server.
- For example `--nsfw-watcher-inspect=0` to inspect nsfw watcher processes with dynamic port allocation.
- All variations of `--inspect` flag are supported: https://nodejs.org/en/docs/inspector/#command-line-options.
- Attach the debugger to the logged port.
In order to look up `server-name` run the backend server with `--log-level=debug` flag to enable logging of IPC servers instantiation.
You should be able to see message of `[${server-name}: ${server-PID}]: IPC started` format, like `[nsfw-watcher: 37557] IPC started`.
### Debug the plugin host
- Pass `--hosted-plugin-inspect=9339` arg to the backend server from the command line.
- Instead, you can run `Launch Browser Backend` launch configuration which is already pre-configured.
- Open the debug view and run the `Attach to Plugin Host` launch configuration.
- It connects to the plugin host if at least one extension is detected, otherwise it timeouts after 60s.
- If you want to debug the activation then enable `stopOnEntry` flag.
- Open the browser page.
---
### Debugging Plugin Sources
[click for base article](https://github.com/eclipse-theia/theia/issues/3251#issuecomment-468166533)
The following launch configuration is meant to be used when the Theia project is opened as the main project in VS Code, the following launch configuration is added inside .vscode/launch.json.
- The source repository of your plugin is expected under your `${workspaceFolder}/plugins` folder
- You can start the frontend from URL: http://localhost:3030
- It's suggested to update your frontend launch configuration URL to open your favorite target project in a second launch
Launch configuration template that will start the backend process, and then attempt to connect on port 9339 to debug the plugin-host sub-process:
```jsonc
{
"name": "Launch VS Code extension as Theia plugin",
"type": "node",
"request": "launch",
"port": 9339,
"timeout": 100000,
"args": [
"${workspaceFolder}/examples/browser/src-gen/backend/main.js",
"${workspaceFolder}",
"--port=3030",
"--hosted-plugin-inspect=9339", // spawn the plugin-host in debug mode
"--plugins=local-dir:${workspaceFolder}/plugins"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"internalConsoleOptions": "openOnSessionStart",
"outputCapture": "std"
}
```
#### Producing typescript maps for your plugin
Enable source maps in the plugin's `tsconfig.json`
```jsonc
{
"compilerOptions": {
"sourceMap": true
}
}
```
If Webpack is used you should bundle in development mode in the `package.json` scripts to avoid minification:
```sh
webpack --mode development
```
As well as enabling source map output in the **webpack.config.js**
```js
module.exports = {
devtool: 'source-map'
}
```
#### Compiling and blocking typescript from walking up parent directories [(see discussion)](https://github.com/Microsoft/TypeScript/issues/13992#issuecomment-386253983)
If you get errors while building like:
```
(parent folders)/index.d.ts: error TS2300: Duplicate identifier
```
You can fix it by modifying your `tsconfig.json`:
```jsonc
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types"]
}
}
```
## Profiling
- Use Chrome devtools to profile both the frontend and backend (Node.js).
- For Node.js: open chrome://inspect, click the configure button and ensure target host and port are listed.
- Learn how to get and understand CPU measurements: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
- Learn how to get and understand Memory measurements: https://developers.google.com/web/tools/chrome-devtools/memory-problems/
- Before taking the memory snapshot always collect garbage.
- Make sure that Chrome extensions don't distort measurements by disabling them.
- For frontend: React extension is leaking components.
- Make measurements before and after improvements to provide them as evidence on a pull request.
- Also document how to reproduce improved measurements in `How to test` section of a pull request description.
- If objects don't have a proper class, i.e. plain JSON, then find one of them in the first snapshot
and check that it is garbage collected in the diff between snapshots.
### Profile the frontend process
- In Browser: open the devtools.
- In Electron: Help -> Toggle Electron Developer Tools.
### Profile the backend process
- Pass `--inspect` arg to the backend server: https://nodejs.org/en/docs/inspector/#command-line-options.
### Profile IPC servers
- Pass `--${server-name}-inspect` arg to the backend server.
- For example `--nsfw-watcher-inspect=0` to inspect nsfw watcher processes with dynamic port allocation.
- All variations of `--inspect` flag are supported: https://nodejs.org/en/docs/inspector/#command-line-options.
### Profile the plugin host
- Pass `--hosted-plugin-inspect` arg to the backend server.
- All variations of `--inspect` flag are supported: https://nodejs.org/en/docs/inspector/#command-line-options.
## Testing
- See the [unit testing](Testing.md) documentation.
- See the [API integration testing](api-testing.md) documentation.
## Code coverage
yarn run test
By default, this will generate the code coverage for the tests in an HTML
format, which can be easily viewed with your browser (Chrome/Firefox/Edge/Safari
etc.) by opening `packages//coverage/index.html`.
## Building on Windows
- Install [`scoop`](https://github.com/lukesampson/scoop#installation).
- Install [`nvm`](https://github.com/coreybutler/nvm-windows) with scoop: `scoop install nvm`.
- Install Node.js with `nvm`: `nvm install 18.17.0`, then use it: `nvm use 18.17.0`. You can list all available Node.js versions with `nvm list available` if you want to pick another version.
- Install `yarn`: `scoop install yarn`.
- If you need to install `windows-build-tools`, see [`Installing Windows Build Tools`](#installing-windows-build-tools).
- If you run into problems with installing the required build tools, the `node-gyp` documentation offers a useful [guide](https://github.com/nodejs/node-gyp#on-windows) how to install the dependencies manually. The versions required for building Theia are:
- Python 3.6 or higher
- Visual Studio [build tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) 17
- If you have multiple versions of either python or Visual Studio installed or if the tool is not found, you may adjust the used version via the npm config:
- `npm config set python /path/to/executable/python --global`
- `npm config set msvs_version 2017 --global`
Clone, build and run Theia.
Using Git Bash as administrator:
```sh
git clone https://github.com/eclipse-theia/theia.git \
&& cd theia \
&& yarn \
&& yarn browser build \
&& yarn browser start
```
If you do not have Git Bash installed on your system, [get one](https://gitforwindows.org/), or use `scoop`: `scoop install git`.
### Installing Windows Build Tools
- Previously, [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools) is required to build Native Nodes modules on Windows. The npm package is now [`deprecated`](https://www.npmjs.com/package/windows-build-tools) because NodeJS installer can now install all the required tools that it needs, including Windows Build Tools.
- In case you need to install the tool manually, after installing `yarn`, run `PowerShell` as _Administrator_ and copy paste the following: `npm --add-python-to-path install --global --production windows-build-tools`.
## Troubleshooting
> First make sure that you follow the steps given in the [docs](https://github.com/eclipse-theia/theia/blob/master/doc/Developing.md#run-the-browser-based-example-applicatio) correctly.
### Linux
The start command will start a watcher on many files in the theia directory.
To avoid ENOSPC errors, increase your default inotify watches.
It can be done like so:
```sh
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```
### Windows
If you see `LINK : fatal error LNK1104: cannot open file 'C:\\Users\\path\\to\\node.lib' [C:\path\to\theia\node_modules\drivelist\build\drivelist.vcxproj]`, then set the Visual Studio version manually with `npm config set msvs_version 2017 --global`.
If you are facing with `EPERM: operation not permitted` or `permission denied`
errors while building, testing or running the application then;
- You don't have write access to the installation directory.
- Try to run your command line (`PowerShell`, `GitBash`, `Cygwin` or whatever
you are using) as an administrator.
- The permissions in the NPM cache might get corrupted. Please try to run
`npm cache clean` to fix them.
- If you experience issues such as `Error: EBUSY: resource busy or locked, rename`,
try to disable (or uninstall) your anti-malware software.
See [here](https://github.com/npm/npm/issues/13461#issuecomment-282556281).
- Still having issues on Windows? File a [bug]. We are working on Linux or OS X
operating systems. Hence, we are more than happy to receive any Windows-related
feedbacks, [bug](https://github.com/eclipse-theia/theia/issues) reports.
If you're still struggling with the build, but you use Windows 10, then you can enable the `Windows Subsystem for Linux` and you can get a Linux distro for free.
### macOS
You need to have the Xcode command line tools installed in order to build and run Theia. You can install the tools by running
```sh
xcode-select --install
```
If you already have Xcode installed, but you see the `xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance` error, you need to run the following command to fix it: `sudo xcode-select --switch /Library/Developer/CommandLineTools`.
The solution is the same if you have updated to `10.14` (Mojave) and you can see the `gyp: No Xcode or CLT version detected!` error. More details [here](https://github.com/nodejs/node-gyp#on-macos).
### Root privileges errors
When trying to install with root privileges, you might encounter errors such as
`cannot run in wd`.
Several options are available to you:
- Install without root privileges
- Use the `--unsafe-perm` flag: `yarn --unsafe-perm`