skills/rslib-modern-package/SKILL.md
Opinionated Rslib recommendations for modern JS/TS npm package design covering pure ESM, strict TypeScript, explicit exports, small stable APIs, pragmatic dependencies, accurate sideEffects, correct declarations, package validation, provenance, README.md, and AGENTS.md. Use when the user wants to make a JS/TS package more modern, check whether the current package setup is healthy, review package.json/exports/types/dependencies/docs/release readiness, or apply a modern library baseline.
npx skillsauth add rstackjs/agent-skills rslib-modern-packageInstall 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.
Use this skill when creating a new Rslib library, modernizing an existing JS/TS package, or reviewing a package against an opinionated modern library standard.
This skill is opinionated: it describes a recommended modern package contract and may suggest breaking changes when they make the package simpler, safer, and easier for modern consumers.
Default recommendation for new JS/TS libraries:
package.json#exports.sideEffects.Inspect the package contract first
package.json, lockfile/package manager, rslib.config.*, tsconfig*, CI/release config, README.md, AGENTS.md, and existing dist output.npm pack --dry-run early when changing package shape so the real tarball contents guide the review.Define target environments explicitly
engines.engines.node >=22 unless real consumers need an older runtime.Prefer pure ESM, but explain compatibility cost
"type": "module" and ESM source/output.require(esm); do not assume CJS consumers always require a separate CJS build.require(esm) compatibility, document and test its constraints: supported Node versions, no top-level await in the loaded graph, namespace-object return shape, default export behavior, and CJS/ESM cycle limits.node:fs/promises.Make exports the public API
package.json#exports as the product contract.pkg/dist/foo.js by exporting ./dist/*. That makes the generated output layout part of the public API and turns internal file moves into breaking changes.pkg and pkg/foo.js, mapped to the actual files in dist../foo.js, or all without extensions. Prefer paths with extensions when browser import maps matter."types" first inside conditional exports.exports to an older package can be breaking because undeclared deep imports stop working../package.json only when consumers legitimately need package metadata.Design a small API surface
AbortSignal.Use Rslib as the implementation path, not the whole standard
rslib-best-practices skill.package.json#exports, files, dependencies, and docs agree with the modern package contract.Keep dependencies small and intentional
URL, URLSearchParams, Intl, fetch, AbortController, structuredClone, crypto.randomUUID, Web Streams, TextEncoder, TextDecoder, node:fs/promises, and node:crypto.exports, types, transitive dependency count, package size, license, maintenance activity, security history, install scripts, side effects, native install fragility, and granular imports.dependencies.peerDependencies, such as React, Vue, Svelte, Rspack, Rsbuild, webpack, TypeScript, and framework runtimes.devDependencies.optionalDependencies or optional peers via peerDependenciesMeta for optional integrations.Make TypeScript strict and package-oriented
strict: true explicitly.lib.dts.tsgo to speed up declaration generation when the project can use tsgo.module and moduleResolution aligned with how declarations are emitted and how consumers resolve the package; NodeNext and bundler-style resolution are both valid in the right toolchain.verbatimModuleSyntax so type-only imports/exports are explicit.isolatedDeclarations when practical so exported APIs are explicit enough for declaration-oriented tooling.import type and export type for type-only dependencies.skipLibCheck to hide broken package types.Keep sideEffects accurate
sideEffects: false only when importing package files has no top-level side effects.sideEffects: false just to improve bundle size; incorrect values can remove required CSS or setup code.setup() or install() function and let users call it themselves.Make package.json authoritative
"type": "module", explicit exports, correct declarations, files allowlist, accurate sideEffects, sensible engines, and release scripts.files when they exist.files should prevent tests, fixtures, private docs, build caches, local configs, and large generated artifacts from leaking into the tarball.main/module fields unless compatibility evidence requires them; if kept, they must agree with exports.devDependencies is broken.Validate the published artifact
rslib build.npm pack --dry-run and inspect included files.rsbuild-plugin-publint to run publint after build; use npx publint as a CLI fallback.rsbuild-plugin-arethetypeswrong to run Are The Types Wrong after build when declarations are shipped; use npx --yes @arethetypeswrong/cli --pack . as a CLI fallback.bin packages, and every public subpath export.Prepare README.md and AGENTS.md before publishing
package.json#exports, supported runtimes, and actual Rslib output.Publish with supply-chain hygiene
exports is missing, points to files not emitted by Rslib, or allows public imports such as pkg/dist/foo.js.module/main fields disagree with exports.devDependencies.dependencies when it should be a peer.sideEffects: false is set while importing CSS, polyfills, global registrations, global listeners, or prototype changes.window/process.package.json has "type": "module".exports.exports, and files agree.sideEffects is accurate.npm pack --dry-run has been inspected.publint passes.development
Debug Rstest issues systematically, including performance regressions. First determine whether the slowdown is in build startup or test execution, then run controlled config or code experiments and compare before/after timings.
development
Create or update draft GitHub releases for the current project's main GitHub repository, then organize GitHub-generated release notes into user-friendly sections without rewriting release note items. Use for preparing, formatting, categorizing, creating, or updating GitHub release notes or draft releases, including optional highlights when the user asks for them.
tools
Migrate ESLint or other linters to Rslint. Use when asked to replace ESLint flat config, lint scripts, VS Code ESLint settings, inline directives, rules, presets, plugins, or lint dependencies with Rslint equivalents.
development
Use when analyzing Rspack/Webpack bundles from local `rsdoctor-data.json` and producing evidence-based optimization recommendations.