{"id":13393080,"url":"https://github.com/schollz/croc","last_synced_at":"2026-10-18T21:10:25.797Z","repository":{"id":37334529,"uuid":"107286889","full_name":"schollz/croc","owner":"schollz","description":"Easily and securely send things from one computer to another :crocodile: :package:","archived":false,"fork":false,"pushed_at":"2026-10-14T16:47:07.000Z","size":12523,"stargazers_count":40595,"open_issues_count":7,"forks_count":1634,"subscribers_count":252,"default_branch":"main","last_synced_at":"2026-10-15T12:44:39.059Z","etag":null,"topics":["data-transfer","file-sharing","golang","pake","peer-to-peer","tcp","transfer"],"latest_commit_sha":null,"homepage":"https://getcroc.com","language":"Go","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/schollz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null},"funding":{"github":"schollz"}},"created_at":"2017-10-17T15:20:18.000Z","updated_at":"2026-10-15T11:40:27.000Z","dependencies_parsed_at":"2026-08-23T14:21:21.269Z","dependency_job_id":null,"html_url":"https://github.com/schollz/croc","commit_stats":{"total_commits":1554,"total_committers":91,"mean_commits":"17.076923076923077","dds":0.1576576576576577,"last_synced_commit":"23a89041934a3110c183cc2e3be382940985ec3b"},"previous_names":[],"tags_count":216,"template":false,"template_full_name":null,"purl":"pkg:github/schollz/croc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schollz%2Fcroc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schollz%2Fcroc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schollz%2Fcroc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schollz%2Fcroc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schollz","download_url":"https://codeload.github.com/schollz/croc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schollz%2Fcroc/sbom","scorecard":{"id":804236,"data":{"date":"2025-08-11","repo":{"name":"github.com/schollz/croc","commit":"fddb0e98ce19a0a93b322781a399fda6f38e9246"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Code-Review","score":1,"reason":"Found 3/20 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/deploy.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:9","Warn: no topLevel permission defined: .github/workflows/stale.yml:1","Warn: no topLevel permission defined: .github/workflows/winget.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/deploy.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:146: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:149: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:185: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:198: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:212: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/stale.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/stale.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/winget.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/schollz/croc/winget.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:11: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v10.2.4 not signed: https://api.github.com/repos/schollz/croc/releases/237142305","Warn: release artifact v10.2.2 not signed: https://api.github.com/repos/schollz/croc/releases/207997333","Warn: release artifact v10.2.1 not signed: https://api.github.com/repos/schollz/croc/releases/192803117","Warn: release artifact v10.2.0 not signed: https://api.github.com/repos/schollz/croc/releases/192798906","Warn: release artifact v10.2.4 does not have provenance: https://api.github.com/repos/schollz/croc/releases/237142305","Warn: release artifact v10.2.2 does not have provenance: https://api.github.com/repos/schollz/croc/releases/207997333","Warn: release artifact v10.2.1 does not have provenance: https://api.github.com/repos/schollz/croc/releases/192803117","Warn: release artifact v10.2.0 does not have provenance: https://api.github.com/repos/schollz/croc/releases/192798906"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/deploy.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}}]},"last_synced_at":"2025-08-23T11:20:24.292Z","repository_id":37334529,"created_at":"2025-08-23T11:20:24.292Z","updated_at":"2025-08-23T11:20:24.292Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38341851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-18T02:00:06.448Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["data-transfer","file-sharing","golang","pake","peer-to-peer","tcp","transfer"],"created_at":"2024-07-30T17:00:42.489Z","updated_at":"2026-10-18T21:10:25.790Z","avatar_url":"https://github.com/schollz.png","language":"Go","funding_links":["https://github.com/sponsors/schollz"],"categories":["Go","Popular","HarmonyOS","Software Packages","开源类库","Misc","File Sharing and Synchronization","File Management and Sharing","Applications","Uncategorized","CLI","golang","Open source library","Productivity Tools","Go (531)","Tools","CLI 项目","Projects","Other Software","Other","软件包","Programming Languages","File transfer ![](https://img.shields.io/badge/_-FILES-0ea5e9?style=flat-square)","Files and Directories","\u003ca name=\"transfer\"\u003e\u003c/a\u003eData transfer","Linux生态圈用户工具","Go 工具","File Sharing","Go Tools","工具集","CLI Applications","🔧 Utilities \u0026 Miscellaneous","File Transfer","File Transfer \u0026 Sync"],"sub_categories":["Windows Manager","Other Software","网络","Snippets Manager","OS Encryption","Sharing Files","Uncategorized","The Internet","File Transfer","Go","Data Storage and Sharing","General Purpose Libraries","其他软件","Privacy front-ends and search","File Sync/Sharing","其他软件库和软件包","Security","小工具集"],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://getcroc.com\"\u003e\u003cimg src=\"web/src/assets/croc.jpg\" width=\"408px\" border=\"0\" alt=\"croc\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/schollz/croc/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/schollz/croc\" alt=\"Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/schollz/croc/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/schollz/croc/actions/workflows/ci.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sponsors/schollz\"\u003e\u003cimg alt=\"GitHub Sponsors\" src=\"https://img.shields.io/github/sponsors/schollz\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eThis project’s future depends on community support. \u003ca href=\"https://github.com/sponsors/schollz\"\u003eBecome a sponsor today\u003c/a\u003e.\u003c/strong\u003e\n\u003c/p\u003e\n\n\n## About\n\n`croc` is a tool that allows any two computers to simply and securely transfer files and folders. AFAIK, _croc_ is the only CLI file-transfer tool that does **all** of the following:\n\n- Allows **any two computers** to transfer data (p2p with relay fallback)\n- Provides **end-to-end encryption** (using PAKE)\n- Enables easy **cross-platform** transfers (Windows, Linux, Mac, [Browser](https://getcroc.com))\n- Allows **multiple file** transfers\n- Allows **resuming transfers** that are interrupted\n- No need for local server or port-forwarding\n- **IPv6-first** with IPv4 fallback\n- Can **use a proxy**, like Tor\n\nFor more information about `croc`, see [my blog post](https://schollz.com/tinker/croc6/) or read a [recent interview I did](https://console.substack.com/p/console-91).\n\n![Example](src/install/customization.gif)\n\n## No-install\n\nYou can use croc without installing anything at [getcroc.com](https://getcroc.com).\n\nThe browser version is fully compatible with the CLI, so you can send and receive files between them.\n\n## Install\n\nYou can download [the latest release for your system](https://github.com/schollz/croc/releases/latest), or install a release from the command-line:\n\n```bash\ncurl https://getcroc.com | bash\n```\n\nWhen the CLI sends or receives a transfer, it checks for a newer croc release at\nmost once every 24 hours. The check runs in the background and any update notice\nis shown after the transfer finishes. Run `croc update --check` at any time to\ncheck explicitly. Installations made by the command above can use `croc update`\n(`croc upgrade` is an alias) to verify and install a stable release when the\nexecutable is user-writable; pass `--yes` to skip confirmation.\nPackage-managed and other installations are never overwritten; the command\nprints the appropriate upgrade guidance instead. Network and release-service\nfailures in background checks are ignored; `--quiet` suppresses the notice.\n\n### On macOS\n\nUsing [Homebrew](https://brew.sh/):\n\n```bash\nbrew install croc\n```\n\nUsing [MacPorts](https://www.macports.org/):\n\n```bash\nsudo port selfupdate\nsudo port install croc\n```\n\n### On Windows\n\nYou can install the latest release with [Scoop](https://scoop.sh/) or\n[Chocolatey](https://chocolatey.org/):\n\n```bash\nscoop install croc\n```\n\n```bash\nchoco install croc\n```\n\n### Using nix-env\n\nYou can install the latest release with [Nix](https://nixos.org/):\n\n```bash\nnix-env -i croc\n```\n\n### On NixOS\n\nYou can add this to your [configuration.nix](https://nixos.org/manual/nixos/stable/#ch-configuration):\n\n```nix\nenvironment.systemPackages = [\n  pkgs.croc\n];\n```\n\n### On Alpine Linux\n\nEnable the community repository for your Alpine release, then install:\n\n```bash\napk add croc\n```\n\nCheck the [Alpine package index](https://pkgs.alpinelinux.org/packages?name=croc)\nfor your branch's version. Stable branches can carry older releases; see the\n[distribution status](packaging/distributions/status.md) before selecting one.\n\n### On Debian and Ubuntu\n\nThe [pkg.haus archive](https://pkg.haus/) provides third-party Debian packages.\nFollow its repository setup and supported-release instructions before running:\n\n```bash\nsudo apt install croc\n```\n\nFor a release that includes upstream `.deb` downloads, download the file matching\n`dpkg --print-architecture` from the [release page](https://github.com/schollz/croc/releases).\nReplace `VERSION` and `ARCH` below with the downloaded filename:\n\n```bash\nsudo apt install ./croc_VERSION-1_ARCH.deb\n```\n\nThis downloaded-package method also applies to older Debian and Ubuntu releases\nthat do not provide croc in their configured repositories. It does not add an APT\nrepository; download a newer package to upgrade it.\n\n### On Fedora and openSUSE\n\nFor a release that includes upstream `.rpm` downloads, choose the file matching\n`rpm --eval '%{_arch}'` from the [release page](https://github.com/schollz/croc/releases).\nReplace `VERSION` and `ARCH` with the downloaded filename:\n\n```bash\nsudo dnf install ./croc-VERSION-1.ARCH.rpm\n# On openSUSE:\nsudo zypper install ./croc-VERSION-1.ARCH.rpm\n```\n\nThese downloads install the CLI, manual, license notices, and shell completions.\nThey require `ca-certificates` and start no background services. Upgrade them\nthrough the package manager; `croc update` leaves package-owned binaries intact.\nSee [Linux packaging](packaging/README.md) for architectures and verification.\n\n### On Arch Linux\n\nInstall with `pacman`:\n\n```bash\npacman -S croc\n```\n\n### On Termux\n\nInstall with `pkg`:\n\n```bash\npkg install croc\n```\n\n### On FreeBSD\n\nInstall with `pkg`:\n\n```bash\npkg install croc\n```\n\n### On Linux, macOS, and Windows via Conda\n\nYou can install from [conda-forge](https://github.com/conda-forge/croc-feedstock) globally with [`pixi`](https://pixi.sh/):\n\n```bash\npixi global install croc\n```\n\nOr install into a particular environment with [`conda`](https://docs.conda.io/projects/conda/):\n\n```bash\nconda install --channel conda-forge croc\n```\n\n### On Linux, macOS via Docker\n\nAdd the following one-liner function to your ~/.profile (works with any POSIX-compliant shell):\n\n```bash\ncroc() { [ $# -eq 0 ] \u0026\u0026 set -- \"\"; mkdir -p \"$HOME/.config/croc\"; docker run --rm -it --user \"$(id -u):$(id -g)\" -v \"$(pwd):/c\" -v \"$HOME/.config/croc:/.config/croc\" -w /c -e CROC_SECRET docker.io/schollz/croc \"$@\"; }\n```\n\nYou can also just paste it in the terminal for current session. On first run Docker will pull the image. `croc` via Docker will only work within the current directory and its subdirectories.\n\n### Build from Source\n\nIf you prefer, you can [install Go](https://go.dev/dl/) and build from source (requires Go 1.27+):\n\n```bash\ngo install github.com/schollz/croc/v11@latest\n```\n\n### On Android\n\nThere are F-Droid apps available:\n\n- [crocgui](https://f-droid.org/packages/com.github.howeyc.crocgui/) — original port (Go, basic UI)\n- [croc-app](https://f-droid.org/en/packages/com.dking.crocapp/) — native Kotlin/Jetpack Compose client with a modern, mobile-first interface\n- [FlCroc](https://github.com/576576/FlCroc) — cross-platform Flutter GUI (Android, Windows, Linux) that wraps the `croc` binary as its transfer core.\n\n### On Desktop\n\nCommunity made desktop apps:\n\n- [Croc GUI](https://github.com/interfluve-wav/croc-gui) — unofficial desktop GUI for macOS, Windows, and Linux that bundles the `croc` binary for drag-and-drop transfers, QR codes, LAN mode, and relay/proxy options.\n- [croc-desktop](https://github.com/SihanTeng/croc-desktop) — unofficial desktop GUI for Linux, macOS, and Windows (experimental iOS/Android) built with Wails v3; embeds croc in-process for send/receive, QR codes, history, logs, and optional relay hosting.\n- [Swamp Swap](https://github.com/Ferase/SwampSwap) — unofficial PyQt6 GUI desktop app for macOS, Windows, and Linux, requires installing `croc` on its own normally in order to use. Made to be compact and simple.\n\n## Usage\n\nTo send a file, simply do:\n\n```bash\n$ croc send [file(s)-or-folder]\nSending 'file-or-folder' (X MB)\nCode is: code-phrase\n```\n\nThen, to receive the file (or folder) on another computer, run:\n\n```bash\ncroc code-phrase\n```\n\nThe code phrase is used to establish password-authenticated key agreement ([PAKE](https://en.wikipedia.org/wiki/Password-authenticated_key_agreement)) which generates a secret key for the sender and recipient to use for end-to-end encryption.\n\n### Share a terminal with `croc ssh`\n\nOn Linux, macOS, FreeBSD, or OpenBSD, start a shared terminal with:\n\n```bash\ncroc ssh\n```\n\nThe host receives separate six-word invitations for read/write and read-only\nparticipants. On Unix, a participant keeps the invitation out of the process\nlist by joining with the command croc prints:\n\n```bash\nCROC_SECRET='six-word-invitation' croc ssh\n```\n\nEveryone sees one persistent terminal. Multiple read/write participants may\ntype; read-only participants receive the same output but their input is\ndiscarded. \n\nThis does not expose an SSH daemon or require an account, public IP, inbound\nport, or SSH key setup. The invitation authenticates an ephemeral Tailcat\nWireGuard path and pins an ephemeral SSH host key. Tailcat uses DERP when it\ncannot establish a direct path; if Tailcat itself is unavailable, the client\nreauthenticates and carries the pinned SSH stream over the ordinary croc relay.\nRemote commands, forwarding, and SFTP are disabled. Anyone who receives an\ninvitation has the role printed beside it until the host stops, so treat both\ninvitations as secrets. \n\nSee the\n[SSH sharing design and security guide](src/docs/SSH_SHARING.md) for protocol,\nreconnection, platform, relay, and threat-model details.\n\n### Customizations \u0026 Options\n\n#### Encrypted temporary storage\n\nWhen an immediate peer-to-peer transfer is inconvenient, `croc` can upload\nregular files as client-side encrypted ciphertext:\n\n```bash\ncroc store [file1] [file2]\ncroc store --downloads 3 --expiration 3d [file1] [file2]\ncroc store --url https://files.example.com [file1] [file2]\n```\n\nThe original `croc send --store` syntax remains supported, with\n`--store-downloads`, `--store-expiration`, and `--store-url` settings.\n\nThe command prints a browser link and a CLI token. The transfer expires after\nthe selected lifetime, measured from successful upload completion, or after\nits configured number of receivers download, authenticate, and verify every\nfile—whichever happens first. The lifetime defaults to one day and accepts\nwhole minutes (`m`), hours (`h`), days (`d`), or weeks (`w`). The download\nlimit defaults to one. Both values are subject to server policy. Run `croc`\nwith no arguments and paste the token at the prompt to receive it. For\nautomation, keep the token out of the process list:\n\n```bash\nCROC_STORE_TOKEN='croc-store-v1....' croc --out ./downloads\n```\n\nThe browser link has the form\n`https://host/s/id#v1.decryption-key`. The decryption key is after `#` because\nURL fragments are not included in HTTP requests, so the storage service gets\nthe opaque transfer ID but not the key. The full link is still a secret: anyone\nwho has it can decrypt the files and claim one of the allowed downloads.\n\nWhile a transfer remains available, its sender can delete it with the locally\nsaved revoke receipt:\n\n```bash\ncroc --revoke [transfer-id]\n```\n\nStored mode is opt-in and separate from croc's normal live relay transfers. A\nself-hosted service can be selected with `croc store --url` (or\n`croc send --store --store-url`) or `CROC_STORE_URL`.\nSee [the stored-transfer design and operator guide](src/docs/STORED_TRANSFERS.md)\nfor protocol, privacy, limits, and deployment details.\n\n#### Using `croc` on Linux or macOS\n\nOn Linux and macOS, the sending and receiving process is slightly different to avoid [leaking the secret via the process name](https://nvd.nist.gov/vuln/detail/CVE-2023-43621). You will need to run `croc` with the secret as an environment variable. For example, to receive with the secret `***`:\n\n```bash\nCROC_SECRET=*** croc\n```\n\nFor single-user systems, the default behavior can be permanently enabled by running:\n\n```bash\ncroc --classic\n```\n\n#### Custom Code Phrase\n\nYou can send with your own code phrase (must be at least 6 characters):\n\n```bash\ncroc send --code [code-phrase] [file(s)-or-folder]\n```\n\nFor default public transfers, SHA-256 of the exact code modulo the ordered\nthree-relay pool determines which deployment both peers use. An automatically\ngenerated sender probes all three relays and generates a normal EFF code that\nmaps to the first healthy one to respond. A custom code maps directly without probing\nor fallback. `--relay`, `CROC_RELAY`, `--ip`, and local-only transfers bypass\nthis public routing rule. The generated sender caches the winning address in\n`best-relay` alongside croc's other configuration files, then reuses it without\nprobing. A relay connection failure removes the cache so the following send\nmeasures the pool again; deleting the file also forces a new measurement.\n\n#### Allow Overwriting Without Prompt\n\nTo automatically overwrite files without prompting, use the `--overwrite` flag:\n\n```bash\ncroc --yes --overwrite \u003ccode\u003e\n```\n\n#### Keep Both Files Without Prompt\n\nTo keep an existing file and receive the incoming one under a new name (e.g. `video (1).mkv`), use the `--rename` flag:\n\n```bash\ncroc --yes --rename \u003ccode\u003e\n```\n\n#### Excluding Folders\n\nTo exclude folders from being sent, use the `--exclude` flag with comma-delimited exclusions. This does a case-insensitive **substring** match against each file's relative path, so any path containing one of the given strings anywhere is excluded:\n\n```bash\ncroc send --exclude \"node_modules,.venv\" [folder]\n```\n\nIf you need to exclude one specific file rather than every path containing a substring (for example, two files share a name at different depths and only one should be excluded), use `--exclude-file` instead. It takes comma-delimited relative paths and matches them **exactly**:\n\n```bash\ncroc send --exclude-file \"subfolder/image.jpg\" [folder]\n```\n\n#### Use Pipes - stdin and stdout\n\nYou can pipe to `croc`:\n\n```bash\ncat [filename] | croc send\n```\n\nTo receive the file to `stdout`, you can use:\n\n```bash\ncroc --yes [code-phrase] \u003e out\n```\n\n#### Send Text\n\nTo send URLs or short text, use:\n\n```bash\ncroc send --text \"hello world\"\n```\n\n#### Send Multiple Files\n\nYou can send multiple files directly by listing the files and/or folders:\n\n```bash\ncroc send [file1] [file2] [file3] [folder1] [folder2]\n```\n\n#### Show QR Code\n\nTo show QR code (for mobile devices), use:\n\n```bash\ncroc send --qr [file(s)-or-folder]\n```\n\nThe QR code opens `https://getcroc.com/?code=...`, where the web client\nautomatically connects in receive-only mode.\n\n#### Use a Proxy\n\nYou can send files via a proxy by adding `--socks5`:\n\n```bash\ncroc --socks5 \"127.0.0.1:9050\" send SOMEFILE\n```\n\nRelay hostnames are resolved by the proxy, so the client does not need a\nworking DNS server to reach the relay. Bare `host:port`, `socks5://host:port`,\nand `socks5h://host:port` all use proxy-side relay DNS. Use an IP address for\nthe proxy itself when local DNS is unavailable. Set `--socks5` on both peers\n(or use the `SOCKS5_PROXY` environment variable).\n\nFor a network that only permits proxy traffic, use `--transport relay` on the\nsender to use the SOCKS5-capable relay transport for file data. The browser\nclient uses the browser's proxy settings for its WebSocket gateway connection;\nthe native CLI flag does not configure the browser.\n\n### Data transport selection\n\nThe native CLI defaults to `--transport auto`. After the normal three-word-code\nPAKE handshake, two compatible native clients create PAKE-bound Tailcat node\nidentities and open one or more TCP streams over an in-process Tailscale\nuserspace WireGuard network. Magicsock starts through DERP and promotes the\nconnection to a direct UDP path whenever NAT traversal succeeds. If the peer is\na browser, an older client, or Tailcat setup fails, both clients use croc's\nexisting relay data ports. The public spelling `--transport derp` is retained;\nin strict mode it requires Tailcat support and disables croc-relay fallback.\nPublic DERP is best effort and may apply fairness limits; see Tailscale's\n[DERP reference](https://tailscale.com/docs/reference/derp-servers) and\n[performance guidance](https://tailscale.com/docs/reference/troubleshooting/poor-performance-tailnet).\n\n\n#### Change Encryption Curve\n\nTo choose a different elliptic curve for encryption, use the `--curve` flag:\n\n```bash\ncroc --curve p521 \u003ccodephrase\u003e\n```\n\n#### Change Hash Algorithm\n\nFor faster hashing, use the `imohash` algorithm:\n\n```bash\ncroc send --hash imohash SOMEFILE\n```\n\n#### Clipboard Options\n\nBy default, the code phrase is copied to your clipboard. To disable this:\n\n```bash\ncroc --disable-clipboard send [filename]\n```\n\nTo copy the full command with the secret as an environment variable (useful on Linux/macOS):\n\n```bash\ncroc --extended-clipboard send [filename]\n```\n\nThis copies the full command like `CROC_SECRET=\"code-phrase\" croc` (including any relay/pass flags).\n\n#### Quiet Mode\n\nTo suppress all output (useful for scripts and automation):\n\n```bash\ncroc --quiet send [filename]\n```\n\n#### Self-host Relay\n\nYou can run your own relay:\n\n```bash\ncroc relay\n```\n\nBy default, it uses TCP ports 9009-9013. You can customize the ports (e.g., `croc relay --ports 1111,1112`), but at least **2** ports are required.\n\nEach relay port allows 64 incomplete handshakes in total and 32 per source IP.\nClients must send their first complete protocol message within 60 seconds and\nfinish the handshake within 5 minutes. Croc sends the first message automatically;\nthese deadlines do not limit how long an authenticated sender can wait for a\nreceiver or how long a transfer can run. Existing room and connection timeouts\nstill apply.\n\nUse `--max-pending-handshakes`, `--max-pending-handshakes-per-source`,\n`--first-message-timeout`, and `--handshake-timeout` to adjust these limits.\nTheir environment variables are `CROC_MAX_PENDING_HANDSHAKES`,\n`CROC_MAX_PENDING_HANDSHAKES_PER_SOURCE`, `CROC_FIRST_MESSAGE_TIMEOUT`, and\n`CROC_HANDSHAKE_TIMEOUT`. All values must be positive; the total limit and overall\ntimeout always bound the per-source allowance and first-message timeout.\n\nUsers behind the same NAT or proxy share a source allowance, including browser\nusers connecting through the same croc-web bridge. Raising the per-source limit\nto the total limit removes the protection against one source filling the pool.\nThese concurrent handshake limits are separate from the source and room join\nrate limits. Fast-admission tokens also use the bounded handshake pool; several\nsource IPs can still fill it.\n\nTo send files using your relay:\n\n```bash\ncroc --relay \"myrelay.example.com:9009\" send [filename]\n```\n\n#### Self-host Relay with Docker\n\nYou can also run a relay with Docker:\n\n```bash\ndocker run -d -p 9009-9013:9009-9013 -e CROC_PASS='YOURPASSWORD' docker.io/schollz/croc\n```\n\nTo send files using your custom relay:\n\n```bash\ncroc --pass YOURPASSWORD --relay \"myreal.example.com:9009\" send [filename]\n```\n\nTo use custom ports, set `CROC_PORTS` (comma-separated) or `CROC_PORT` (base port):\n\n```bash\ndocker run -d -p 9010-9011:9010-9011 -e CROC_PORTS='9010,9011' -e CROC_PASS='YOURPASSWORD' docker.io/schollz/croc\n```\n\n#### Web client\n\nThe React/Vite client in [`web/`](web/) can send and receive multiple files and\njoin `croc ssh` sessions hosted by normal CLI peers. The production client and its WebAssembly protocol\nruntime are bundled only in the standalone `croc-web` server, keeping generated\nassets and web-server code out of the cross-platform `croc` binary. Linux\namd64 builds of `croc-web` are published separately with each release. It\nserves both the site and its same-origin WebSocket relay:\n\n```bash\ncroc-web getcroc.com\n```\n\nThis binds to `127.0.0.1:9014` by default for an HTTPS reverse proxy. `/`\nserves the website and `/ws` bridges to the code-selected public relay at\n`1.getcroc.com`, `2.getcroc.com`, `3.getcroc.com`, or `4.getcroc.com`. For a directly\naccessible local development server, `croc-web localhost:5173` binds and\nserves on `localhost:5173`. Use `--bind`, `--relays`, and `--ports` before the\nwebsite address to customize the local listener or upstream croc relay.\n\nRun `make build-web` to generate the ignored production assets and build a\nlocal server. See [`web/README.md`](web/README.md) for frontend development,\ncustom relay, and reverse-proxy instructions.\n\n## Deployment\n\n### Disco\n\n[Disco](https://disco.cloud/) is used to deploy. The root [`Dockerfile`](Dockerfile) and [`disco.json`](disco.json) deploy the\n`croc-web` web client and `croc` TCP relay as two Disco services built from the\nsame image.\nDisco serves the website over HTTPS, while relay ports 9009-9017 are published\ndirectly as TCP ports.\n\nSet the deployment environment variables with:\n\n```bash\ndisco env:set \\\n  SITE_URL=yoururl.com \\\n  CROC_RELAY_PORTS=9009,9010,9011,9012,9013,9014,9015,9016,9017 \\\n  CROC_PASS=yourpass \\\n  --project croc\n```\n\n`SITE_URL` must be the public website hostname without `https://`. Change the\nproject name if it is not `croc`. The `web` service mounts the named\n`croc-store` volume at `/www/croc/storage`, which is also its configured\n`--store-dir`, so stored ciphertext and metadata survive container replacement\nand redeployment. The `web` service also reserves published TCP port 9020 and\nmaps it to unused container port 65535. This deliberate port collision makes\nDisco stop the previous volume-owning web service before starting its\nreplacement, avoiding concurrent access to the store. Port 9020 carries no\napplication traffic and should remain blocked by the server firewall.\n\nStored-upload policy can be set per deployment without editing `disco.json`:\n\n```bash\ndisco env:set \\\n  CROC_STORE_CREATE_RATE=60 \\\n  CROC_STORE_ACTIVE_UPLOADS=10 \\\n  CROC_STORE_UPLOAD_TIMEOUT=5m \\\n  CROC_STORE_TRUSTED_PROXY=VERIFIED_PROXY_IP/32 \\\n  --project croc --disco YOUR_DISCO_HOST\n```\n\nReplace the proxy placeholder with the socket source address seen by croc.\nWith Docker Swarm routing, this can be the `lb-disco-main` endpoint shown by\n`docker network inspect disco-main`, rather than Caddy's container address.\nVerify the source on each instance and again after Docker network changes.\nCaddy's normal forwarding configuration supplies `X-Forwarded-For`; verify\nthat different external clients remain distinct and that a forged incoming\nheader cannot choose their accounting IP. Do not edit Disco-generated Caddy\nconfiguration or trust an entire private network to work around a mismatch.\n\nThe values above are deployment overrides; croc's defaults remain five creation\nattempts per hour and two unfinished uploads per IP. `CROC_STORE_DOWNLOADS`\ncontrols downloads from each link and does not raise upload limits. See the\n[stored-transfer operator guide](src/docs/STORED_TRANSFERS.md) for timeout,\ncleanup, and rate-limit response behavior.\n\nThe ports in `CROC_RELAY_PORTS` must match the `publishedPorts` entries in\nthe `relay` service in [`disco.json`](disco.json); do not include the web\nservice's deployment-only port 9020. Disco cannot generate host port mappings\nfrom an environment variable. Make sure the relay TCP ports are also open in\nthe server's firewall or cloud security group.\n\n## Acknowledgements\n\n`croc` has evolved through many iterations, and I am thankful for the contributions! Special thanks to:\n\n- [@warner](https://github.com/warner) for the [idea](https://github.com/magic-wormhole/magic-wormhole)\n- [@tscholl2](https://github.com/tscholl2) for the [encryption gists](https://gist.github.com/tscholl2/dc7dc15dc132ea70a98e8542fefffa28)\n- [@skorokithakis](https://github.com/skorokithakis) for [proxying two connections](https://www.stavros.io/posts/proxying-two-connections-go/)\n\nAnd many more!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschollz%2Fcroc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschollz%2Fcroc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschollz%2Fcroc/lists"}