Links#
https://docs.npmjs.com/cli/v11/configuring-npm/package-json
https://docs.npmjs.com/cli/v11/configuring-npm/npmrc
https://docs.npmjs.com/cli/v11/commands/npm-ci
https://docs.npmjs.com/cli/v11/commands/npm-publish
https://nodejs.org/api/packages.html
1. Important Points#
Node.js package management:
npm is default
package.json defines metadata/scripts/dependencies
package-lock.json locks versions
npm ci for CI/container build
do not commit auth token
{
"name": "@my-org/order-client",
"version": "1.0.0",
"type": "module",
"private": false,
"main": "./src/index.js",
"exports": {
".": "./src/index.js"
},
"files": [
"src",
"README.md"
],
"scripts": {
"test": "node --test",
"prepack": "npm test",
"pack": "npm pack",
"publish:dry": "npm publish --dry-run",
"publish:registry": "npm publish --access restricted"
},
"engines": {
"node": ">=20"
},
"publishConfig": {
"access": "restricted",
"registry": "https://registry.npmjs.org/"
}
}
3. Install Dependencies#
npm install express
npm install -D eslint @eslint/js
npm ci
npm install:
local development
npm ci:
CI / Docker
requires package-lock.json
4. Registry#
npm config get registry
npm config set registry https://registry.npmjs.org/
registry=https://registry.npmjs.org/
@my-org:registry=https://npm.pkg.github.com/
always-auth=true
5. Private Registry Auth#
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
cat > .npmrc <<'EOF'
@my-org:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
always-auth=true
EOF
npm ci
6. TLS / CA#
strict-ssl=true
cafile=/etc/ssl/private/company-ca.pem
export NODE_EXTRA_CA_CERTS=/etc/ssl/private/company-ca.pem
export npm_config_cafile=/etc/ssl/private/company-ca.pem
export npm_config_strict_ssl=true
do not:
strict-ssl=false in production
NODE_TLS_REJECT_UNAUTHORIZED=0 in production
7. Docker With Private Packages#
# syntax=docker/dockerfile:1
FROM node:22-bookworm-slim AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
docker build \
--secret id=npmrc,src="$HOME/.npmrc" \
-t order-api:local .
8. Create A Package / Library#
// src/OrderClient.js
export class OrderClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
}
async createOrder(request) {
const response = await fetch(`${this.baseUrl}/orders`, {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify(request)
});
if (!response.ok) {
throw new Error(`create order failed: ${response.status}`);
}
return response.json();
}
}
// src/index.js
export { OrderClient } from "./OrderClient.js";
9. Pack And Publish#
npm pack --dry-run
npm pack
npm publish --access restricted
publish checklist:
version updated
files allowlist reviewed
registry reviewed
access reviewed
10. Monorepo / Workspace#
{
"name": "order-platform",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
]
}
11. Production Checklist#
install:
package-lock.json committed
npm ci used in CI
registry pinned when required
token stored in secret manager
security:
no token in committed .npmrc
no token copied into Docker image
strict-ssl enabled
company CA configured when needed
publish:
exports reviewed
files allowlist reviewed
npm pack --dry-run reviewed
publishConfig reviewed