CLI tool
imsnif/synp avatar
imsnif/synp

synp: converting between yarn.lock and package-lock.json without losing the tree

Convert yarn.lock to package-lock.json and vice versa

788 stars42 forksJavaScriptMIT

At a glance

What is it?
synp is a JavaScript command line tool that converts a yarn lockfile into a package-lock.json and back again, working from the node_modules directory on disk because the two formats do not carry the same information. It is MIT licensed, and the documentation is candid that bundled dependencies are its weak point.
Who is it for?
synp fits a team moving between npm and yarn that needs to hand over a lockfile to people who use the other tool, and that can install dependencies first so the tree on disk is authoritative. It does not fit a team that wants a pure file to file conversion with no install step, because that is exactly what the two lockfile formats cannot support.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem the tool actually solves

synp converts yarn.lock to package-lock.json and vice versa, and the reason it needs more than a file parser is explained in its own documentation.

The two lockfiles use different methods to deterministically lock down dependency versions, and oftentimes they do not contain all the information needed to be purely converted. A yarn lockfile records resolved versions and integrity hashes, and an npm lockfile records a dependency tree with nesting, and the mapping between them is not one to one.

So synp uses the existing node_modules directory of the package to determine the package state and assist in the conversion. That is the whole design in one sentence, and it is why the tool insists on a current install.

The consequence for the reader is that this is not a lockfile translator in the abstract. It is a tool that reads what is actually installed on your disk and writes a lockfile that describes it. For the use case it was built for, which is handing a repository to a colleague who uses the other package manager, that is exactly right.

The project is MIT licensed, written in JavaScript, and the last push to the repository was on 2026-10-18. The last tagged release is v1.9.14 from November 2024, after v1.9.13 and v1.9.12 in April 2024.

Command line and programmatic use

Installation is a global npm install:

bash
npm install -g synp

Converting from yarn.lock means making sure the node_modules folder exists and is up to date first, and then pointing the tool at the source file:

bash
yarn # be sure the node_modules folder dir and is updated
synp --source-file /path/to/yarn.lock
# will create /path/to/package-lock.json

The other direction is the same shape with the tools swapped:

bash
npm install # be sure the node_modules dir exists and is updated
synp --source-file /path/to/package-lock.json
# will create /path/to/yarn.lock

Note the comments in those examples. The install step is not a convenience, it is a requirement, because the node_modules tree is where the missing information comes from.

The library form exposes the same two conversions as functions:

javascript
const { npmToYarn, yarnToNpm } = require('synp')

const libPath = '/path/to/my/lib'
const stringifiedYarnLock = npmToYarn(libPath)
const stringifiedPackageLock = yarnToNpm(libPath)

Both take a directory path and return the lockfile as a string, which is the shape you want if you are writing a migration script rather than converting by hand.

The caveat about direction, and the one about bundled dependencies

There is a note in the documentation that saves you a step in one direction. If all you need is to convert from package-lock.json to yarn.lock, then as of version 1.7.0 Yarn is able to import its dependency tree from npm's package-lock.json natively, without external tools, using the yarn import command.

So the tool is worth reaching for in the direction Yarn does not cover, which is yarn.lock to package-lock.json, and the other direction is a convenience you can get from the package manager itself.

The documented caveat is bundled dependencies, and it is worth understanding why. A package that bundles its own dependencies has a node_modules layout that does not match what the lockfiles describe, and the tool does not play well with that case. The documentation argues this is not a practical problem, because installing the packages later with the converted file will by definition update the proper packages in the file, and asks for an issue with a use case if that does not hold.

That argument is reasonable for the common case and less so for a repository with vendored or bundled trees, where the converted lockfile may not describe the packages that are actually present. The second documented caveat, on package checksums, follows in the same section and is worth reading in full in the repository rather than from a summary.

The project is built with a Travis CI pipeline and a coveralls coverage badge, and follows the standard JavaScript style guide, which is the shape of a small, stable utility that has not needed a redesign in years.

What a lockfile conversion has to reconstruct

