npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ember-content-mapper

v0.3.1

Published

A TypeScript content mapper for Ember's .gts and .gjs files

Readme

ember-content-mapper

Type-check .gts and .gjs files with native TypeScript 7.

This package is a TypeScript content mapper.

Requirements

  • TypeScript 7.1 nightly or newer (typescript@next)
  • Node 22.21.1 or newer, or Node 24.10.0 or newer
  • imports must specify the file extensions

Install

pnpm add -D ember-content-mapper @glint/ember-tsc

Use

Add the mapper to tsconfig.json:

{
  "contentMappers": [
    {
      "package": "ember-content-mapper",
      "extensions": [".gts", ".gjs"],
    },
  ],
  "include": ["src"],
}

Type-check:

tsc --noEmit --runExternalCode

Options

options accepts the options of Glint's ember-template-imports environment:

{
  "contentMappers": [
    {
      "package": "ember-content-mapper",
      "extensions": [".gts", ".gjs"],
      "options": {
        "additionalGlobals": ["t"],
        "additionalSpecialForms": {},
      },
    },
  ],
}

Directives

Glint's directives work as before:

  • {{! @glint-expect-error }} suppresses the diagnostics on the next line. If there are none, TypeScript reports glint2578: Unused '@glint-expect-error' directive.
  • {{! @glint-ignore }} suppresses the diagnostics on the next line.
  • {{! @glint-nocheck }} suppresses the diagnostics in the whole template.

Declaration files

A sibling declaration file wins over transforming the module, matching Glint: counter.gjs is typed from counter.d.gjs.ts (TypeScript 7's arbitrary-extension convention) or counter.gjs.d.ts (Glint's) when one exists. The declaration is parsed as a .ts module, so anything unbodied or uninitialized in it must use ambient (declare) syntax.

Migrating from TS6

On TypeScript 6, Glint 2 type-checks .gts and .gjs with its own compiler, ember-tsc, and serves editors from its own language server. TypeScript 7 does both itself and calls this mapper for the transform. So most of the migration is deleting configuration.

Install the TypeScript 7 nightly and the mapper:

pnpm add -D typescript@next ember-content-mapper

Keep @glint/ember-tsc and @glint/template installed. The mapper transforms with @glint/ember-tsc and references its types, and @glint/template types the signatures you write by hand.

tsconfig.json

Add the contentMappers entry from Use. Then remove { "name": "@glint/tsserver-plugin" } from compilerOptions.plugins. TypeScript 7 does not load tsserver plugins. The contentMappers entry replaces it.

"ember-source/types" and "@glint/ember-tsc/types" in compilerOptions.types become redundant: the mapper references both from the transformed text. Removing them is optional. Keep them while another tool that builds a program from the same tsconfig.json (for example eslint) still runs against the project; without them those tools lose the @ember/* and Glint types. Keep every other entry, for example "@embroider/core/virtual" or "vite/client".

If the project still has a Glint 1 glint key, its environment options move to the mapper's options. See Options.

package.json

  • Replace ember-tsc in your scripts with tsc --noEmit --runExternalCode. Without --runExternalCode, TypeScript reports TS100024: Content mappers require the '--runExternalCode' command line flag to be enabled.
  • Remove @glint/tsserver-plugin.

Source

Add the extension to relative imports of .gts and .gjs modules:

-export { default as Counter } from './counter';
+export { default as Counter } from './counter.gts';

TypeScript resolves a content-mapped file only when the specifier has the extension. Glint resolved it either way, so this is usually the only source change the migration needs.

A project that is clean under ember-tsc can report a few diagnostics that Glint dropped because they landed on unmapped generated text. See Diagnostics that Glint drops.

Glint's {{! @glint-expect-error }}, {{! @glint-ignore }}, and {{! @glint-nocheck }} directives keep working. See Directives.

Editor

Glint's language server is no longer in the loop. See Editors for what replaces it.

Known issues

TypeScript 7 behavior changes that surface through the mapper. These are compiler behaviors, not mapper bugs; each links to the upstream report.

  • JSDoc @extends over expression heritage is dropped (TypeScript#64058). On TypeScript 6, a classic class Foo extends Component.extend(SomeMixin) {} with a /** @extends {Component<FooSignature>} */ tag keeps its signature. TypeScript 7 rejects the tag (TS8023/TS8026) and the signature is lost, so every invocation types the component as taking no arguments, blocks, or element. Workaround: a sibling declaration file (see Declaration files).
  • Closure-style function(...) JSDoc types no longer parse, and the parse error silently drops every later @property in the same typedef — arguments vanish from the signature with no error at the definition. Rewrite them as arrow types: {function(string)=} becomes {((s: string) => void)=}. Documented as intentional in typescript-go's CHANGES.md.
  • Declaration builds emit foo.d.gts.ts rather than foo.d.ts, which complicates package.json#exports for published packages (TypeScript#64053).

Tracked in #23, along with a request for a mapper debug mode (TypeScript#64055).

Editors

  • VS Code: TypeScript (Native Preview) plus Glint 2 1.4.0 or newer. Glint registers .gts and .gjs with TypeScript and stands down its own language server.
  • Neovim: ember.nvim attaches TypeScript 7's LSP when tsconfig.json has contentMappers.

examples/README.md has the details.

Debug

TS_CONTENT_MAPPER_DEBUG=1 logs the JSON-RPC traffic between tsc and the mapper.

TS_CONTENT_MAPPER_WORKERS=<n> sets the number of transform workers (default: cores − 1, at most 8; 1 = main thread). tsc --extendedDiagnostics shows the wait as Content mapper request wait time.

Repository

  • examples/: two Ember apps that use the mapper.
  • test/test-packages/: copies of Glint's test packages, with the known differences recorded in test/test-packages/README.md.
  • test/: snapshot tests of the transform, tests of the server process, LSP tests against the example app (hover, definition, completion, diagnostics, rename), and compiler mode tests (declaration emit, --build up-to-date checks, option diagnostics).

Prior art

License

MIT