npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tinyrack/devsync

v1.13.3

Published

A personal CLI tool for git-backed configuration sync.

Readme

devsync

devsync is a cross-platform CLI for managing the configuration files in your home directory with git and syncing them across multiple devices.

Instead of treating the repository as the source of truth, devsync treats your actual local config as the truth. You choose files and directories under HOME, devsync mirrors them into a git-backed sync repository, and later restores that repository onto another device when you need it.

1. Purpose and how it differs

Most dotfiles tools start from the repository and ask you to shape your local system around it.

devsync takes the opposite approach:

  • Your real config under HOME is the source of truth.
  • The git repository is a sync artifact, not the primary authoring location.
  • push captures your current local state into the repository.
  • pull applies the repository back onto another device.

That makes devsync a good fit when you want to:

  • manage existing dotfiles and app configs without reorganizing your home directory,
  • keep profile-specific config workflows intact,
  • sync plain files and encrypted secrets together,
  • use normal git remotes as the transport layer between PCs,
  • handle platform-specific paths across Windows, macOS, and Linux.

Core capabilities:

  • track files and directories under your home directory,
  • store synced artifacts in ~/.config/devsync/sync,
  • mark paths as normal, secret, or ignore,
  • encrypt secret artifacts with age,
  • assign entries to profiles so different machines sync different subsets,
  • support platform-specific local paths per entry,
  • preview both directions with status, push --dry-run, and pull --dry-run.

2. Installation

Requirements:

  • Node.js 25.5+
  • npm
  • git

Install globally:

npm install -g @tinyrack/devsync
devsync --help

Run without installing globally:

npx @tinyrack/devsync --help

Run from this checkout:

npm install
npm run start -- --help

The published package name is @tinyrack/devsync, and the installed command is devsync.

Single executable builds with Node SEA

This repository also supports a local-platform single executable build through Node SEA.

Requirements for SEA builds:

  • Node.js 25.5+
  • the build must run on the same platform you want to execute initially

Build the executable:

npm run sea:build
./dist/sea/devsync --version

Run the dedicated smoke test:

npm run sea:smoke

Notes:

  • The SEA output is written to dist/sea/devsync on Unix-like systems and dist/sea/devsync.exe on Windows.
  • npm run sea:bundle creates only the single-file bundled entry that feeds SEA generation.
  • The initial SEA workflow is local-platform only. Cross-platform release generation and code signing are separate concerns.

3. Quickstart

Initialize a local sync repository:

devsync init

Provide an existing age private key during setup:

devsync init --key AGE-SECRET-KEY-...

Track a few configs:

devsync track ~/.gitconfig
devsync track ~/.zshrc
devsync track ~/.config/mytool --mode secret

Review what would be captured:

devsync status
devsync push --dry-run

Write your current local config into the sync repository:

devsync push

Open the sync repository and publish it with git:

devsync cd
# inside the spawned shell
git add .
git commit -m "Update synced config"
git push
exit

On another device, clone and restore from the same repo:

devsync init https://example.com/my-sync-repo.git
devsync status
devsync pull --dry-run
devsync pull

Notes:

  • push updates the sync repository contents only; it does not create git commits or push to a remote.
  • pull updates local files only.
  • Secret paths are stored encrypted in the repository and require the configured age identity to decrypt on restore.
  • init prompts for an age private key when --key is omitted. Submit an empty response to generate a new identity automatically.
  • Long-running commands such as init, status, push, pull, and multi-target track now stream progress to stderr while keeping the final summary on stdout.
  • Use --verbose to show more detailed per-entry and per-file progress output.

Shell autocomplete

Load autocomplete into the current shell session with eval:

eval "$(devsync autocomplete bash)"
eval "$(devsync autocomplete zsh)"

To enable autocomplete automatically for future shells, add the matching eval line to your shell startup file such as ~/.bashrc or ~/.zshrc.

4. Detailed docs

How tracking works

  • You track files or directories that live under your home directory.
  • devsync mirrors them into ~/.config/devsync/sync/default/<repoPath> for the default profile, or ~/.config/devsync/sync/<profile>/<repoPath> for a named profile.
  • Plain artifacts are stored as-is.
  • Secret artifacts are stored with the .devsync.secret suffix.

Storage layout:

  • Sync repo: ~/.config/devsync/sync
  • Default profile artifacts: ~/.config/devsync/sync/default/<repoPath>
  • Named profile artifacts: ~/.config/devsync/sync/<profile>/<repoPath>
  • Default age identity: $XDG_CONFIG_HOME/devsync/age/keys.txt

Sync modes

Each tracked path can use one of three modes:

  • normal: store and restore plain content
  • secret: encrypt before storing in the repo
  • ignore: skip during push and pull

Set modes when tracking, or update them later:

