Self-hosted service
tickstep/aliyunpan avatar
tickstep/aliyunpan

Aliyunpan: one binary per CPU family, and a sync policy that deletes

Command-line client for Aliyun Drive (Aliyunpan), with JavaScript plugin support and sync/backup features.

5,137 stars393 forksGoApache-2.0

At a glance

What is it?
The Go client behind Aliyun Drive command line work: one binary published for eight CPU families, package manager routes that cover fewer of them, an interactive shell with Tab completion, and a sync loop whose two policies differ mostly in what they remove.
Who is it for?
Use aliyunpan when you want a terminal client for Aliyun Drive on a NAS, an embedded box or a headless machine, and pick the sync policy knowing that exclusive deletes and increment never does. Verify the backend before you commit: the login link points at openapi.alipan.com, the credential file is what the container mount expects, and main was last pushed on September 7, 2026 with v0.4.0 released on June 29, 2026.
Can I use it commercially?
Yes. Apache-2.0 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 69 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

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

From daily snapshots

Star history

  • tickstep/aliyunpan5,137 ★ · +21
Star history
Repository2026-09-232026-11-14
tickstep/aliyunpan5.1k5.1k

21 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

One binary per CPU family, and the release label is the only thing that tells them apart

Taking the binary straight from the release page means picking a filename by architecture, and the label list runs to eight families. arm, armv5 and armv7 cover 32-bit ARM. arm64 covers 64-bit ARM. 386 and x86 cover 32-bit Intel and AMD. amd64 and x64 cover 64-bit Intel and AMD. mips targets the MIPS instruction set, the kind of CPU in Kylin systems, where the big and little endian distinction decides which file you need. macOS ships two: amd64 for Intel machines and arm64 for Apple silicon. loong64 targets LoongArch64 machines such as Loongson CPUs. iOS arm64 is listed as well, with the stated requirement that the phone be jailbroken. There is no single universal build, so a reader who skips this table can end up holding a file built for the wrong instruction set.

apt, yum, brew and winget each cover less ground than the zip does

The direct download route is the widest of the six. Every package manager route is narrower. The apt instructions cover apt based systems such as Ubuntu and deepin, on amd64 and arm64 only. The yum instructions, written for CentOS and RockyLinux, also cover amd64 and arm64 only. brew, aimed at macOS, covers amd64 and arm64, with arm64 named as Apple Silicon. winget, for Windows, covers x86 and x64 only. What falls through the gap is 32-bit ARM, MIPS and LoongArch64 hardware, which has no package manager entry at all. On those machines the release page zip is the documented path, and with it you get no package manager update channel.

brew installs into the system prefix, so the config file goes with it

Because brew places the binary under a system directory, the config file lands under it too. The way out is the ALIYUNPAN_CONFIG_DIR environment variable pointed at a directory that already exists:

shell
brew install aliyunpan
export ALIYUNPAN_CONFIG_DIR=/Users/tickstep/Applications/adrive/config

The same variable works off macOS, where the documented example sets it to a path under the user home instead. Leave it unset and the program falls back to its default location, which on a brew install is the system one. The consequence is that any backup script that reads the config has to know that path in advance.

exclusive mirrors the directory, increment only ever adds

A backup pass runs one loop of three stages: scan, compare, execute. The policy you choose decides what happens to files that exist on only one side. exclusive is a one to one mirror, so extra files in the target directory get deleted, and a file deleted at the source is deleted at the target as well. increment copies only modified and new files. Extra files at the target are kept, and neither a source deletion nor an addition at the target is removed. The choice is not cosmetic. Under exclusive, anything else living in the target directory disappears on the next pass. Under increment, a file deleted at the source stays in the target directory.

The sync container cannot log in for you

The sync image mounts a config file it expects to already hold credentials:

