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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@chriswa/ts-codegen

v1.4.1

Published

A simple, dynamic TypeScript code generator with development watch support

Downloads

28

Readme

@chriswa/ts-codegen

A simple, dynamic TypeScript code generator with development "watch" support.

What it does

Scans the provided directory (and subdirs) for Handlebars templates and generates TypeScript code. Supports two template formats:

  1. Standalone templates (.hbs files) - example.hbs generates example.ts
  2. Embedded templates (.hbs.ts files) - Template and generated code in the same file

Uses handlebars-helpers library for template functionality. Primarily used for listing files in a directory and importing them, often with registration in factories or registries.

Installation

pnpm add @chriswa/ts-codegen

Example

Import and register classes in a directory with a factory. In watch mode, the output file is updated when class files are created, renamed, and deleted.

Template: src/things/_index.ts.hbs

// Generated code - see *.hbs file

import { myFactory } from '../factories'

// Auto-import all TypeScript files in this directory (excluding templates and outputs)
{{#each (match (readdirRecursive ".") "*.ts")}}
{{#unless (contains (array "_index.ts" "_index.ts" "Base.ts") this)}}
import { {{replace (basename this) ".ts" ""}} } from './{{replace this ".ts" ""}}'
{{/unless}}
{{/each}}

// Register all classes with the factory
{{#each (match (readdirRecursive ".") "*.ts")}}
{{#unless (contains (array "_index.ts" "_index.ts" "Base.ts") this)}}
myFactory.registerClass({{replace (basename this) ".ts" ""}})
{{/unless}}
{{/each}}

Generated: src/things/_index.ts

// Generated code - see *.hbs file

import { myFactory } from '../factories'

// Auto-import all TypeScript files in this directory (excluding templates and outputs)
import { FooThing } from './FooThing'
import { BarThing } from './BarThing'
import { BaazThing } from './BaazThing'

// Register all classes with the factory
myFactory.registerClass(FooThing)
myFactory.registerClass(BarThing)
myFactory.registerClass(BaazThing)

Embedded Templates

Embedded templates (.hbs.ts files) are an alternative to standalone templates where the template and generated code exist in the same file. The template (as comments) comes first, followed by the generated code.

Before Processing: src/config.hbs.ts

// export const message = 'Hello from World!'
// export const template = '{{taskPathBasename}}'

// ===================== GENERATED CODE BELOW =====================
// Generated by @chriswa/ts-codegen (embedded template)
// Do not edit manually - changes will be overwritten
// ================================================================
// This section will be replaced by the code generator

After Processing: src/config.hbs.ts

// export const message = 'Hello from World!'
// export const template = '{{taskPathBasename}}'

// ===================== GENERATED CODE BELOW =====================
// Generated by @chriswa/ts-codegen (embedded template)
// Do not edit manually - changes will be overwritten
// ================================================================
export const message = 'Hello from World!'
export const template = 'config.hbs.ts'

Format:

  • Template is written as TypeScript comments (lines starting with // )
  • Generated code replaces content after the generated code banner
  • File is processed in-place, preserving the template for future regeneration

Template Helpers

This package includes all handlebars-helpers plus custom helpers:

readdirRecursive

Recursively reads directory contents and returns file paths relative to the template location.

{{#each (readdirRecursive ".")}}
// Found: {{this}}
{{/each}}

Combined with handlebars-helpers

Combine helpers for file processing:

{{#each (match (readdirRecursive ".") "*.ts")}}
{{#unless (contains (array "excluded.ts" "another.ts") this)}}
// Process: {{this}}
{{/unless}}
{{/each}}

Common helpers include:

  • match - Filter arrays with glob patterns
  • contains - Check if array contains value
  • unless - Conditional exclusion
  • array - Create arrays
  • basename - Get filename from path
  • replace - String replacement

include

Include and process other template files with parameter passing. Supports relative paths and TypeScript path mapping.

{{include "./shared/entity-template.hbs" entityType="User" items=(array "UserService" "UserModel")}}

Path Resolution:

  • Relative paths: ./shared/template.hbs, ../common/template.hbs
  • TypeScript paths: @/shared/template.hbs (requires tsconfig.json with path mapping)

Template Composition Example:

Shared Template (shared/entity-template.hbs):

// Auto-generated {{entityType}} entities
{{#each items}}
import { {{this}} } from './{{this}}'
{{/each}}

export const {{camelcase entityType}}Classes = [
{{#each items}}
  {{this}},
{{/each}}
]

Consumer Templates:

{{include "./shared/entity-template.hbs" entityType="User" items=(array "UserService" "UserModel")}}
{{include "@/shared/entity-template.hbs" entityType="Product" items=(array "ProductService" "ProductModel")}}

Examples

For comprehensive examples of how to use ts-codegen, see the examples/ directory. Each example contains:

  • input/ - Template files and supporting code
  • expected/ - Expected generated output
  • meta/ - Configuration for handling non-deterministic content (when applicable)

Available Examples:

Run the examples with: pnpm test (runs all examples as tests)

Usage

CLI Usage

# Build once
npx ts-codegen build src

# Watch for changes
npx ts-codegen watch src

# Clean generated files
npx ts-codegen clean src

Programmatic Usage

import { build, watch, clean } from '@chriswa/ts-codegen'

// Build templates
await build('src')

// Watch for changes
watch('src')

// Clean generated files
clean('src')

Vite Plugin

// vite.config.ts
import { defineConfig } from 'vite'
import { tsCodegenVitePlugin } from '@chriswa/ts-codegen'

export default defineConfig({
  plugins: [
    tsCodegenVitePlugin('src'),
  ],
})

TypeScript-First

This package distributes TypeScript source files and uses tsx to run TypeScript directly. This provides IDE support, type safety, and eliminates compilation steps for consumers.

License

MIT