Open-source project
OpenListTeam/OpenList-Worker avatar
OpenListTeam/OpenList-Worker

OpenList-Worker: the OpenList file list ported to edge runtimes

Service Worker Backend for OpenList

616 stars1,045 forksTypeScriptAGPL-3.0

At a glance

What is it?
OpenList-Worker is the official TypeScript and Serverless port of the OpenList project, a multi purpose directory listing tool that mounts dozens of cloud drives behind one interface. The rewrite takes the backend from Go to TypeScript so it can run on Cloudflare Workers, EdgeOne and Alibaba ESA, and the interesting decisions are in the storage layer, where the database driver, format and cipher are all configuration.
Who is it for?
OpenList-Worker fits a team that wants to aggregate personal or shared cloud drives behind one interface and deploy it to an edge runtime with platform native storage, and it does not fit a workload that needs a durable filesystem, heavy write throughput or a long running Go service.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, 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 Go backend rewritten in TypeScript to run on Workers

OpenList is a multi function directory listing tool that supports mounting file storage from dozens of cloud drives and offers file preview, download and sharing. OpenList-Worker is the official TypeScript and Serverless architecture port of the OpenListTeam/OpenList project, and the README is specific about what changed: the backend was rewritten from Go into a TypeScript service that runs on Workers, while the frontend keeps a consistent interface and interaction experience.

The runtime targets are the point of the port. The project runs on Cloudflare Workers, on Tencent's EdgeOne Cloud Functions and on Alibaba Cloud ESA, and the platform list is broader still, adding Vercel, AWS Lambda and a Node.js container environment. The repository layout shows how one codebase serves all of them, with separate directories for the Cloudflare functions, the EdgeOne cloud functions, the Node functions and the shared source, plus a wrangler.jsonc, an edgeone.json, an esa.jsonc, a sea-config.json, a serverless.yml and a vercel.json.

The stack on the backend is Hono.js for the web framework, TypeScript for the language, and Wrangler with esbuild for the build. The frontend is SolidJS with TypeScript, using the official OpenList-Frontend project, the Hope UI component library and Vite for the build.

The licence is AGPL-3.0, the version in package.json is 4.2.3, the last push was on 2026-10-20 and the repository is not archived. There are no GitHub releases, so the version you get is the one published to the package registry, and the deployment platforms pull the code from the repository directly.

Seventy-eight drivers, including eight that are not storage at all

The driver count is the headline feature, and the README groups them in a way that is more useful than a flat list.

The domestic cloud drive group covers a long list of regional providers, among them Aliyun Drive through both its open platform and share links, Quark Drive in its open platform and UC TV editions, Baidu Netdisk for albums, 115, 123 Cloud, China Telecom's 189 with its PC and TV variants, China Mobile's 139 and He Caiyun, Wo Jia, Thunder Cloud, Tencent Weiyun, Lanzou, PikPak through shares, Doubao Netdisk, WPS Netdisk and Aliyun Docs. The international group names Google Drive for albums, OneDrive for apps and share links, Dropbox, MEGA, MediaFire, Proton Drive, Yandex Disk, Degoo, Bunny Storage and TeraBox. Object storage is covered by the S3 compatible APIs for AWS, OSS, COS and MinIO, Cloudflare R2 through a Workers binding or its S3 API, Azure Blob, WebDAV, FTP, SFTP, SMB and IPFS. Code hosting is covered by GitHub, GitHub Releases and CNB Releases, and there is a group for other programs such as AList V3, Cloudreve, Kodbox, Seafile and Febbox.

Then there is the part that is more interesting, the virtual and functional drivers: Local, Alias, UrlTree, AutoIndex, Strm, Crypt, Virtual and Chunk. These are not places to fetch files from. They are transformations, and they are what turn a file browser into a composable layer. UrlTree turns a list of URLs into a browsable tree. Strm produces stream links. Crypt is an encrypted store. Alias and Virtual rewrite paths. Chunk splits large files. AutoIndex generates a directory listing for a source that has none.

That combination is the actual capability: a static index over remote drives, with a mapping layer in between, which is how you build a personal search or preview surface over storage you do not control.

Sharing, search, background tasks and two outbound protocols

The core capabilities are listed in the README and they describe a file management system rather than a listing page.

