Tips & Tricks (Diperbarui: 2/6/2026)

Membuat dan Menerbitkan Paket npm dengan Claude Code

Buat paket npm dengan Claude Code: tsup, exports, tipe, npm pack, README generator, dan workflow CI publish.

Membuat dan Menerbitkan Paket npm dengan Claude Code

Meminta Claude Code untuk “membuat paket npm” biasanya menghasilkan file dengan cepat. Namun paket yang siap dipakai orang lain membutuhkan kontrak yang jelas: package.json, exports, deklarasi tipe, README yang sesuai API, pengecekan npm pack, dan workflow CI untuk publish. Jika salah satu bagian ini longgar, paket bisa berjalan di lokal tetapi gagal saat di-install oleh pengguna.

Panduan ini memakai paket utilitas string berbasis TypeScript. Claude Code digunakan sebagai rekan implementasi dan reviewer, bukan sebagai tombol publish otomatis. Untuk keputusan rilis sungguhan, pakai referensi resmi: npm package.json, scoped public packages, npm pack, trusted publishing, dan dokumentasi Claude Code.

Tulis Kontrak Paket Lebih Dulu

Prompt pertama sebaiknya tidak generik. Sebutkan nama paket, pengguna, runtime, format modul, perintah verifikasi, dan kebijakan publish. type: "module", main, exports, dan types saling terkait. Jika Claude Code hanya menulis salah satunya, package dapat build tetapi entry point rusak.

AreaKeputusan contohYang perlu dicek Claude Code
Nama@acme/string-kitapakah scoped public package perlu --access public
PenggunaNode.js dan TypeScriptapakah ESM import dan CJS require berjalan
Buildtsup menghasilkan ESM, CJS, tipeapakah dist berisi file di exports
Isi pakethanya dist, README.md, LICENSEapakah npm pack --dry-run menampilkan file tak terduga
PublishGitHub Actions + npm Trusted Publishingapakah token npm jangka panjang dihindari

Diagram singkat membantu Claude Code melihat seluruh alur, bukan hanya implementasi fungsi.

flowchart LR
  A["Brief paket"] --> B["package.json"]
  B --> C["src/index.ts"]
  C --> D["Vitest"]
  D --> E["tsup build"]
  E --> F["npm pack dry-run"]
  F --> G["CI publish"]

Jika paket Anda adalah CLI, lanjutkan ke pengembangan CLI dengan Claude Code. Untuk pola prompt dan verifikasi harian, baca tips produktivitas Claude Code.

Buat Proyek Minimal

Mulai dari folder bersih. Di repo besar, error package sering bercampur dengan workspace, dependency lama, atau script yang sudah ada.

mkdir string-kit
cd string-kit
npm init -y
npm install -D typescript tsup vitest @types/node
mkdir src scripts

package.json adalah kontrak publik. main untuk CJS, module untuk beberapa bundler, types untuk TypeScript, dan exports untuk entry point modern. files dibuat sempit agar test, draft, sourcemap, dan konfigurasi lokal tidak ikut terbit.

{
  "name": "@acme/string-kit",
  "version": "0.1.0",
  "description": "Small TypeScript string utilities used as an npm package example.",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    },
    "./package.json": "./package.json"
  },
  "files": ["dist", "README.md", "LICENSE"],
  "sideEffects": false,
  "scripts": {
    "build": "tsup",
    "test": "vitest run",
    "docs": "node scripts/write-readme.mjs",
    "test:pack": "npm pack --dry-run",
    "prepublishOnly": "npm run test && npm run build && npm run test:pack"
  },
  "keywords": ["string", "typescript", "utilities"],
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^22.15.0",
    "tsup": "^8.5.0",
    "typescript": "^5.8.0",
    "vitest": "^3.2.0"
  }
}

TypeScript dipakai untuk type check, sedangkan output JavaScript ditangani tsup. Pemisahan ini membuat review dist dan exports lebih mudah.

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "declaration": true,
    "declarationMap": true,
    "skipLibCheck": true,
    "noEmit": true
  },
  "include": ["src", "tsup.config.ts"]
}

Implementasi dan Test yang Benar-Benar Jalan

