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

@lint-suite/eslint-plugin-type-placement

v1.0.0

Published

Require types and type-only imports to use prescribed file placement

Readme

@lint-suite/eslint-plugin-type-placement

An ESLint rule for TypeScript and Angular-style feature code that enforces predictable locations for exported types, constants, and internal type-only imports. It keeps shared exported types in common/*.type.ts, limits *.type.ts and *.const.ts exports, and ensures internal import type declarations target type-oriented modules.

Install

Requires Node.js 24+, ESLint ^10.9.1, and TypeScript >=6.0.3.

pnpm add -D @lint-suite/eslint-plugin-type-placement eslint@^10.9.1 typescript@">=6.0.3" typescript-eslint

The plugin does not configure a TypeScript parser. Use typescript-eslint for TypeScript files:

// eslint.config.js
import typePlacement from '@lint-suite/eslint-plugin-type-placement';
import tseslint from 'typescript-eslint';

export default [{
  files: ['**/*.ts'],
  languageOptions: { parser: tseslint.parser },
  plugins: { typePlacement },
  rules: { 'typePlacement/type-placement': 'error' }
}];

Options

internalPatterns defaults to []. Each supplied string becomes a regular expression. A matching non-relative import type source is treated as internal and must be a *.type.ts, *.schema.ts, or common barrel.

rules: {
  'typePlacement/type-placement': ['error', {
    internalPatterns: ['^@workspace/']
  }]
}

This non-default option makes @workspace/* type-only imports subject to the internal-source restriction. Without it, non-relative package and workspace-alias imports are allowed.

Filename rules and exemptions

Filename is part of this rule's contract. Exported type aliases and interfaces belong in common/*.type.ts or test/common/*.type.ts. A *.type.ts file may export only type aliases and interfaces; a *.const.ts file may export only const variable declarations.

Relative import type sources are internal. Their companion module must have a final filename segment ending in .type.ts or .schema.ts, unless the source is a common barrel such as ../common or ./common/index.ts. The same requirement applies to non-relative imports that match internalPatterns.

The rule does not inspect files ending in .spec.ts, .stub.ts, .schema.ts, or .d.ts; state.type.ts files; or files below a /fixtures/ path. The exemption applies to the entire file.

Examples

Each snippet below is checked by this rule alone, not by an entire ESLint configuration. Every example states its filename; import examples also state the required companion filename. The internalPatterns option is called out where it is non-default.

Valid examples

1. Exported type in a common type file

// Filename: src/orders/common/order.type.ts
export type Order = { readonly id: string };

2. Exported interface in a test common type file

// Filename: src/orders/test/common/order.type.ts
export interface Order { readonly id: string }

3. Const-only export in a const file

// Filename: src/orders/order.const.ts
export const PAGE_SIZE = 20;

4. Relative type import from a type file

// Filename: src/orders/order.ts
// Companion file: src/orders/common/order.type.ts
import type { Order } from './common/order.type.ts';

5. Relative type import from a common barrel

// Filename: src/orders/order.ts
// Companion barrel: src/orders/common/index.ts
import type { Order } from './common/index.ts';

6. External alias import with default options

// Filename: src/orders/order.ts
import type { Signal } from '@angular/core';

This remains valid because internalPatterns defaults to [].

Invalid examples

1. Exported type outside a common type file

// Filename: src/orders/order.ts
export interface Order {}

Move the type to src/orders/common/order.type.ts.

2. Type file outside a common directory

// Filename: src/orders/order.type.ts
export type Order = { readonly id: string };

The .type.ts suffix alone is insufficient; the file must be under common.

3. Value export in a common type file

// Filename: src/orders/common/order.type.ts
export const DEFAULT_ORDER = { id: 'new' };

*.type.ts files may export only type aliases and interfaces.

4. Function export in a const file

// Filename: src/orders/order.const.ts
export function createOrder() {}

*.const.ts files may export only const variable declarations.

5. Relative type import from a regular module

// Filename: src/orders/order.service.ts
// Companion file: src/orders/order.ts
import type { Order } from './order.ts';

The companion must instead be a .type.ts, .schema.ts, or common barrel module.

6. Internal alias type import from a regular module

// Filename: src/orders/order.ts
// Non-default rule option: { internalPatterns: ['^@workspace/'] }
// Companion module: @workspace/orders
import type { Order } from '@workspace/orders';

Because the non-default option marks this alias as internal, its companion must be a type file, schema file, or common barrel.

The named typePlacementRule export is for composed plugin registries.