Skip to content

kazvizian/packlet-js

Repository files navigation

📦️ Packlet

TypeScript Bun
Conventional Commits Commitizen friendly license
Turborepo Changesets Butterfly Biome Linter & Formatted

gzip size

A concise toolkit for packaging and creating deterministic release artifacts.

Packages

  • @packlet/core – Core utilities: artifact manifest, validation, name derivation, copy helpers
  • @packlet/gpr – Tools for preparing GitHub Packages (GPR) scoped variants and tarballs
  • @packlet/cli – Unified CLI exposing packlet commands (gpr, validate, list-artifacts)
  • @packlet/build – Lightweight build wrapper (ESM+CJS+d.ts) usable in any TS/JS package

Philosophy

  • Deterministic packing and artifact generation belong to packlet.
  • Orchestration and publishing (CI, tokens, releases) are handled by sailet — see related docs in docs/.
  • Both interact through a stable artifacts.json manifest.

Quick Start (monorepo)

# install & build
bun install
bun run build

# prepare a GPR variant and output a JSON manifest
node packages/cli/dist/index.mjs gpr --root packages/gpr --json

# list artifacts (human or JSON output)
node packages/cli/dist/index.mjs list-artifacts --artifacts packages/gpr/.artifacts
node packages/cli/dist/index.mjs list-artifacts --artifacts packages/gpr/.artifacts --json

# validate dist
node packages/cli/dist/index.mjs validate --root packages/gpr --json

Build system

All packages are built with the lightweight wrapper @packlet/build, which standardizes:

  • ESM outputs: dist/index.mjs (CJS available via --cjs when explicitly requested)
  • Type declarations: dist/index.d.ts via tsc --emitDeclarationOnly
  • Minification: enabled by default (use --no-minify to disable during debugging)

Typical package scripts:

{
  "scripts": {
    "build": "node packages/build/dist/cli.mjs build --sourcemap none --external-auto",
    "build:cli": "node packages/build/dist/cli.mjs build --cjs --exec-js --sourcemap none --external-auto"
  },
  "devDependencies": {
    "@packlet/build": "workspace:*"
  }
}

For CLI packages (including the umbrella packlet and @packlet/cli), --exec-js marks the built entry executable (prefers index.mjs).

Changelogs

Each package maintains its own CHANGELOG.md generated by Changesets during real releases. The umbrella packlet package contains an aggregate changelog that summarizes notable changes across all packages; it is populated only when a release is performed. This keeps history clear while avoiding noise between releases.

CLI Commands (packlet)

  • packlet build – Build ESM + CJS outputs and emit .d.ts (flags: --entry, --outdir, --formats, --sourcemap, --no-types, --target, --exec-js, --no-minify)

  • packlet gpr – Prepare a GPR-staged package and tarballs Flags: --root, --gpr-dir, --artifacts, --dist, --scope, --registry, --name, --include-readme, --no-include-readme, --include-license, --no-include-license, --json, --manifest <file>

  • packlet validate – Verify required dist entries (index.js, index.mjs, index.d.ts)

  • packlet list-artifacts – List all .tgz files in an artifacts directory

Note

@packlet/gpr also provides a lightweight prepare subcommand (mainly for CI or testing). It conditionally stages the GPR variant if packlet.gpr is enabled and dist/ exists. Supported flags: --root, --dist, --gpr-dir, --artifacts, --scope, --registry, --name, with optional --json and --manifest <file> for machine-readable output.

Artifacts Manifest

Running packlet gpr generates <root>/.artifacts/artifacts.json:

{
  "schemaVersion": 1,
  "packageName": "<base-name>",
  "scopedName": "@<scope>/<base-name>",
  "version": "<semver>",
  "artifacts": [
    { "file": "<name>-<version>.tgz", "size": 12345, "sha512": "..." }
  ]
}

Name derivation (for GPR)

Priority used when deriving the staged GPR package name:

  1. Explicit overrides
  • packlet.gprName in package.json (scoped or unscoped), or
  • --name flag / GPR_NAME env (scoped or unscoped)
  1. Monorepo default: package name
  • In monorepos, we prefer the package's own name (scope stripped) as base.
  1. Single-package repos
  • Use repo name from repository.url if present, otherwise package.json.name (scope stripped).

Unscoped bases are combined with the chosen scope (default kazvizian).

You can set packlet.gprName to values like packlet-core (becomes @kazvizian/packlet-core) or a fully scoped value @acme/packlet-core to force a specific name.

Developer Notes

Temporary test fixtures are created under .temp/ and cleaned up automatically.

CI & Windows

  • Windows runners do not honor POSIX execute bits. Tests that verify chmod +x fall back to asserting file presence on Windows.
  • npm pack can be slow/flaky on Windows. The GPR preparation logic auto-skips packing when CI=true and the platform is Windows, or when GPR_SKIP_PACK=true is set.

Environment variables:

  • GPR_SKIP_PACK=true — force skip npm pack in GPR preparation.
  • CI=true on Windows — implicitly skips npm pack.

License

MIT © KazViz

About

A KazVizian toolkit to prepare deterministic release artifacts and packaging.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 3

  •  
  •  
  •