Artikel paket publik tidak boleh berhenti di pseudocode. Modul ini mengekspor empat fungsi kecil: slugify, truncate, interpolate, dan byteLength. Kodenya sederhana, tetapi cukup untuk membuktikan build, tipe, test, dan packaging.

export function slugify(input: string): string {
  return input
    .normalize("NFKD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

export function truncate(input: string, maxLength: number, suffix = "..."): string {
  if (!Number.isInteger(maxLength) || maxLength < 1) {
    throw new RangeError("maxLength must be a positive integer");
  }
  if (suffix.length >= maxLength) {
    throw new RangeError("suffix must be shorter than maxLength");
  }
  if (input.length <= maxLength) return input;
  return `${input.slice(0, maxLength - suffix.length)}${suffix}`;
}

export function interpolate(template: string, values: Record<string, string | number>): string {
  return template.replace(/\{\{\s*([\w.-]+)\s*\}\}/g, (match, key: string) => {
    return Object.hasOwn(values, key) ? String(values[key]) : match;
  });
}

export function byteLength(input: string): number {
  return new TextEncoder().encode(input).length;
}

Test mencakup kasus normal, batas, error, dan Unicode. Saat meminta Claude Code, tulis spesifik: aksen, placeholder tidak dikenal, panjang tidak valid, dan byte UTF-8.

import { describe, expect, it } from "vitest";
import { byteLength, interpolate, slugify, truncate } from "./index";

describe("slugify", () => {
  it("turns a title into an npm-friendly slug", () => {
    expect(slugify("Hello npm Package!")).toBe("hello-npm-package");
  });

  it("removes accents before replacing separators", () => {
    expect(slugify("Crème brûlée utils")).toBe("creme-brulee-utils");
  });
});

describe("truncate", () => {
  it("keeps short text unchanged", () => {
    expect(truncate("short", 10)).toBe("short");
  });

  it("adds a suffix inside the requested length", () => {
    expect(truncate("Claude Code package", 12)).toBe("Claude Co...");
  });

  it("rejects invalid lengths", () => {
    expect(() => truncate("abc", 2)).toThrow(RangeError);
  });
});

describe("interpolate", () => {
  it("replaces known placeholders and keeps unknown ones", () => {
    expect(interpolate("Hi {{ name }}, ship {{pkg}} {{missing}}", {
      name: "Masa",
      pkg: "@acme/string-kit",
    })).toBe("Hi Masa, ship @acme/string-kit {{missing}}");
  });
});

describe("byteLength", () => {
  it("counts UTF-8 bytes", () => {
    expect(byteLength("npm")).toBe(3);
    expect(byteLength("日本語")).toBe(9);
  });
});

tsup dan README Generator

Konfigurasi tsup tetap kecil. outExtension membuat ESM sebagai .js dan CJS sebagai .cjs, sesuai package.json. sourcemap dimatikan agar source map internal tidak terpublish tanpa keputusan sadar.

import { defineConfig } from "tsup";

export default defineConfig({
  entry: ["src/index.ts"],
  format: ["esm", "cjs"],
  dts: true,
  clean: true,
  sourcemap: false,
  minify: false,
  target: "es2022",
  outDir: "dist",
  outExtension({ format }) {
    return { js: format === "esm" ? ".js" : ".cjs" };
  },
});

README mudah tertinggal dari kode. Generator kecil menjaga contoh install dan usage tetap selaras dengan API.

import { writeFile } from "node:fs/promises";

const fence = String.fromCharCode(96).repeat(3);
const readme = `# @acme/string-kit

Small TypeScript string utilities packaged with tsup.

## Install

${fence}bash
npm install @acme/string-kit
${fence}

## Usage

${fence}ts
import { slugify, truncate } from "@acme/string-kit";

console.log(slugify("Hello npm Package!"));
console.log(truncate("Claude Code package", 12));
${fence}
`;

await writeFile(new URL("../README.md", import.meta.url), readme);

Verifikasi dengan npm pack

npm publish jangan menjadi verifikasi pertama. npm pack --dry-run menunjukkan file yang akan masuk registry. Cek README, LICENSE, tipe, output ESM/CJS, dan pastikan test atau draft tidak ikut.

npm run docs
npm test
npm run build
npm pack --dry-run
node -e "import('./dist/index.js').then((m)=>console.log(m.slugify('Hello ESM')))"
node -e "const m=require('./dist/index.cjs'); console.log(m.slugify('Hello CJS'))"

Untuk smoke test yang lebih mirip pengguna, install .tgz di folder lain.

npm pack
mkdir ../string-kit-smoke
cd ../string-kit-smoke
npm init -y
npm install ../string-kit/acme-string-kit-0.1.0.tgz
node -e "import('@acme/string-kit').then((m)=>console.log(m.truncate('Claude Code package', 12)))"

Ada tiga contoh penggunaan nyata. Tim produk dapat berbagi aturan string antara web, admin, dan dokumentasi. Tim konten dapat memakai truncate dan interpolate untuk deskripsi, kartu, dan release notes. Design system atau CLI dapat menerbitkan utilitas kecil agar aplikasi upgrade dengan SemVer.

Publish dari GitHub Actions

Publish dari CI membuat proses lebih bisa direview. npm Trusted Publishing memakai OIDC dan mengurangi kebutuhan token npm jangka panjang. Konfigurasikan trusted publisher di npm, lalu batasi publish hanya pada event release.

name: package

on:
  push:
    branches: [main]
  pull_request:
  release:
    types: [published]

permissions:
  contents: read
  id-token: write

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org
          cache: npm
      - run: npm ci
      - run: npm run docs
      - run: npm test
      - run: npm run build
      - run: npm pack --dry-run

  publish:
    if: github.event_name == 'release'
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org
          cache: npm
      - run: npm ci
      - run: npm run docs
      - run: npm test
      - run: npm run build
      - run: npm publish --access public

Untuk changelog dan SemVer yang lebih rapi, kombinasikan dengan Claude Code dan Changesets.

Jebakan Umum

Jebakan pertama adalah hanya memakai main dan lupa exports. Kedua, files terlalu luas sehingga test, draft, atau sourcemap ikut publish. Ketiga, README tidak diperbarui setelah nama fungsi atau scope berubah. Keempat, menjanjikan Unicode yang tidak dipenuhi: truncate ini memakai panjang string JavaScript, bukan grapheme visual. Kelima, menyerahkan keputusan nama, scope, 2FA, Trusted Publishing, dan approval release akhir kepada Claude Code.

Template Prompt Claude Code

Create a TypeScript npm package.

Goal:
- Package name: @acme/string-kit
- Support both ESM import and CJS require
- Use tsup to emit dist/index.js, dist/index.cjs, and dist/index.d.ts
- Include README generation, Vitest tests, and npm pack verification

Constraints:
- Only touch package.json, tsconfig.json, tsup.config.ts, src, scripts, and .github/workflows
- Do not use pseudocode; the project must run after npm install
- Do not publish source maps or unnecessary test files in the package tarball

Acceptance criteria:
- npm test passes
- npm run build passes
- npm pack --dry-run output is summarized
- ESM import and CJS require smoke tests are shown
- List the human release checks before npm publish

CTA: Jadikan Workflow Publish sebagai Template

Paket npm tidak selesai setelah versi pertama. README, CI Node version, dependencies, permissions, dan strategi SemVer akan berubah. Mulai dari cheatsheet Claude Code gratis untuk prompt aman dan command verifikasi. Untuk template siap pakai, lihat produk ClaudeCodeLab. Untuk tim yang perlu mengatur CLAUDE.md, CI, izin publish, dan review, gunakan training dan konsultasi Claude Code.

Saya mencoba workflow ini di folder sementara Windows: npm install, npm test, npm run build, npm pack --dry-run, serta smoke test ESM/CJS dengan node -e semuanya lolos. Dalam kerja Masa, meminta Claude Code menjelaskan output npm pack sebelum release sering menangkap README usang, tipe hilang, dan file tak terduga di tarball.

Ringkasan

Claude Code mempercepat pembuatan paket npm, tetapi kontrak publish harus tetap eksplisit. Satukan package.json, exports, tipe, tsup, test, README, npm pack, dan CI. Sebelum publish, cek dist, cek tarball, dan coba entry point yang sama dengan pengguna.

#Claude Code #npm #packagepublikasi #TypeScript #OSS
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.