simple-js-library
v1.0.1
Published
Testing JS NPM Library
Readme
Simple JS Library (TypeScript + TSUP)
A minimal example of a modern npm library built with TypeScript and tsup, outputting:
- CommonJS (CJS)
- ES Modules (ESM)
- Type Definitions (DTS)
This README documents every step, the issues encountered, and how they were resolved.
1. Project Setup
Create a new folder and initialize npm:
mkdir simple-js-library
cd simple-js-library
npm init -yInstall dependencies:
npm install tsup typescript --save-devProject structure:
simple-js-library/
src/
index.ts
dist/ (generated)
package.json
tsconfig.json2. Source Code (src/index.ts)
export function HelloWorld() {
console.log("Hello World");
}3. TypeScript Configuration (tsconfig.json)
The library uses TypeScript only to generate type definitions. JavaScript output is handled by tsup.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "dist",
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}Key points:
emitDeclarationOnly: trueensures TypeScript emits only.d.tsfiles.module: "ESNext"avoids conflicts with tsup.- JavaScript is generated solely by tsup.
4. TSUP Build
Add this script in package.json:
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --clean"
}Run the build:
npm run buildExpected output in dist/:
index.js(CJS)index.mjs(ESM)index.d.ts(types)
5. Correct package.json
Because tsup produces index.js (CommonJS) and index.mjs (ESM), the entries must line up with those filenames:
{
"name": "simple-js-library",
"version": "1.0.0",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
}
},
"files": ["dist"],
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --clean"
}
}6. Local Testing (Recommended: npm pack)
Simulate a real publish:
npm run build
npm packThis generates:
simple-js-library-1.0.0.tgzTest it in another project:
npm install ../simple-js-library/simple-js-library-1.0.0.tgzUsage:
const { HelloWorld } = require("simple-js-library");
HelloWorld();7. Issues Encountered & Resolutions
7.1 TypeScript error
"A top-level export modifier cannot be used in a CommonJS module when verbatimModuleSyntax is enabled."
- Cause:
verbatimModuleSyntax: truecombined withmodule: "CommonJS"caused conflicts. - Fix: Use
"module": "ESNext"so TypeScript emits declarations only.
7.2 TSUP was not generating .cjs files
- Cause: tsup emitted CommonJS as
index.js(its default) whilepackage.jsonexpectedindex.cjs. - Fix: Keep tsup defaults and adjust
package.jsonto referenceindex.jsfor CommonJS.
7.3 Node error
"Cannot find module dist/index.cjs."
- Cause:
exports["."].requirepointed to./dist/index.cjs, a file that does not exist. - Fix: Point
requireto./dist/index.jsandimportto./dist/index.mjs.
7.4 Local install copied too many files
- Cause:
npm install ../foldercopies the entire folder. - Fix: Use
npm packand install the generated tarball to mimic a real publish.
8. Everything Working
Final setup:
- tsup emits CJS + ESM correctly.
package.jsonpoints to the generated files.- TypeScript generates types only.
- Local testing works via
npm pack. - Both
require()andimportcalls succeed:
const { HelloWorld } = require("simple-js-library");
HelloWorld();
import { HelloWorld } from "simple-js-library";
HelloWorld();9. Ready for Publish
Publish the package:
npm publish --access publicThis project now follows a standard modern structure for npm libraries built with TypeScript and tsup.
