{"id":28921825,"url":"https://github.com/playcanvas/playcanvas-sync","last_synced_at":"2026-02-10T15:22:08.633Z","repository":{"id":37212084,"uuid":"261911590","full_name":"playcanvas/playcanvas-sync","owner":"playcanvas","description":"Real-time synchronization of files between PlayCanvas and your local machine","archived":false,"fork":false,"pushed_at":"2025-05-18T21:31:42.000Z","size":1362,"stargazers_count":77,"open_issues_count":14,"forks_count":20,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-06-19T03:18:15.690Z","etag":null,"topics":["game-development","javascript","nodejs","playcanvas","typescript"],"latest_commit_sha":null,"homepage":"https://playcanvas.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/playcanvas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-05-07T00:34:13.000Z","updated_at":"2025-05-18T21:31:46.000Z","dependencies_parsed_at":"2023-10-31T11:30:17.321Z","dependency_job_id":null,"html_url":"https://github.com/playcanvas/playcanvas-sync","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/playcanvas/playcanvas-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playcanvas%2Fplaycanvas-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playcanvas%2Fplaycanvas-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playcanvas%2Fplaycanvas-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playcanvas%2Fplaycanvas-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/playcanvas","download_url":"https://codeload.github.com/playcanvas/playcanvas-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playcanvas%2Fplaycanvas-sync/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261250335,"owners_count":23130544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-development","javascript","nodejs","playcanvas","typescript"],"created_at":"2025-06-22T07:08:23.979Z","updated_at":"2026-02-10T15:22:08.627Z","avatar_url":"https://github.com/playcanvas.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Overview\n\nThe `pcsync` and `pcwatch` utilities allow editing copies of JavaScript and other textual files of a PlayCanvas project locally on your own computer, in a text editor of your choice.\n\n`pcsync` also allows pushing and pulling of [binary files](#using-pcsync-for-binary-files), such as images and models.\n\nIn addition, if your project has a file called [`pcignore.txt`](#the-pcignoretxt-file), PlayCanvas merge will not affect the files listed in it, and the operation of `pcsync` and `pcwatch` will be restricted only to those files.\n\n`pcsync` is used to push or pull one or all files to or from PlayCanvas (overwriting existing files with the same name/path) and to compare one or all local files to their remote (PlayCanvas) versions.\n\n`pcwatch` detects changes to local files and folders (edits, removals and creation) as they happen and applies them to PlayCanvas in real time.\n\nIf you do not need your local changes pushed to PlayCanvas \"as you type\", you do not have to use `pcwatch`. Running `pcsync pushAll` periodically can be sufficient.\n\nOnly the `pcsync pull` and `pcsync pullAll` commands can change local files. Other `pcsync` commands and `pcwatch` change only remote files. Thus your local directory holds the authoritative version of your textual files.\n\nThe only scenario we do not support is when developer A uses `pcwatch`, while developer B is editing files of the *same PlayCanvas branch* in the browser code editor. B's work will be overwritten by A, if they edit the same file. Either B should start using local files, or A should stop `pcwatch` and switch to the browser code editor.\n\n# The `pcsync` Utility\n\n`pcsync` has the following commands:\n\n```\n  diffAll                     compare all local and remote files and folders\n  diff \u003cfilePath\u003e             show line-by-line diff of the remote and local files at filePath\n  pullAll                     download all remote files, overwriting their local counterparts\n  pushAll                     upload all local files, overwriting their remote counterparts\n  pull \u003cfilePath\u003e             download remote file, creating local folders if needed\n  push \u003cfilePath\u003e             upload local file, creating remote folders if needed\n  rename \u003coldPath\u003e \u003cnewPath\u003e  rename remote file or folder, change its parent folder if needed\n  rm \u003cfilePath\u003e               remove remote file or folder\n  parseIgnore                 list assets matched by pcignore.txt\n```\n\nA local directory [designated](#config-variables) as `PLAYCANVAS_TARGET_DIR` corresponds to the root of the PlayCanvas file and folder asset hierarchy.\n\nAll file and folder paths passed to `pcsync` as arguments should be relative to this root and use forward slashes even on Windows, e.g.\n\n```\npcsync rename dir1/file1.js file1.js\n```\n\nwill move `file1.js` to the root asset directory.\n\n`pushAll` and `pullAll` accept an optional `-y` or `--yes` flag to automatically answer \"yes\" to confirmation prompts.\n\n# The `pcwatch` Utility\n\n`pcwatch` does not need any options.\n\nMoving or renaming a file or a folder will appear to `pcwatch` as a `remove + create`. In such cases it may be better to stop `pcwatch`, perform the operation locally, apply it to PlayCanvas with `pcsync rename`, and start `pcwatch` again.\n\n# Adding New Files as Script Components\n\nAssume file F was created locally and pushed to PlayCanvas with `pcsync` or `pcwatch`, and now you are adding F as a script component to an entity in PlayCanvas Editor.\n\nNote that it will take a second or two for F to appear in the dropdown list, because F is parsed by the editor for the first time when that list is populated.\n\n# The `pcignore.txt` File\n\nIf your project has a file called `pcignore.txt` in the root folder, any file listed there will be the same before and after a PlayCanvas merge.\n\nThe operation of `pcsync` and `pcwatch` is restricted to the files listed in `pcignore.txt`, if `pcignore.txt` exists. This ensures that the set of files managed locally exactly matches the set ignored by PlayCanvas merge, which is appropriate for most workflows.\n\nTo make `pcsync` and `pcwatch` work with more files than listed in `pcignore.txt`, use the `PLAYCANVAS_INCLUDE_REG` config variable, which is a regular expression to test each file's path from the root of the asset hierarchy.\n\nBefore a PlayCanvas merge, make sure that the latest checkpoint of the destination branch is taken after `pcignore.txt` was added.\n\nIf you are using git for your textual files, you can perform a git merge before a PlayCanvas merge of the corresponding branches, push the result to the PlayCanvas destination branch, and then perform a PlayCanvas merge.\n\n## `pcignore.txt` Syntax\n\n`pcignore.txt` consists of one or more lines, each of which is either a path (with the same syntax as .gitignore), or one of the following:\n\n```\nignore_all_textual_files\nignore_all_js_files\nignore_all_files_with_extension \u003cextension1,extension2,...\u003e\nignore_regexp \u003cregexp string\u003e\nsource_branch_wins\n```\n\n`ignore_all_textual_files` is the most common choice.\n\n`source_branch_wins` (included once anywhere) changes the PlayCanvas merge behavior: instead of keeping items matching `pcignore.txt` as is (in the destination branch), the merge result will now include the versions of the corresponding items (if present) from the source branch.\n\nMultiple `ignore_regexp` lines can be provided. Any textual asset whose path from the root of the asset hierarchy matches an `ignore_regexp` expression will be ignored.\n\nTo check your `pcignore.txt` syntax, you can run `pcsync parseIgnore`. It will list all existing files that match your current `pcignore.txt`.\n\nUse a space and not * or ? to match a space in a file or folder name in gitignore lines.\n\n# Using `pcsync` for Binary Files\n\nBinary files include assets such as textures (JPG and PNG) and models (GLB).\n\n`push`, `pull` (single file) and `rm` work with binary file arguments without any special options.\n\n`pushAll`, `pullAll` and `diffAll` have two options that make them work with matching files only, including binary (without one of these options `pcsync` only works with textual files):\n\n```\n  -e, --ext \u003cextensions\u003e  handle files with provided extensions\n  -r, --regexp \u003cregexp\u003e   handle files matching the provided regular expression\n```\n\nFor instance:\n\n```\npcsync diffAll -e jpeg,png\npcsync pushAll -r \"\\\\.(png|jpeg)\"\n```\n\nThe regular expression tests each file's path from the root.\n\n# Installation\n\nRequires Node.js \u003e= 20. We recommend using [nvm](https://github.com/nvm-sh/nvm) to manage Node versions.\n\nInstall globally from npm:\n\n```\nnpm install -g playcanvas-sync\n```\n\nThis makes the `pcsync` and `pcwatch` commands available system-wide.\n\nTo uninstall:\n\n```\nnpm uninstall -g playcanvas-sync\n```\n\n# Config Variables\n\nConfig variables can be set in a file called `.pcconfig` in your home directory, in `pcconfig.json` in your target directory (and your remote PlayCanvas branch), or provided as environment variables (which would have the highest precedence).\n\nThe home directory location is:\n\n* Windows: `C:\\Users\\\u003cusername\u003e`\n* Mac/Linux: `/Users/\u003cusername\u003e` or `/home/\u003cusername\u003e`\n\n## Getting Your API Key\n\nGet your PlayCanvas API key (token) from your PlayCanvas account page (playcanvas.com/\u0026lt;username\u0026gt;/account). See the [User Manual](https://developer.playcanvas.com/user-manual/api/#authorization) for detailed instructions.\n\n## Getting Your Branch and Project IDs\n\nFrom the Chrome Developer Tools console (on the PlayCanvas Editor page) run:\n\n```\ncopy({\n  PLAYCANVAS_BRANCH_ID: config.self.branch.id,\n  PLAYCANVAS_PROJECT_ID: config.project.id\n})\n```\n\nThis will copy your branch and project id to the clipboard.\n\n![](https://raw.githubusercontent.com/playcanvas/playcanvas-sync/main/docs/images/branch-id-project-id-clipboard.gif)\n\nAlternatively, you can get your branch id from the Version Control Panel of the PlayCanvas Editor, and your project id from its home page url, e.g. for `playcanvas.com/project/10/overview/test_proj` the id is 10. See the [User Manual](https://developer.playcanvas.com/user-manual/api/#parameters) for more details.\n\n## Sample Config File\n\nCreate a directory for the local versions of your PlayCanvas files, e.g. `proj1`. Add its full path to `.pcconfig` in your home directory, along with your API key and the branch/project IDs.\n\nA sample `.pcconfig` should look like this:\n\n```\n{\n  \"PLAYCANVAS_BRANCH_ID\": \"abc\",\n  \"PLAYCANVAS_PROJECT_ID\": 10,\n  \"PLAYCANVAS_TARGET_DIR\": \"/Users/zpaul/proj1\",\n  \"PLAYCANVAS_API_KEY\": \"xyz\",\n  \"PLAYCANVAS_BAD_FILE_REG\": \"^\\\\.|~$\",\n  \"PLAYCANVAS_BAD_FOLDER_REG\": \"\\\\.\",\n  \"PLAYCANVAS_CONVERT_TO_POW2\": 0\n}\n```\n\nAll listed key-value pairs are necessary. You can split them between `.pcconfig` (in your home directory), `pcconfig.json` (in your project target directory), and environment variables.\n\n`PLAYCANVAS_TARGET_DIR` can only be set in `.pcconfig` or an environment variable. You can also set `PLAYCANVAS_USE_CWD_AS_TARGET` to `1` in `.pcconfig` to use your current working directory as your target.\n\nFor some workflows, it may be necessary to keep the `pcconfig.json` file at the top level in the target directory, but treat one of its subdirectories as the root of the local file hierarchy. In such cases `PLAYCANVAS_TARGET_SUBDIR` needs to be provided, e.g.\n\n```\n\"PLAYCANVAS_TARGET_SUBDIR\": \"src\"\n```\n\nBackslash characters should be written as `\\\\` (escaped).\n\n# Files and Folders to Exclude\n\nMany text editors and operating systems create local auxiliary files and directories that do not need to be automatically pushed to PlayCanvas.\n\n`PLAYCANVAS_BAD_FILE_REG` and `PLAYCANVAS_BAD_FOLDER_REG` contain RegExp strings (note the escapes) that tell `pcwatch` which files and directories to ignore. In our sample `.pcconfig`, a bad file has a name that starts with a dot or ends with `~`. A bad folder is one that has a dot anywhere in its path relative to `PLAYCANVAS_TARGET_DIR`. The expressions provided are sufficient in most cases, and you can simply copy them into your `.pcconfig`.\n\nTo determine which auxiliary files and folders your OS and text editor create, run `pcwatch` with config/environment variables `PLAYCANVAS_DRY_RUN` and `PLAYCANVAS_VERBOSE` set to `1`, and create/edit some files.\n\n`pcwatch` output will show all file system events as they happen, and which of them will be filtered out by your current `PLAYCANVAS_BAD_FILE_REG` and `PLAYCANVAS_BAD_FOLDER_REG`.\n\nIf in your case no bad files and folders exist, use a string like `\"matchNothing\"` as the value of `PLAYCANVAS_BAD_FILE_REG` and/or `PLAYCANVAS_BAD_FOLDER_REG`.\n\n# Troubleshooting\n\nProblems are often caused by setting config variables incorrectly. Execute your command with the config/environment variable `PLAYCANVAS_VERBOSE` set to `1` to print the current values of all config variables and other useful data.\n\n# Sample Workflows\n\n## Case 1: Single user per PlayCanvas branch, without `git`\n\n* Run `pcsync pullAll` to download existing textual files from PlayCanvas\n* Launch `pcwatch`\n* Start editing/creating files locally in your own text editor\n\nTo merge changes from another PlayCanvas branch into your branch without `git`:\n\n* Stop `pcwatch`\n* Run `pcsync diffAll`, and, if necessary, `pcsync push/pushAll` to make sure the PlayCanvas version is up-to-date.\n* Perform merge in PlayCanvas\n* Use `pcsync pullAll` to download the merge result\n\n## Case 2: Single user per PlayCanvas branch, with `git`\n\n* Create your own PlayCanvas branch of your team's project\n* Create a git branch for your work, and make it your local target directory\n* Create a [`pcignore.txt`](#the-pcignoretxt-file) file, listing all files you intend to keep in git, create a PlayCanvas checkpoint that includes your `pcignore.txt`\n* Launch `pcwatch`\n* Start editing/creating files locally in your own text editor\n* When necessary, merge in `git` the branch of another group member into your branch\n* Use `pcsync pushAll` to update your remote branch after git merge\n* Merge the same branches in PlayCanvas\n* Use `pcsync diffAll` to verify that local and remote files are still in sync\n\n## Case 3: Multiple users working on the same PlayCanvas branch, with `git`\n\nMost items from Case 1 apply, also:\n\n* Periodically run `pcsync diffAll`. It is usually OK to see extra remote files (coming from other team members). If you notice that a remote file is different from your local file, consider a `git` merge to include your team member's changes into your `git` branch, resolve conflicts in `git`, if any, as usual.\n* Avoid `pcsync pull/pullAll`. To get others' files/changes into your branch, use `git` merge instead to maintain an accurate `git` history of edits to each file (who added what).\n\n# Using TypeScript\n\n## TypeScript Bindings\n\nYou can build TypeScript Bindings from the PlayCanvas engine repo (branch `stable`) as mentioned in the [instructions here](https://github.com/playcanvas/engine):\n\n```\nnpm run build:types\n```\n\nThis will generate the file `build/output/playcanvas.d.ts` in your engine folder.\n\n## TypeScript Workflow\n\nTypeScript source files are usually compiled into a single JavaScript file, which is then used in a PlayCanvas project.\n\nThis JavaScript file can be added to your [`pcignore.txt`](#the-pcignoretxt-file) to prevent PlayCanvas merge from reporting conflicts in it.\n\nIf you are storing your TypeScript source files in git, there is no need to include them in your PlayCanvas project.\n\n# Setting up Visual Studio Code for local editing on Mac\n\nCopy the file `playcanvas.d.ts` with [TypeScript bindings for the PlayCanvas engine](#typescript-bindings) to a folder called `typings` in your target directory.\n\nCreate a `jsconfig.json` file in your target directory with the following content:\n\n```\n{\n    \"compilerOptions\": {\n        \"target\": \"ES5\",\n        \"module\": \"commonjs\",\n        \"files\": [\n            \"typings/playcanvas.d.ts\"\n        ]\n    }\n}\n```\n\nYour folder structure should look like this:\n\n![](https://raw.githubusercontent.com/playcanvas/playcanvas-sync/main/docs/images/vscode-target-directory-file-structure.png)\n\nAdd `jsconfig.json` and `typings` to `PLAYCANVAS_BAD_FILE_REG` and `PLAYCANVAS_BAD_FOLDER_REG`, e.g.\n\n```\n\"PLAYCANVAS_BAD_FILE_REG\": \"^\\\\.|~$|jsconfig.json\",\n\"PLAYCANVAS_BAD_FOLDER_REG\": \"^\\\\.|typings\"\n```\n\nNow you are ready to start using `pcsync` and `pcwatch` to sync your PlayCanvas project and edit with VS Code goodness 🚀\n\n![](https://raw.githubusercontent.com/playcanvas/playcanvas-sync/main/docs/images/vs-code-demo.gif)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaycanvas%2Fplaycanvas-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplaycanvas%2Fplaycanvas-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaycanvas%2Fplaycanvas-sync/lists"}