It is worth being precise about why a pure file conversion is not possible, because it explains the shape of the tool.

A yarn lockfile is essentially a flat list of resolved package versions with their integrity hashes, keyed by the range that requested them. An npm lockfile is a tree: it records which package was resolved at which version and where it sits in the dependency graph, including the nested copies that a conflict forced into a subdirectory.

Those two shapes encode different information. A yarn lockfile knows every version that exists in the resolution but not necessarily which parent pulled it in. An npm lockfile knows the placement but derives it from an install that has already happened. So a converter that only reads one file has to guess about the tree structure, and the guess is where a wrong conversion comes from.

Reading node_modules resolves that, because the installed tree is the tree. The converter does not need to reconstruct what npm would have done from the yarn lockfile alone, because the answer is on disk, and the yarn lockfile then supplies the hashes that node_modules does not have in a convenient form.

That is also why the tool is not a candidate for a continuous integration step that runs on a repository without an install step. The install is the input.

Who this is for, and who should look elsewhere

The use case the tool serves is narrow and real. A repository standardises on yarn, a contributor or a downstream team uses npm, and the project needs to hand over a package-lock.json that is not hand-written, because a hand-written one drifts from the yarn lockfile within a week and produces an install that resolves differently on two machines.

The reverse situation, a project standardised on npm that wants to try yarn, has a better answer already in Yarn itself, since version 1.7.0 the yarn import command reads package-lock.json natively. So synp earns its place in the direction Yarn does not cover.

It also earns a place in the scripted migration case, where a large monorepo has to move package managers and dozens of lockfiles have to be regenerated consistently, and the library form with npmToYarn and yarnToNpm is what makes that a loop rather than a manual task.

The cases where it does not fit are equally clear. A project with no node_modules and no intention of installing before converting is asking for something the formats cannot deliver. A project with a large number of bundled or vendored dependencies will get a conversion that does not describe what is installed, and the documentation's own caveat acknowledges that. And a project that has already standardised on one package manager and has no reason to change has no use for it at all.

For most teams, the honest assessment is that this is a tool for a specific week rather than a dependency to carry for the life of the project.

Editorial conclusion

synp fits a team moving between npm and yarn that needs to hand over a lockfile to people who use the other tool, and that can install dependencies first so the tree on disk is authoritative. It does not fit a team that wants a pure file to file conversion with no install step, because that is exactly what the two lockfile formats cannot support. Before using it, make sure node_modules is current and was installed by the tool you are converting from, and check whether your dependencies include anything bundled, since that is the documented case where the conversion is weakest.

Frequently asked questions

What does synp do and why does it need node_modules?

It converts yarn.lock to package-lock.json and back. The two lockfile formats use different methods to lock down dependency versions and oftentimes do not contain all the information needed for a pure conversion, so synp uses the existing node_modules directory to determine the actual package state.

How do I install and run synp from the command line?

Install it with `npm install -g synp`. For the yarn direction, run yarn first so node_modules is current, then `synp --source-file /path/to/yarn.lock` to produce a package-lock.json. For the other direction, run npm install first and then `synp --source-file /path/to/package-lock.json` to produce a yarn.lock.

Do I still need synp to convert package-lock.json into yarn.lock?

Probably not. The documentation notes that as of version 1.7.0 Yarn can import its dependency tree from npm's package-lock.json natively with the yarn import command, so no external tool is needed in that direction.

What is synp's weakness?

Bundled dependencies. The tool does not play well with them, because a package with its own bundled tree does not match what the lockfiles describe. The documentation argues it is not a practical problem since installing with the converted file updates the entries, and asks for an issue if that does not hold in your case.

Can synp be used as a library?

Yes. The package exports npmToYarn and yarnToNpm, each taking a directory path and returning the lockfile as a string, so a migration script can call them directly rather than shelling out to the command line.

Official sources

  1. imsnif/synp on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/imsnif-synp.svg)](https://hysenlabs.com/projects/imsnif-synp)

Was this useful?