Repository navigation
Description
What problem does this solve?
Ember projects increasingly use Glimmer JavaScript (.gjs) and Glimmer TypeScript (.gts) to colocate JavaScript or TypeScript with a <template> block:
import Component from '@glimmer/component';
import Avatar from './avatar.gts';
import { formatDate } from '../utils/format-date.ts';
import type User from '../data/user.ts';
interface Signature {
Args: {
user: User;
};
}
export default class UserCard extends Component<Signature> {
get userName() {
return this.args.user.name;
}
<template>
<Avatar @user={{@user}} />
<span>{{this.userName}}</span>
<time>{{formatDate @user.createdAt}}</time>
</template>
}Treating these files as plain JavaScript or TypeScript through custom file-extension mapping only indexes the host-language portion. It does not understand the embedded Glimmer template, so important graph information is missing:
- component references such as
<Avatar />; - lexically scoped function, helper, and modifier calls such as
formatDate; - named argument paths such as
@userand@user.createdAt; - component member references such as
this.userName; - ownership of template calls and usages by the surrounding class, function, or module.
For modern Ember applications, a meaningful part of the dependency graph lives inside <template>. Indexing only the host code therefore produces an incomplete view of the application, particularly for call tracing and agent-assisted code exploration.
The repository already supports similar hybrid/container formats such as Astro, Vue/Vue SFC, and Svelte. Adding .gjs and .gts follows the same general direction: preserve normal JavaScript/TypeScript extraction while parsing the embedded template with the appropriate grammar.
This also appears to be a reasonably bounded addition. Maintained Tree-sitter grammars already exist for both the host files and the embedded template:
- ember-tooling/tree-sitter-glimmer
- ember-tooling/tree-sitter-glimmer-javascript
- ember-tooling/tree-sitter-glimmer-typescript
Proposed solution
Add first-class language support for:
- Glimmer JavaScript (
.gjs); - Glimmer TypeScript (
.gts).
The implementation could reuse the existing JavaScript/TypeScript extraction paths for host-language definitions, imports, calls, and usages, then run a focused embedded-template extraction pass over each <template> body.
At minimum, the Glimmer pass should extract:
- component invocations;
- helpers, modifiers, and block helpers;
- named argument paths such as
@userand@user.createdAt; - component member paths such as
this.userName; - links from lexically scoped template references to imports and class members where resolvable;
- ownership by the enclosing class, function, or module;
- source locations mapped back to the original
.gjs/.gtsfile.
Malformed templates should result in partial extraction rather than discarding valid host-language data or valid sibling templates.
This should fit within the existing language integration surface—extension detection, vendored grammars, language specs, extraction logic, tests, and documentation—without requiring a new public MCP API or a separate indexing pipeline.
Useful references and public test beds:
- embroider-build/content-tag for the
<template>tag format and transformation behavior; - typed-ember/glint for real Glimmer TypeScript usage and fixtures;
- the three Tree-sitter grammar repositories above for parser fixtures and expected AST shapes.
Acceptance criteria could include:
.gjsand.gtsfiles are discovered without custom extension configuration;- host JavaScript/TypeScript extraction remains at parity with
.jsand.ts; - component and function calls, named argument usages (
@arg), and component member usages (this.*) inside<template>are present in the graph; - lexically scoped template references resolve to their imports or class members where possible;
- template relationships are attributed to the correct enclosing owner;
- malformed template regions preserve valid host and sibling extraction;
- integration is verified against a real Ember/Glint repository.
Alternatives considered
Custom file extensions
Mapping .gjs to JavaScript and .gts to TypeScript is useful as a fallback, but it only handles file discovery and host-language parsing. It cannot provide semantic extraction from <template>, which is the main reason first-class support is needed.
Preprocess files before indexing
The indexer could preprocess files with content-tag, or consume the virtual TypeScript representation produced by Glint, and then index the generated host-language code. This would add an external transformation step, complicate source-location mapping, and make indexing dependent on project-specific tooling. The available Tree-sitter grammars make direct parsing a smaller and more predictable integration.
Confirmations
- I searched existing issues and this is not a duplicate.
Activity
DeusData commentedon Jul 24, 2026
Thanks for the proposal. This is triaged under the parsing epic for
0.9.2-rc. Any implementation needs to stay inside the current local static-binary model: a pinned and license-audited grammar, maintainer-vendored source, no external preprocessor/runtime dependency, and RED fixtures for both.gjsand.gtsembedded template/script boundaries. This classification is for review and does not yet accept a particular grammar or implementation.DeusData commentedon Oct 19, 2026
Thank you again for the Glimmer host/template boundary proposal. The language-support scope and grammar choice still need maintainer review, including source-location and malformed-template behavior. I have no new implementation decision to announce.