JSDoc banners
@ttsc/banner adds a fixed @packageDocumentation JSDoc banner to the top of every emitted file. Common case: a license / copyright line at the top of your published package.
Install
npm install -D @ttsc/banner@ttsc/banner ships the ttsc.plugin auto-discovery marker in its package.json, so ttsc picks it up the moment it appears in your dependencies / devDependencies, no compilerOptions.plugins[] entry needed. The banner text still comes from the banner.config.* file below; the plugin errors without one. To turn a discovered plugin off without uninstalling it, declare the tsconfig entry with enabled: false (see Plugin protocol).
Configure
Register the plugin in tsconfig.json (optional with auto-discovery; the explicit entry is equivalent and takes precedence):
// tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "transform": "@ttsc/banner" }
]
}
}Drop a banner.config.ts next to tsconfig.json:
// banner.config.ts
import type { ITtscBannerConfig } from "@ttsc/banner";
export default {
text: "License MIT (c) 2026 Acme",
} satisfies ITtscBannerConfig;A banner.config.* file always exports an object with a text string.
The config is a Node module and runs under the module format Node would give it: an explicit .cts/.mts extension decides on its own, and an ambiguous .ts or .js config follows the nearest package.json "type". So __dirname works in a CommonJS package and import.meta.dirname in a "type": "module" package, and Nodeβs globals need no /// <reference types="node" /> directive as long as @types/node is installed beside the config.
Run ttsc. Every emitted .js and .d.ts gets:
/**
* ----------------------------------------------------------------
* License MIT (c) 2026 Acme
*
* @packageDocumentation
*/@ttsc/banner discovers its config by walking upward from the tsconfig directory, looking for banner.config.{ts,cts,mts,js,cjs,mjs,json}. When a build integration compiles through a generated tsconfig outside the project (the bundler adapters do this whenever an alias or a compilerOptions overlay is set), the integration declares the real project root (pluginConfigDir on TtscCompiler) and the walk starts there instead of the temp directory. To point at a specific file instead of relying on auto-discovery, set configFile on the tsconfig entry (a relative path resolves against the same base directory):
// tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "transform": "@ttsc/banner", "configFile": "./config/banner.config.ts" }
]
}
}If no config file is found, the compile fails, banners are never silently skipped.
Common use cases
- License headers at the top of every file in a published library.
- Generated-file warnings:
"β οΈ Generated by codegen β do not edit by hand." - Build provenance:
"Built from commit @{COMMIT_SHA}"(interpolation is up to your build script; the banner plugin itself takes a fixed string).
See also
- @ttsc/paths: another emit-time plugin.
- @ttsc/strip: strip configured calls and
debuggerfrom the emit. - Plugin Development: write your own.