# TypeScript Elements is the first build tool to build the TypeScript compiler into itself. The compiler's Go source code is part of the Elements source code and compiles into the same binary, so it is not a separate program or a linked library. Type checking is a phase of the build, running in the same process against the same in-memory source graph as compilation, so a save is checked, compiled, and hot reloaded in milliseconds. Both targets are checked, the browser and the server, each against the types it actually has. ## One program, one graph Every source in a project has a version derived from its content and the versions of everything it imports. The checker consults that version like every other phase of the build: a file whose version has not moved is not rechecked, and a change deep in the graph rechecks exactly the cone that depends on it. The same graph drives the build cache, the test runner, hot reload, and the deploy, so type checking, compilation, and release agree on one version of every file. Checking runs incrementally inside the build. A single-file save type checks, compiles, and hot reloads in milliseconds. ## The Elements languages are built into the TypeScript checker Elements HTML templates and JSOC config files are their own languages, built into the TypeScript compiler's binder and checker rather than beside them. A template attribute is declared like a TypeScript declaration. A template name resolves through the normal symbol table. The expressions inside `{}` are checked against the surrounding scope by the same checker that checks a `.ts` file, with the same error messages. There is no second type system to learn, and no seam where TypeScript ends and Elements begins. ```ehtml Example

{comment.text.toUpperCase()}

{comment.txet}

``` ## Two targets, one source A file is checked for every target it reaches. Server code sees Node's types and the server half of `@elements/app`; browser-reachable code sees the DOM and the browser half. A server-only call such as `sql()` made from code the browser can reach is a compile error at the call site, so a query or a secret cannot reach the browser by accident. You do not annotate anything; the compiler follows the call graph. See `rpc` for the boundary and `async` for how sync-style calls type check without `await`. ## Options TypeScript options live under `build.typescript` in `config.jsoc`, a flat mirror of the tsconfig `compilerOptions` that apply to an Elements build. Strict checking is on. There is no `tsconfig.json` in an Elements project and you should not add one. ```jsoc config.jsoc build: { typescript: { lib: ["es2022", "dom"], }, }, ``` Full config syntax: `config`. ## Editors The project server speaks the Language Server Protocol, so editors get completions, diagnostics, go-to-definition, and rename for `.ts` files, HTML templates, and JSOC alike, from the same checker the build uses. It replaces `tsserver`. There is nothing to set up. Installing Elements installs the editor integration: the extension for VS Code and its derivatives, and the plugin for Vim and Neovim. No plugin manager, no `.vimrc` or `init.lua` changes. For what Vim and Neovim get and how to wire it by hand instead, see `editors/vim`; for VS Code, `editors/vscode`. ## Diagnostics Type errors are build errors. They appear in `elements build`, in `elements build -json` as diagnostics with a `path` and a 1-based `loc`, and in the editor, all from one check. A build with a type error anywhere does not release, and neither do the tests it would have gated. See `build`. ## Related - `build`: the loop the checker runs inside. - `html`: the template language the checker understands. - `config`: `build.typescript`. - `async`: the sync-style transform and how it types.