Streamline your local Node.js package dependency workflow.
Knit is a fork of yalc, which was created by @wclr. The name is inspired by this GitHub thread.
knit
is a CLI with a local repository designed to mirror a remote package repository, such as npm. It allows you to publish packages from a local project folder to a local store, and install them in other local projects. It also allows you to easily propagate package updates.
knit
can be used with projects where package managers, such as npm
, yarn
, or pnpm
, are used
for managing package.json
dependencies. knit
creates a knit.lock
file in your project (similar to yarn.lock
and package-lock.json
) that is used to ensure consistency while performing knit
routines.
Install locally in a project (replace yarn
with your preferred package manager):
yarn add -D @omnidev/knit
Or execute it directly and ephemerally with yarn dlx
:
yarn dlx @omnidev/knit [...]
knit publish
: publish a package to a local store (~/.knit
by default)
knit add $PACKAGE_NAME
: add a package from the store to a project
$PROJECT_DIR/.knit/
and injects a relative local (file:
/link:
depending on usage) dependency into package.json
knit link $PACKAGE_NAME
which creates a symlink in node_modules
to the package content, and will not modify package.json
(like npm/yarn link
does), or you even may use it with npm
/yarn
/pnpm
workspacesknit help
for helpknit publish
)Run in a project to publish it to the store.
Copies all the files that should be published to a remote registry
If your package has any of these lifecycle scripts, then will run before publishing, in the following order:
prepublish
prepare
prepublishOnly
prepack
preknitpublish
If your package has any of these lifecycle scripts, they will run after publishing, in the following order:
postknitpublish
postpack
publish
postpublish
Use --no-scripts
to publish without running scripts
When publishing, knit
can optionally calculate a hash signature from the file contents and use the signature in the resulting package version
(e.g. "1.2.3+ffffffff"
). To enable this, pass --sig
to the knit publish
command
Use .knitignore
to exclude files from publishing to knit repo, such as README.md
---content
will show included files in the published package
Considering publishing, knit
emulates the behavior of the npm
client (npm pack
). If you have a nested .knit
folder in your package that you are going to publish with knit
and you use the package.json
files
key, it should be included there explicitly. See wclr/yalc#95
If you want to include the .knit
folder in published package content, add the !.knit
pattern to .npmignore
By default, Knit resolves the workspace:
protocol in dependencies. This can be bypassed with --no-workspace-resolve
For convenience, you can automatically propagate package updates to dependent projects
Note for Windows users: make sure the LF
(line feed) symbol is used in published sources; it may be needed for some packages to work correctly (for example, bin
scripts). knit
won't convert line endings for you (because npm
and yarn
won't either)
knit add
)Run in a project to pull a package from the store and install it as a dependency.
.knit
folder and injects a file:.knit/$PACKAGE_NAME
dependency into package.json
knit add $PACKAGE_NAME@version
. This version will be fixed in knit.lock
and will not affect newly published versions during updates--link
to add a link:
protocol dependency instead of the file:
protocol--dev
to add the package as a development dependency (devDependencies
)--pure
to avoid modifying package.json
and node_modules
--workspace
(or -W
) to add a dependency with workspace:
protocolknit link
)As an alternative to add
, you can use the link
command. This is similar to npm link
/yarn link
, except the symlink source will be the local .knit
folder of your project instead of the global link directory.
After knit
copies package content to the .knit
folder, it will create a symlink (and not modify package.json
): $PROJECT_DIR/.knit/$PACKAGE_NAME ⟹ $PROJECT_DIR/node_modules/$PACKAGE_NAME
.
knit update
)Run knit update $PACKAGE_NAME
to update to the latest version of $PACKAGE_NAME
from the store, or just knit update
to update all the packages found in knit.lock
.
preknit
and postknit
scripts will be executed in the target package as part of add and update operations (which are performed during knit push
, see push section)(pre|post)knit.package-name
script in your package.json
--update
(or --upgrade
/--up
) to run your package managers's update command for packagesknit remove
)knit remove $PACKAGE_NAME
to remove the package's dependency information from package.json
and knit.lock
knit remove --all
to remove all packages from a projectknit installations
)knit installations clean $PACKAGE_NAME
to unpublish a package previously published with knit publish
knit installations show $PACKAGE_NAME
to show all packages where $PACKAGE_NAME
has been installedknit publish --push
(or knit push
) will publish your package to the store and propagate all changes to existing knit
package installations (this performs the update
operation on the target location).
When you run knit add|link|update
, the project's package locations are tracked and saved, so knit
knows where each package in the store is being used in your local environment.
The scripts
option is false
by default, so it won't run pre/post
scripts (change this behavior by passing --scripts
).
Flags:
--changed
: causes knit
to first check if the package content has changed before publishing and pushing
--replace
: causes knit
to force replacement of the package contentpreknit
and postknit
(detailed in Update section): execute lifecycle script(s) on every push--update
: run the npm|yarn|pnpm update
command for pushed packagesknit
filesIt is up to you whether you would like to commit the files generated by knit
(.knit/
and knit.lock
) to your repository.
Reasons not to commit:
knit
modules temporarily during developmentknit link
(which does not modify package.json
)knit add
and don't want to worry about changing the file:
/link:
dependencies
knit check
in a precommit hook, e.g. with Husky, which checks package.json
for Knit dependencies and exits with an error if it finds anyReasons to commit:
knit
files within the projects you are working on and treat it as a part of the project's codebase
If you decide to commit, consider that standard non-code files like README.md
and LICENSE.md
will also be included, so you may want to exclude them in .gitignore
with a pattern such as **/.knit/**/*.md
. Alternatively, use .knitignore
to avoid including those files in package content.
Useful for monorepos, knit publish $PROJECT_NAME
will perform the publish operation in the ./$PROJECT_NAME
directory relative to process.cwd()
.
Instead of completely removing a package, it can be temporary set back with knit retreat [--all]
(e.g. before package publication to a remote registry).
Later, it can be restored with knit restore
.
npm
/yarn
/pnpm
Workspaces--pure
will be used by default if you try to add
a project in a workspaces
-enabled package, so package.json
and node_modules
will not be modified. Then, you can add the Knit-enabled package folder to workspaces
in package.json
(e.g. add .knit/*
and .knit/@*/*
patterns). During the update
(or push
) operation, package content will be updated automatically and your package manager will handle the rest.
If you want to override the default pure behavior, use --no-pure
.
While working with knit
, you might face a situation when you have locations where Knit-enabled projects have been removed from the filesystem, which will cause warnings when knit
tries to push a package to the missing location. To get rid of these warnings, use knit installations clean $PACKAGE_NAME
.
Use --store-folder
to override the default location for storing published packages.
Use --quiet
to fully disable output, except for errors. Use --no-colors
to disable colors.
.knitrc
A .knitrc
file can be created to declaratively set default options for Knit.
Valid options:
sig
: control hash signatures for package versionsworkspace-resolve
: control workspace:
protocol resolutiondev-mod
: control removal of devDependencies
from package contentscripts
: control lifecycle scriptsquiet
: control console outputfiles
: control display of included files in published packagesExample:
workspace-resolve=false
sig=false
The code in this repository is licensed under MIT, © Brian Cooper. The original yalc work is licensed under MIT, © Alex Osh. See LICENSE.md for more information.