frontier/skills/esm/SKILL.md
Use when writing JavaScript or TypeScript modules, creating Node.js projects, adding imports or exports, setting up package.json, tsconfig, or resolving file paths — ensure modern ESM is used instead of CommonJS.
npx skillsauth add jon23d/skillz esmInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Always use ECMAScript Modules (ESM). Never use CommonJS (require, module.exports, __dirname, __filename). This applies to all new files and to any existing file you edit — migrate it to ESM in the same pass.
Imports and exports:
import / export — never require() or module.exports.js extension on local imports (even when the source is .ts)package.json:
"type": "module" in every package.jsonPath resolution (__dirname / __filename):
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
import.meta.url directly when only a URL is needed (e.g. new URL('../data.json', import.meta.url))Node.js built-ins:
node: protocol prefix: import fs from 'node:fs', import path from 'node:path'Dynamic imports:
await import('./module.js') when lazy-loading is needed — not require()Use "module": "NodeNext" and "moduleResolution": "NodeNext" in tsconfig.json. This is the only correct configuration for ESM TypeScript targeting Node.js.
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2022",
"outDir": "dist"
}
}
.js extensions in import paths even in .ts files — TypeScript resolves the source but Node.js loads the compiled outputimport type for type-only imports to avoid runtime overhead// Correct in a .ts file
import { formatDate } from './utils.js';
import type { Config } from './config.js';
When you edit any file that uses CommonJS, convert the whole file to ESM in the same edit:
require() with importmodule.exports = ... / exports.x = ... with export__dirname / __filename with the fileURLToPath pattern"type": "module" in package.json"type": "module" → Node.js defaults to CJS, breaking all import statements. Fix: add "type": "module" to package.json..js extension on local imports → ESM does not auto-resolve extensions. import './utils' fails; import './utils.js' works.__dirname directly → Not defined in ESM. Use the fileURLToPath pattern above.require() for JSON files → Use JSON.parse(await fs.readFile(new URL('./data.json', import.meta.url), 'utf8')) or the import assertion syntax if supported.import — CJS interop works one-way (ESM can import CJS; CJS cannot require ESM)."module": "CommonJS" in tsconfig → Incompatible with ESM output. Use "NodeNext".// package.json
{ "type": "module" }
// Named export
export function formatDate(date) { ... }
export const config = { ... };
// Default export
export default class Server { ... }
// Import local module (extension required)
import { formatDate, slugify } from './utils.js';
// Import node built-in
import { readFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
// __dirname equivalent
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
// JSON file
const data = JSON.parse(
await readFile(new URL('./data.json', import.meta.url), 'utf8')
);
// Dynamic import
const { default: mod } = await import('./plugin.js');
development
Use when adding or modifying environment variable handling in TypeScript projects or monorepos — especially when using process.env directly, missing startup validation, sharing env schemas across packages, or encountering "undefined is not a string" errors at runtime from missing env vars.
testing
Use when creating a new skill, editing an existing skill, writing a SKILL.md, or verifying a skill works before deployment.
development
React UI design principles and conventions. Load when building or modifying any user interface or React components. Covers application type detection, visual standards, component design and structure, Mantine (business apps) and Tailwind (consumer apps), accessibility, responsiveness, state management, data fetching, testing, and in-app help patterns.
development
Use when setting up ESLint and/or Prettier in a TypeScript project, adding linting to an existing TypeScript codebase, or configuring typescript-eslint, eslint-config-prettier, or related packages.