sh
docker run -d --name=aliyunpan-sync --restart=always -v "<your aliyunpan_config.json>:/home/app/config/aliyunpan_config.json" -v "<your local dir>:/home/app/data" -e ALIYUNPAN_PAN_DIR="<your drive pan dir>" -e ALIYUNPAN_SYNC_MODE="upload" -e ALIYUNPAN_SYNC_POLICY="increment" -e ALIYUNPAN_SYNC_DRIVE="backup" -e ALIYUNPAN_SYNC_LOG="true" tickstep/aliyunpan-sync:v0.4.0

There is no login step in that command. The file it wants is the one a successful login produces elsewhere, so the order is fixed: log in on a machine first, keep the resulting aliyunpan_config.json, then mount it. ALIYUNPAN_SYNC_MODE takes upload or download, ALIYUNPAN_SYNC_POLICY takes exclusive or increment, ALIYUNPAN_SYNC_DRIVE names the drive and ALIYUNPAN_SYNC_LOG turns on logging. A container started before that file exists has nothing to authenticate with.

JavaScript hooks run inside the Go binary rather than a Node process

Plugin support is documented in docs/plugin_manual.md, where JavaScript attaches to the upload and download steps, and the same kind of script filters which files a backup copies. The engine is dop251/goja, listed in go.mod, which places plugin execution inside the Go binary instead of a separate runtime. That module also pins go 1.22 and pulls in urfave/cli for the command surface, peterh/liner for the interactive line, oleiade/lane, tickstep/bolt, tickstep/aliyunpan-api and olekukonko/tablewriter. The practical consequence is that a plugin written against Node built-ins carries no promise of running here, because it is evaluated by an embedded interpreter.

Login needs two browser passes and the link dies after five minutes

The login command prints a browser link that is valid for five minutes, and the flow takes two passes: one authorization and one QR code scan. The address points at openapi.alipan.com/oauth/authorize with the scopes user:base, file:all:read and file:all:write. Once it succeeds the prompt changes from aliyunpan > to a form carrying the working directory and the account nickname. Two details weigh on a headless box: five minutes is the window for both passes, and the credentials it writes are the same file the container mounts. For the full command set the text defers to docs/manual.md, and what it shows is a short list: album and abm, marked Beta, cd, download, ls, mkdir, mv, pwd, recycle, rename, rm, share, sync and upload.

Editorial conclusion

Use aliyunpan when you want a terminal client for Aliyun Drive on a NAS, an embedded box or a headless machine, and pick the sync policy knowing that exclusive deletes and increment never does. Verify the backend before you commit: the login link points at openapi.alipan.com, the credential file is what the container mount expects, and main was last pushed on September 7, 2026 with v0.4.0 released on June 29, 2026.

Frequently asked questions

What is aliyun, and what does the aliyunpan CLI do with it?

aliyunpan is a Go command line client for Aliyun Drive. It offers an interactive shell with commands such as ls, cd, upload, download, sync, share and recycle, JavaScript plugins for customizing the upload and download steps, and a backup mode aimed at NAS and embedded devices.

How does aliyunpan sync handle files that were deleted?

Under exclusive the backup is a one to one mirror: extra files in the target directory are deleted and a deletion at the source removes the target copy too. Under increment only modified and new files are copied, and nothing is deleted on either side.

Where does aliyunpan keep its config file?

Set the ALIYUNPAN_CONFIG_DIR environment variable to a directory that already exists. Without it the program uses its default location, which matters for brew installs because those put the binary and its config under the system directory.

Which CPU architectures does the aliyunpan apt repo cover?

Only amd64 and arm64. The yum repository covers those same two, brew covers amd64 and arm64 on macOS, and winget covers x86 and x64 on Windows. MIPS and LoongArch64 builds exist only as downloads from the release page.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. tickstep/aliyunpan on GitHub
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/tickstep-aliyunpan.svg)](https://hysenlabs.com/projects/tickstep-aliyunpan)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/tickstep-aliyunpan.svg)](https://hysenlabs.com/projects/tickstep-aliyunpan)

Was this useful?