generatePackageJson on a js:tsc target to create a distributable package in its output directory. Add generateExportsField when you also want inferred exports.
Generated packages
The projectpackage.json is optional. When present, it must contain name and
version. Otherwise, generation uses the Isox project name and workspace root
version (or 0.0.0 when the root has no version).
It preserves package metadata and production/optional/peer dependencies, strips
scripts, development dependencies, workspace and package-manager settings, and
infers runtime dependencies from the project’s compiled sources. Source metadata
is never rewritten. Existing
main, module, types/typings, bin, exports, and type-version
paths are translated and checked against generated output. Existing exports win
when additional subpaths are merged. Conditional root exports cannot be merged
with additional subpaths until expressed as a subpath map.
For ordinary packages without explicit entry points, emitted index.js,
index.mjs, or index.cjs and corresponding declarations supply defaults.
Declarations emitted into a separate declarationDir are copied under types/
in the distributable package, with declaration-map paths adjusted. Explicit and
wildcard declaration exports are rewritten to that location.
Plugin registries and workspace versions
For plugins, the executor copies and rewrites the registries referenced byexecutors and generators (usually executors.json and generators.json) and
their schemas, preserving implementation paths without creating a root entry
point. Package-local README, license, and notice files are included when present.
workspace:*, workspace:^, and workspace:~ become publishable versions using
package manifests of discovered Isox projects. Workspace aliases and
relative workspace references are supported; unresolved packages or unsupported
workspace ranges fail. Projects without manifests use their Isox names and the
workspace version for these references. Lockfiles are not generated.
Dependency detection
Dependency detection parses TypeScript and JavaScript syntax. Default, named, namespace, and side-effect imports, runtime re-exports, literalimport(),
require(), and require.resolve() calls count. Module-local
createRequire(__filename) and createRequire(import.meta.url) calls are also
recognized, including aliases. A require created for another package’s path is
not treated as this project’s dependency; neither are require.resolve calls
with explicit lookup options for another workspace. Computed module names cannot
be inferred.
This package-generation analysis uses the build’s source inputs and its own
runtime/type classification. It does not substitute the project dependency lists
from discovery.json for the dependencies written to the published manifest.
import type, export type, inline type-only bindings, and import() type
expressions add dependencies only for local workspace packages, so published
declarations can resolve their workspace types. External type-only packages are
not inferred. Mixed imports count when they have a runtime
binding. Declaration files, comments, ordinary strings, Node builtins, relative
imports, self-imports, and path aliases resolved within the project are excluded.
Dependency versions
Existing project runtime, optional, and peer declarations keep their ranges and classification. For newly detected packages, versions come first from the project manifest, then the workspace root manifest (includingdevDependencies),
then matching Isox workspace projects. Scoped subpaths collapse to their package
name, and npm aliases are preserved. For example,
createRequire(__filename).resolve('@typescript/native/package.json') adds
@typescript/native using its root-manifest alias even when the project has no
manifest entry. Missing versions fail generation with an actionable error.
Output and failures
Output may live outside the project directory, within the workspace, such as<workspace>/dist/<package>. Executor schemas already supplied as output assets
are reused when generating the manifest. publishConfig.exports overrides the
source exports map; its paths are relative to the output package. Build-only
publishConfig.directory and linkDirectory fields are removed from generated
metadata so the resulting package can be packed directly. Generated manifests
omit files, including any allowlist from the source manifest.
Metadata is written atomically after successful compilation and packaging
validation. Type errors preserve previous output and metadata. A packaging error
fails the build even if TypeScript has already emitted updated files.
Reusing package generation in plugins
Import the shared generator from@isox-sh/js/helpers (or
@isox-sh/js/helpers/package-json). Its PackageJsonOptions and
PackageJsonContext types are exported from both entry points.
emittedFiles is a set of absolute compiler output paths; assets maps absolute
output paths to buffers. The optional declarationDir identifies separately
emitted declarations. The returned Map<string, Buffer> includes the generated
manifest and supporting package files. Plugins can modify these buffers or add
entries before publishing them. The helper does not write files: the calling
plugin owns output validation, writing, and cleanup.
Pass tsConfig (absolute or relative to the workspace root) and optionally
sourceFiles (absolute paths) to select sources for dependency detection. The
TypeScript executor supplies these automatically. Without them, the helper uses
the nearest tsconfig; if none exists, it scans emitted JavaScript instead.
Back to TypeScript.