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

@qlik/dts-bundler

v1.1.0

Published

Bundle TypeScript declaration files into a single file

Readme

TypeScript Declaration Bundler

A tool for bundling TypeScript files (.ts and/or .d.ts) by inlining local imports and optionally inlining types from specified npm packages. Works both as a CLI tool and as a library you can import in your Node.js projects.

Features

Core Bundling

  • 🎯 Inline local imports — Automatically resolves and inlines all relative imports (./ or ../)
  • 📦 Selective library inlining — Optionally inline types from specific npm packages
  • 🔄 External import consolidation — Keeps external imports at the top of the bundled file
  • 🎨 Type-only import handling — Properly handles import type statements
  • 🔁 Export re-export resolution — Resolves export * from statements

Advanced Capabilities

  • 🧩 Ambient module inlining — Optionally inline declare module "..." blocks for external modules
  • 🌐 declare global support — Control whether declare global blocks are inlined or preserved
  • 🔀 Declaration merging — Correctly handles TypeScript declaration merging scenarios
  • 🌳 Tree shaking — Removes unused declarations from the output
  • 🏷️ Name collision resolution — Automatically resolves naming conflicts across files

Output Control

  • 📛 UMD module name — Generate UMD-compatible output with export as namespace
  • 🔤 Sorted output — Optionally sort declarations alphabetically for consistent diffs
  • 📜 Banner control — Include or exclude the generated banner comment
  • 🔒 Preserve const enums — Respect preserveConstEnums compiler option
  • 📚 Triple-slash references — Automatically add /// <reference types="..." /> for @types/* packages

Developer Experience

  • 🛠️ Dual usage — Use as CLI tool or import as a library
  • Full TypeScript support — Complete type definitions included
  • Fast — Built on the TypeScript compiler API for accurate and efficient parsing

Installation

npm install @qlik/dts-bundler
# or
pnpm add @qlik/dts-bundler
# or
yarn add @qlik/dts-bundler

Usage

As a Library

import { bundleTypes } from "@qlik/dts-bundler";
import fs from "fs";

// Basic usage - returns bundled content as string
const bundledContent = bundleTypes({
  entry: "./src/types.ts",
});

// Write to file
fs.writeFileSync("./dist/bundle.d.ts", bundledContent);

// With inlined libraries
const bundledWithLibs = bundleTypes({
  entry: "./src/types.ts",
  inlinedLibraries: ["@my-org/types", "some-package"],
  inlineDeclareExternals: true,
});

fs.writeFileSync("./dist/bundle.d.ts", bundledWithLibs);

As a CLI Tool

bundle-types -e < entry > -o < output > [-i < inlinedLibraries > ]

CLI Options

  • -e, --entry <file> - Required: Entry TypeScript file to bundle
  • -o, --output <file> - Required: Output file path for bundled types
  • -i, --inlinedLibraries <list> - Optional: Comma-separated list of npm packages to inline
  • -h, --help - Show help message

CLI Examples

Basic usage (inline only local imports):

bundle-types -e ./src/types.ts -o ./dist/bundle.d.ts

With npm package inlining:

bundle-types \
  -e ./src/types.ts \
  -o ./dist/bundle.d.ts \
  -i @my-org/types-pkg,@another/types-pkg

Using npm scripts (add to package.json):

{
  "scripts": {
    "bundle-types": "bundle-types -e ./src/types.ts -o ./dist/bundle.d.ts"
  }
}

Then run:

npm run bundle-types

Real-World Use Cases

Use Case 1: Publishing a Library

When publishing a library, bundle internal types but keep framework types external:

import { bundleTypes } from "@qlik/dts-bundler";
import fs from "fs";

const bundled = bundleTypes({
  entry: "./src/index.ts",
  inlinedLibraries: ["@my-company/internal-types"],
});

fs.writeFileSync("./dist/index.d.ts", bundled);

Use Case 2: Monorepo Type Sharing

In a monorepo, inline types from your own packages:

bundle-types \
  -e ./src/types.ts \
  -o ./dist/types.d.ts \
  -i @myorg/pkg-a,@myorg/pkg-b,@myorg/pkg-c

Use Case 3: Single File Distribution

Create a single file with all types for easy distribution:

import { bundleTypes } from "@qlik/dts-bundler";
import fs from "fs";

const bundled = bundleTypes({
  entry: "./src/api.types.ts",
});

fs.writeFileSync("./api-complete.d.ts", bundled);

Use Case 4: Build Pipeline Integration

Integrate into your build process:

// build.js
import { bundleTypes } from "@qlik/dts-bundler";
import fs from "fs";

async function build() {
  // ... other build steps

  const bundled = bundleTypes({
    entry: "./src/public-api.ts",
  });

  fs.writeFileSync("./dist/index.d.ts", bundled);

  console.log("✓ Types bundled!");
}