Browsing covers a unified directory tree with online preview for images, video, audio, documents, code and archives. Upload and download work across storages, with batch downloads, streaming transfer and direct link redirection, which is the mechanism that lets a client fetch straight from the upstream rather than proxying bytes through the worker.

Sharing generates links with an expiry date, a password and permission control, and supports anonymous access and directory shares, so a folder can be published as a unit.

Full text search queries the storages that have been indexed. Offline tasks are handled by a background task queue for batch operations and asynchronous processing, which is what makes a bulk operation across seventy-eight drivers practical on a runtime that may freeze between requests.

The external interface capability is the one that changes the shape of the product. The aggregated storage can be exposed outward as WebDAV or as an S3 compatible protocol, so it can be mounted into third party tools as if it were a disk or a bucket. There is also an MCP endpoint, a Model Context Protocol server that AI assistant clients can call, and a concurrency deduplication mechanism where identical directory listing or metadata requests at the same moment produce a single upstream call and the rest reuse that result, which avoids pointless rate limiting on the upstream drive.

RBAC, four ways to authenticate, and the health probes

Permission management is role based, with user groups, directory level read and write permissions and quotas. The README is clear that the permission model is not just about roles either, since the quota and the directory scope are part of it.

Authentication is layered. There is a built in account and password, plus TOTP verification, WebAuthn and FIDO login, SSO single sign on, and LDAP directory authentication. So an organisation can put the whole thing behind its existing identity provider, and a personal deployment can ignore all of that.

Hardening is listed separately: JWT sessions, CSRF protection, clickjacking protection through X-Frame-Options, and a content security policy. The JWT secret is the same secret used for scheduled task authentication, which is worth noting because it means a leaked secret is not only a session problem.

Two health endpoints are provided, a /health liveness probe and a /healthz readiness probe, and the README says they exist for monitoring and alerting. On a platform like Workers, where an instance is not a process you can keep alive, having a documented readiness endpoint is what lets an external monitor tell the difference between a cold start and a broken deployment.

The at rest encryption story is part of the same picture. The configuration surface includes a cipher for sensitive fields, covering drive credentials, two factor secrets and password hashes, with a set of named algorithms, and the default is none, meaning no encryption, which is a choice the deployer has to make rather than something the platform forces.

One click deploy, and the two variables worth setting by hand

The deployment section offers one click buttons for EdgeOne Makers on the international and China sites and for Cloudflare Workers, and the README flags a snag: if Cloudflare reports that it cannot fetch the repository content, you need to fork the project first and deploy through the connect to GitHub repository route.

Most deployments need no configuration beyond one variable. Data storage defaults to DB_DRIVER=auto, which selects whatever persistence the platform provides, and the README says the only variable it recommends setting explicitly is JWT_SECRET, a random string of at least 16 characters used to sign JWT tokens and to encrypt data, generated with openssl rand -hex 32. If it is not configured, the application generates one at initialisation and persists it.

The README also insists that JWT_SECRET be set as a secret rather than as an ordinary variable, because ordinary variables can be replaced on a redeploy. That is a small instruction with a large consequence, and it is the kind of detail that separates a deployment that works from one that silently loses its sessions and its stored credentials.

Initialisation happens in the browser. The first visit to the site opens an installation wizard where you set the administrator account and password, and if you would rather skip the wizard you can set ADMIN_PASS and the admin account is created with that password.

The storage layer is the part to read before you deploy

The cloudflare bindings block in package.json documents the configuration surface, and it is the most informative part of the file.

DB_DRIVER selects the storage driver, with auto as the default and blob, cfkv, kv, d1, do and mysql as the explicit options. The description of the default is where the design shows: an explicitly configured driver is never replaced automatically, and if it is unavailable the application reports a configuration error, including which driver auto-detection would have picked, rather than writing to another backend. Invalid driver and format combinations are reported the same way. That is an unusual amount of care about a misconfiguration, and it is the right care for a system that holds the credentials of seventy-eight different services.

DB_FORMAT selects the storage format, with map for the whole JSON document, key for per key storage and sql for the relational format that is compatible with the Go version. The sql format is what lets an existing Go deployment migrate without changing its data.

