Core framework for building cloud and desktop IDE applications using modern web technologies with TypeScript and dependency injection.
npx @tessl/cli install tessl/npm-theia--core@1.64.0Theia Core is the foundational framework for building cloud and desktop IDE applications using modern web technologies. It provides comprehensive APIs for application structure, dependency injection, widget systems, command handling, and cross-platform development with TypeScript.
npm install @theia/core// Main entry point (cross-platform APIs)
import { inject, injectable, Command, CommandRegistry, interfaces } from "@theia/core";
// Browser-specific APIs
import { FrontendApplication, Widget, ReactWidget } from "@theia/core/lib/browser";
// Node-specific APIs
import { BackendApplication, CliContribution } from "@theia/core/lib/node";
// React for widget development
import * as React from "react";For CommonJS:
const { inject, injectable } = require("@theia/core");
const { FrontendApplication } = require("@theia/core/lib/browser");import { injectable, inject } from "@theia/core";
import { CommandContribution, CommandRegistry, Command } from "@theia/core";
import { FrontendApplication, ReactWidget } from "@theia/core/lib/browser";
import * as React from "react";
// Define a command
const MY_COMMAND: Command = {
id: 'my-extension.hello',
label: 'Say Hello'
};
// Create a command contribution
@injectable()
export class HelloWorldContribution implements CommandContribution {
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(MY_COMMAND, {
execute: () => {
console.log('Hello from Theia!');
}
});
}
}
// Create a widget
@injectable()
export class HelloWidget extends ReactWidget {
constructor() {
super();
this.id = 'hello-widget';
this.title.label = 'Hello';
}
protected render(): React.ReactNode {
return <div>Hello World Widget</div>;
}
}Theia Core is built around several key architectural patterns:
Core dependency injection infrastructure using InversifyJS with Symbol-based service tokens and contribution patterns.
function inject(serviceIdentifier: interfaces.ServiceIdentifier): ParameterDecorator;
function injectable<T>(target: interfaces.Newable<T>): interfaces.Newable<T>;
interface ContributionProvider<T> {
getContributions(): T[];
}Centralized command registry with handler prioritization, context awareness, and event-driven lifecycle.
interface Command {
id: string;
label?: string;
iconClass?: string;
category?: string;
}
interface CommandHandler {
execute(...args: any[]): any;
isEnabled?(...args: any[]): boolean;
isVisible?(...args: any[]): boolean;
}
interface CommandRegistry {
registerCommand(command: Command, handler?: CommandHandler): Disposable;
executeCommand<T>(id: string, ...args: any[]): Promise<T | undefined>;
}Type-safe event system with emitters, async event handling, cancellation support, and disposable subscriptions.
interface Event<T> {
(listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable;
}
class Emitter<T> {
readonly event: Event<T>;
fire(event: T): void;
dispose(): void;
}
interface CancellationToken {
readonly isCancellationRequested: boolean;
readonly onCancellationRequested: Event<any>;
}Comprehensive widget system built on Phosphor/Lumino with React integration, layout management, and extensible widget types.
class Widget {
readonly id: string;
readonly title: Title<Widget>;
readonly parent: Widget | null;
show(): void;
hide(): void;
close(): void;
}
class ReactWidget extends Widget {
protected render(): React.ReactNode;
protected onAfterAttach(): void;
protected onBeforeDetach(): void;
}Frontend and backend application frameworks with lifecycle management, contribution points, and cross-platform support.
class FrontendApplication {
readonly shell: ApplicationShell;
start(): Promise<void>;
stop(): void;
}
class BackendApplication {
use(...handlers: express.Handler[]): void;
start(port?: number): Promise<void>;
stop(): void;
}
interface FrontendApplicationContribution {
initialize?(): void;
configure?(app: FrontendApplication): void;
onStart?(app: FrontendApplication): void;
onStop?(app: FrontendApplication): void;
}Unified resource abstraction for files, URIs, and virtual resources with versioning, encoding support, and multiple resolvers.
interface Resource {
readonly uri: URI;
readonly version?: ResourceVersion;
readContents(options?: ResourceReadOptions): Promise<string>;
saveContents?(content: string, options?: ResourceSaveOptions): Promise<void>;
}
interface ResourceProvider {
get(uri: URI): Promise<Resource>;
}
class URI {
readonly scheme: string;
readonly path: string;
static file(path: string): URI;
static parse(value: string): URI;
toString(): string;
}Type-safe preference management with schema definition, providers, and runtime configuration changes.
interface PreferenceService {
get<T>(preferenceName: string, defaultValue?: T): T | undefined;
set(preferenceName: string, value: any): Promise<void>;
onPreferenceChanged: Event<PreferenceChangeEvent<any>>;
}
interface PreferenceSchema {
[name: string]: PreferenceSchemaProperty;
}Comprehensive keybinding system with context awareness, command integration, and platform-specific key handling.
interface Keybinding {
keybinding: string;
command: string;
context?: string;
args?: any[];
}
interface KeybindingRegistry {
registerKeybinding(binding: Keybinding): Disposable;
getKeybindingsForCommand(commandId: string): Keybinding[];
}Hierarchical menu system with dynamic contributions, context menus, and integration with commands.
interface MenuNode {
readonly id: string;
readonly label?: string;
readonly icon?: string;
readonly sortString?: string;
}
interface MenuModelRegistry {
registerMenuAction(menuPath: MenuPath, item: MenuAction): Disposable;
registerSubmenu(menuPath: MenuPath, label: string): MenuPath;
}type Disposable = {
dispose(): void;
};
interface DisposableCollection extends Disposable {
push(disposable: Disposable): Disposable;
pushAll(disposables: Disposable[]): Disposable[];
}
type MaybePromise<T> = T | Promise<T>;
type MaybeArray<T> = T | T[];
interface URI {
readonly scheme: string;
readonly authority: string;
readonly path: string;
readonly query: string;
readonly fragment: string;
}
interface ApplicationError<C = number, D = any> extends Error {
readonly code: C;
readonly data: D;
}interface EmitterOptions {
onFirstListenerAdd?: Function;
onLastListenerRemove?: Function;
leakWarningThreshold?: number;
}
interface WaitUntilEvent {
waitUntil(thenable: Promise<any>): void;
}
type EventListener<T> = (e: T) => any;// InversifyJS interfaces namespace
namespace interfaces {
interface ServiceIdentifier<T = any> {
// Service identifier for dependency injection
}
interface Bind {
// Container binding interface
}
interface Container {
// InversifyJS container interface
get<T>(serviceIdentifier: ServiceIdentifier<T>): T;
}
interface Newable<T> {
new (...args: any[]): T;
}
}// Core service symbols for dependency injection
const CommandService: symbol;
const CommandRegistry: symbol;
const LoggerFactory: symbol;
const ILogger: symbol;
const PreferenceService: symbol;
const ResourceProvider: symbol;
const KeybindingRegistry: symbol;
const MenuModelRegistry: symbol;