build();

How It Works

The bundler performs the following steps:

  1. Parse Entry File: Reads and parses the entry TypeScript file using the TypeScript compiler API
  2. Resolve Imports:
    • Local imports (starting with ./ or ../) are always resolved and inlined
    • Imports from packages in the inlinedLibraries list are also inlined
    • All other imports are tracked as external dependencies
  3. Recursive Processing: Recursively processes all files that should be inlined
  4. Generate Output:
    • External imports are consolidated and placed at the top
    • All inlined type declarations follow
    • An export {} statement ensures the file is treated as a module

Example Transformation

Input Files

src/types.ts:

import type { ExternalType } from "@external/package";
import type { LocalType } from "./local-types";

export interface MyType extends LocalType {
  external: ExternalType;
}

src/local-types.ts:

export interface LocalType {
  id: string;
  name: string;
}

Output File

dist/bundle.d.ts:

// Generated by @qlik/dts-bundler

import type { ExternalType } from "@external/package";

export interface LocalType {
  id: string;
  name: string;
}

export interface MyType extends LocalType {
  external: ExternalType;
}

export {};

API Reference

For complete API documentation, see the API Reference.

Quick Reference

bundleTypes(options)

Bundle TypeScript declaration files.

import { bundleTypes } from "@qlik/dts-bundler";
import fs from "fs";

const bundled = bundleTypes({
  entry: "./src/types.ts",
  inlinedLibraries: ["@my-org/types"],
  inlineDeclareExternals: true,
});

fs.writeFileSync("./dist/bundle.d.ts", bundled);

Options Summary

| Option | Type | Default | Description | | -------------------------- | ---------- | ----------- | ----------------------------------------------- | | entry | string | — | (Required) Entry TypeScript file path | | inlinedLibraries | string[] | [] | Libraries to inline into the bundle | | allowedTypesLibraries | string[] | undefined | @types/* packages for triple-slash references | | importedLibraries | string[] | undefined | Libraries to keep as imports | | inlineDeclareGlobals | boolean | false | Inline declare global blocks | | inlineDeclareExternals | boolean | false | Inline declare module blocks | | exportReferencedTypes | boolean | false | Auto-export referenced types | | noBanner | boolean | false | Exclude banner comment | | sortNodes | boolean | false | Sort declarations alphabetically | | umdModuleName | string | undefined | UMD module name (export as namespace) | | respectPreserveConstEnum | boolean | false | Respect tsconfig preserveConstEnums |

See the full API documentation for detailed descriptions and examples of each option.

Tips & Best Practices

  1. Multiple libraries: Separate with commas (CLI) or use an array (library)

    # CLI
    -i @org/pkg1,@org/pkg2,@org/pkg3
    // Library
    inlinedLibraries: ["@org/pkg1", "@org/pkg2", "@org/pkg3"];
  2. Scoped packages: Include the full scope

    inlinedLibraries: ["@mycompany/types", "@anothercompany/utils"];
  3. Package subpaths: Specify the exact import path

    inlinedLibraries: ["@mycompany/types/dist/api"];
  4. Check the output: Always verify the generated file matches your expectations

    bundle-types -e ./src/types.ts -o ./dist/bundle.d.ts
    head -50 ./dist/bundle.d.ts

Limitations

  • Only handles TypeScript files (.ts, .tsx, .mts, .cts, .d.ts, .d.mts, .d.cts)
  • Does not handle runtime JavaScript code (this is a type bundler)
  • Assumes all imported files exist and are accessible
  • Does not perform type checking (use tsc for that)
  • Circular dependencies may cause issues in complex scenarios

Requirements

  • Node.js >= 20
  • TypeScript ^5.9.3 (included as a dependency)

Troubleshooting

"Could not resolve import" warning

This warning appears when the bundler cannot find an imported file. Check:

  • The file path is correct
  • The file has a .ts, .tsx, or .d.ts extension
  • The file exists at the resolved location

Duplicate type definitions

If you see duplicate types in the output, ensure:

  • You're not importing the same file through multiple paths
  • Your import paths are consistent (absolute vs relative)

Process exits unexpectedly

If the entry file doesn't exist, the process will exit with code 1. Ensure:

  • The entry file path is correct
  • The file exists before running the bundler

Development

Running Tests

The project uses vitest for testing with snapshot testing for output verification.

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Update snapshots when output changes are intentional
pnpm test:update

Snapshot Testing

Tests use snapshots to verify bundler output. If you make changes that affect the generated output:

  1. Run pnpm test to see the diff
  2. Review the changes carefully
  3. If correct, run pnpm test:update to update snapshots
  4. Commit the updated snapshot files

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Related

License

ISC