Skip to content

Build a TypeScript playground

Build a TypeScript editor with syntax colours, line numbers, find, a minimap and language diagnostics. Start with the Quick start container in a Vite browser application.

Terminal window
npm install @singapore-editor/core @singapore-editor/tree-sitter @singapore-editor/tree-sitter-languages @singapore-editor/typescript-lsp @singapore-editor/gutters @singapore-editor/find @singapore-editor/minimap

The example converts VS Code editor colours with editorThemeFromVscodeTheme. The background and foreground appear as soon as the editor mounts.

Register the bundled language contributions with createTreeSitterLanguagePlugin. Open a document with languageId: 'typescript'. The grammar loads when needed, and the worker returns syntax tokens.

Add createLineGutterPlugin() and createEditorFindPlugin() to plugins, and import their stylesheets. Line numbers appear on the left. Use Ctrl+F or Cmd+F to search the file.

Create the TypeScript plugin and call setWorkspaceFiles with /src/math.ts. The worker resolves the import in /src/main.ts. Passing a string to twice produces a diagnostic because twice takes a number.

Add createMinimapPlugin() and its stylesheet. The minimap appears beside the text and can scroll the editor.

playground.ts
import { Editor } from '@singapore-editor/core/editor'
import { createTreeSitterLanguagePlugin } from '@singapore-editor/tree-sitter'
import { TREE_SITTER_LANGUAGE_CONTRIBUTIONS } from '@singapore-editor/tree-sitter-languages'
import { createTypeScriptLspPlugin } from '@singapore-editor/typescript-lsp'
import { createLineGutterPlugin } from '@singapore-editor/gutters'
import { createEditorFindPlugin } from '@singapore-editor/find'
import { createMinimapPlugin } from '@singapore-editor/minimap'
import { editorThemeFromVscodeTheme } from '@singapore-editor/core/shiki'
import '@singapore-editor/core/style.css'
import '@singapore-editor/gutters/style.css'
import '@singapore-editor/find/style.css'
import '@singapore-editor/minimap/style.css'
export function mountPlayground(element: HTMLElement): Editor {
const typescript = createTypeScriptLspPlugin()
typescript.setWorkspaceFiles([
{ path: '/src/math.ts', text: 'export const twice = (n: number) => n * 2\n' },
])
const editor = new Editor(element, {
theme: editorThemeFromVscodeTheme({
colors: { 'editor.background': '#18202b', 'editor.foreground': '#dce5ef' },
}),
plugins: [
createTreeSitterLanguagePlugin(TREE_SITTER_LANGUAGE_CONTRIBUTIONS),
createLineGutterPlugin(),
createEditorFindPlugin(),
typescript,
createMinimapPlugin(),
],
})
editor.openDocument({
documentId: '/src/main.ts',
text: "import { twice } from './math'\n\ntwice('two')\n",
languageId: 'typescript',
})
return editor
}

Call mountPlayground with your container and dispose the returned editor when the view closes. The live editor below runs that same file.

import { twice } from './math'

twice('two')

Change 'two' to 2. The TypeScript diagnostic should clear after the worker processes the edit. Hover over twice to inspect its type.

You have built an editor with a second virtual file and a local language service. It needs no external language-server process. The guides cover worker hosting and sharing a project across editors.

Open the full demo to browse the repository through the GitHub API and edit its files.

Check the browser network panel for failed worker, grammar or standard-library requests. Serve the production build and confirm those assets resolve under its base path.

Use matching absolute virtual paths in setWorkspaceFiles and documentId. Include the imported files in the worker’s workspace file set.

Continue with Language servers and Bundling and workers in the sidebar.