DB_CIPHER sets the at rest cipher for sensitive fields, and the options are enumerated with their envelope versions: none, which is the default and means no encryption, aes-256-gcm with an HKDF derived key writing the enc:v2: envelope, which is the recommended one, aes-256-gcm-pbkdf2 writing the older enc:v1: envelope with a per field PBKDF2 derivation and described as slow, aes-256-cbc-hmac for enc:v3:, chacha20-poly1305 for enc:v4: as a pure JavaScript implementation, and the single and triple DES CBC HMAC variants for enc:v5: and enc:v6:, which are marked for compatibility only.

There is also a frontend CDN option, with a variable pointing at a CDN that serves the built frontend, and a build from source switch. The env example explains the fallback chain in detail, and the point of it is that a CDN that refuses to serve HTML still works as long as the hashed assets match the build exactly.

Local development, and the difference from the Go deployment

Manual deployment needs Node.js 18 or newer, pnpm is recommended, and a Cloudflare account for the Workers target. The local flow is a dependency install, then a development server.

bash
pnpm install

The bindings and variables are configured as needed in wrangler.jsonc, with JWT_SECRET documented in .dev.vars.example, and there are two development modes.

bash
pnpm run dev:unified
pnpm run dev:worker

The unified mode pulls the official frontend and runs the worker, and the worker-only mode skips the frontend, which is what you want when you are changing backend code.

Production deployment has the same two shapes.

bash
pnpm run deploy
pnpm run deploy:worker

The environment template in the repository is also instructive, because it explains why the values are blank. The file is committed to a public repository, so it must never contain real secrets, and the values the user enters during deployment become the worker's secrets, which are not overwritten on later updates. For local development the same file is copied to .env, which the gitignore already covers.

The difference from the Go version is the real trade-off. The Go release is a long running service with its own database and its own process lifecycle, and it can be installed anywhere a binary runs. This port trades that for the ability to run on an edge runtime with platform native persistence, which removes the server you have to keep alive, at the cost of working within the platform's storage primitives, with the driver and format options above, and of the request and execution limits those platforms impose.

Editorial conclusion

OpenList-Worker fits a team that wants to aggregate personal or shared cloud drives behind one interface and deploy it to an edge runtime with platform native storage, and it does not fit a workload that needs a durable filesystem, heavy write throughput or a long running Go service. Before deploying, set JWT_SECRET as a secret rather than a plain variable, decide the storage driver explicitly rather than leaving it on auto, and read the driver descriptions for the 78 storage backends you actually plan to mount.

Frequently asked questions

What is OpenList-Worker and how does it relate to OpenList?

It is the official TypeScript and Serverless architecture port of the OpenListTeam/OpenList project, which is a directory listing tool that mounts dozens of cloud drives. The backend was rewritten from Go into a TypeScript service that runs on Cloudflare Workers, EdgeOne and Alibaba ESA, while the frontend keeps the same interface.

Which storage backends does OpenList-Worker support?

The README counts 78 built in storage drivers, covering regional cloud drives, international services such as Google Drive and Dropbox, S3 compatible object storage, code hosting, and other file sharing programs. It also lists virtual drivers including Local, Alias, UrlTree, AutoIndex, Strm, Crypt, Virtual and Chunk for local mounts, aliases, URL lists, encrypted storage and chunking.

Which environment variables do I need to set when deploying OpenList-Worker?

The README says most deployments need no extra configuration because data storage defaults to DB_DRIVER=auto, and it recommends setting only JWT_SECRET, a random string of at least 16 characters used to sign tokens and encrypt data, which is auto-generated if left unset. ADMIN_PASS can be set to skip the browser setup wizard.

How do I run OpenList-Worker locally?

You need Node.js 18 or newer, with pnpm recommended. Run pnpm install, configure the bindings and variables in wrangler.jsonc, then start pnpm run dev:unified to pull the official frontend and run the worker, or pnpm run dev:worker to run the worker alone.

What does OpenList-Worker expose to other tools?

Besides browsing, uploading, sharing with expiry, password and permissions, full text search and background offline tasks, it can expose the aggregated storage outward as WebDAV or as an S3 compatible protocol, and it provides an MCP endpoint for AI assistant clients. Identical concurrent listing requests are deduplicated into a single upstream call.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. OpenListTeam/OpenList-Worker on GitHub
  4. README
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/openlistteam-openlist-worker.svg)](https://hysenlabs.com/projects/openlistteam-openlist-worker)