devsync track ~/.config/mytool --mode secret
devsync track ~/.config/mytool/cache --mode ignore
devsync track ~/.config/mytool/public.json --mode normal

Child entries inside a tracked directory inherit the parent mode unless explicitly overridden.

Profiles

Profiles let you sync different subsets of entries on different machines. Each entry can be assigned to one or more profiles. When a profile is active, only entries assigned to that profile (plus entries with no profile restriction) are synced.

devsync track ~/.ssh/config --mode secret --profile work
devsync track ~/.gitconfig --profile work --profile personal
devsync track ~/.zshrc
devsync profile use work
devsync profile list

Key behaviors:

  • Entries without --profile are synced on all profiles (including when no profile is active).
  • Entries with --profile are only synced when one of the listed profiles is active.
  • Pass --profile '' to clear profile restrictions from an entry.
  • The default profile namespace is reserved for entries with no profile restriction.
  • Commands like push, pull, and status accept --profile to override the active profile for a single operation.

Platform-specific paths

Entries can specify different local paths per platform, so the same sync config works across Windows, macOS, Linux, and WSL:

Example manifest.json:

{
  "version": 7,
  "age": {
    "identityFile": "$XDG_CONFIG_HOME/devsync/age/keys.txt",
    "recipients": ["age1example..."]
  },
  "entries": [
    {
      "kind": "file",
      "localPath": {
        "default": "~/.gitconfig",
        "win": "%USERPROFILE%/.gitconfig"
      },
      "mode": {
        "default": "normal"
      }
    },
    {
      "kind": "directory",
      "localPath": {
        "default": "~/.config/mytool",
        "win": "%APPDATA%/mytool"
      },
      "mode": {
        "default": "normal",
        "win": "ignore"
      },
      "profiles": ["work"]
    },
    {
      "kind": "file",
      "localPath": {
        "default": "~/.config/mytool/token.json"
      },
      "mode": {
        "default": "secret"
      },
      "profiles": ["work"]
    }
  ]
}

The localPath object supports default, win, mac, linux, and wsl keys. The default key is required. On WSL, wsl is used first, then linux, then default. The mode object uses the same shape. mode.default is required, OS-specific keys are optional, and on WSL the fallback order is wsl -> linux -> default. An explicit child mode replaces the parent's full mode policy instead of merging platform overrides.

Common workflow

Check what changed:

devsync status

Capture local config into the repository:

devsync push

Restore repository state locally:

devsync pull

Use dry runs when you want to review first:

devsync push --dry-run
devsync pull --dry-run

Override the active profile for a single operation:

devsync push --profile work
devsync pull --profile personal
devsync status --profile work

Command reference

init

Create or connect the local sync repository.

devsync init
devsync init https://example.com/my-sync-repo.git
devsync init --identity "$XDG_CONFIG_HOME/devsync/age/keys.txt" --recipient age1...

track

Track a file or directory under your home directory.

devsync track ~/.gitconfig
devsync track ~/.gitconfig ~/.zshrc ~/.config/nvim
devsync track ~/.ssh/config --mode secret
devsync track ~/.ssh/config --mode secret --profile work
devsync track ~/.config/mytool/cache --mode ignore

If the target is already tracked, its mode is updated. Targets may also be repository paths inside a tracked directory to create child entries with a specific mode.

untrack

Remove a tracked entry from the sync config.

devsync untrack ~/.gitconfig
devsync untrack ~/.config/mytool
devsync untrack .config/mytool/token.json

This only updates the sync config; actual file changes happen on the next push or pull.

status

Preview planned push and pull changes.

devsync status
devsync status --profile work

doctor

Validate repo state, config, tracked paths, and secret setup.

devsync doctor

push

Write local state into the sync repository.

devsync push
devsync push --dry-run
devsync push --profile work

pull

Apply repository state back onto local paths.

devsync pull
devsync pull --dry-run
devsync pull --profile work

profile list

Show configured profiles and which one is active.

devsync profile list

profile use

Set or clear the active sync profile.

devsync profile use work
devsync profile use

Omit the profile name to clear the active profile.

cd

Launch a shell in the sync repository directory.

devsync cd

devsync cd opens a child shell rooted at the sync repository directory. Exit that shell to return to your original session.

For flag-level details, use built-in help:

devsync --help
devsync init --help
devsync track --help

Development

Run the CLI locally:

npm run start -- --help

Watch mode:

npm run dev

Validation:

npm run typecheck
biome check .
npm run test

Or run everything at once:

npm run check

Release

  • CI runs npm run check on every push and pull request.
  • npm publishing runs automatically for Git tags matching v*.*.*.
  • The release workflow expects the pushed tag to match package.json version.

Typical release flow:

npm version patch
git push --follow-tags