PicX: a GitHub repository turned into an image host
PicX is an image-hosting tool built on the GitHub API, offering image upload and hosting, link generation and a toolbox of common image utilities.
At a glance
- What is it?
- PicX is a browser-based image hosting tool built on the GitHub API, where every upload becomes a commit in one repository and a set of link rules decides how the file is served. Since v3.0 the repository and branch are fixed by the project, which narrows it to people willing to hand over that choice.
- Who is it for?
- PicX fits a solo writer who wants pictures committed to a repository and served from jsDelivr or Statically without running a media server, and it does that from a page you open with nothing installed. It does not fit a team that needs its own repository, a pipeline that has to push images from a build, or anyone whose files must stay out of version control; those cases push you to the PicX v2.0 site or off GitHub-backed hosting entirely.
- 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 received new commits within the last day.
- 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Drag, paste or pick: every upload ends as a GitHub commit
PicX has no install step, and the hosted page at picx.xpoet.cn is the entire interface. Three ways of getting a file in are offered, drag and drop, clipboard paste and the normal file picker, and all three end the same way: a commit written through the GitHub API into a repository, plus a link that addresses that commit.
What makes the storage layer unusual is that it is not storage in the usual sense. Images are not handed to a bucket or a media server. They sit in a Git repository next to source code, where they are versioned, comparable and deletable like anything else a developer pushes. Everything else in the tool follows from that decision, including the parts that would otherwise be the product, such as naming, batching and link formatting.
Four link rules repoint one commit at different CDNs
Each built-in link rule rewrites a committed path into a different delivery URL: GitHub itself, GitHub Pages, jsDelivr or Statically. A custom rule editor covers the cases those four do not, and the settings page adds output formatting on top, so the same address can be copied as Markdown, HTML or BBCode. That distinction decides where a picture actually works, since a Markdown image is only an image in a Markdown renderer.
The repository topics are cdn, cloudflare, github-api, image-hosting, image-toolbox, jsdelivr and staticaly, so the delivery side was built with several networks in mind. The storage side has exactly one option. Keep that asymmetry in view when you compare PicX with anything that keeps images outside a repository: you gain a choice of networks to fetch from, and you gain no choice about where the bytes live.
Renaming, hashing and prefixes decide the committed filename
The upload pipeline applies a naming mode before anything is written. Rename sets the name yourself. Hashing exists to keep every image name unique, so the same picture uploaded twice cannot quietly overwrite its earlier commit. A prefix option prepends a string, which is how a project tag or a date ends up in front of every file. Directories are multi-level, so an upload can land several folders deep rather than at the root, and the management view lists what sits inside each level.
Batch operations cover the other half of the daily work. Images can be uploaded together, deleted together, and their links copied together instead of one image per visit, and the link format for the whole selection follows the Markdown, HTML or BBCode setting already chosen. That combination, rather than any single feature, is what turns the page into something usable while writing rather than a one-off uploader.
Compression and watermarking happen before the commit
The dependency list explains how: @jsquash/avif, @jsquash/jpeg, @jsquash/oxipng and @jsquash/webp are all present, and they are the re-encoders doing the work. Automatic compression is a setting, so a full-resolution phone photo can be shrunk before the upload step runs, which means the repository stores the small version and the original never becomes a commit at all. The watermark feature sits in the same settings area and is applied before the file leaves the page.
The toolbox takes the same codecs further and separates three jobs: compression, converting an image to Base64, and watermarking. Base64 conversion is the odd one out, because it never reaches the hosting layer. It is a local transformation for cases where you want the encoded string itself, such as a data URI in a style sheet or a document that will not accept a URL. Nothing in that path is written to a repository.
v3.0 removed repository and branch selection on purpose
This is the one decision that changes who can use the tool at all. From v3.0 onward there is no free choice of repository or branch, and the stated reason is that removing the choice simplifies operation. Anyone who still needs a custom repository or branch is pointed at the older PicX v2.0 deployment at v2.picx.xpoet.cn, a separate site kept running for that audience.
Note carefully what survived. Multi-level directory management is still a feature, so you still control the folder layout inside a repository you did not pick. You keep the naming modes, the link rules and the codecs; you give up the destination. For a solo writer that trade is cheap. For a team with an existing repository convention, a private images repository, or a review process around added files, it removes the reason the tool was interesting.
The version numbers in the repository tell the same story about pacing: v3.0.1 on 2024-03-13, v3.0.2 on 2024-04-30, then nothing until v3.1.0 on 2026-09-30, and the last push carries that same 2026-09-30 date. The build you would pin today is about two and a half years newer than the one before it, which is worth weighing before you depend on a feature that only exists in the newest one.
Running your own copy means Node 24, pnpm 11.18.0 and a build
The README gives you no install steps, because the hosted page is the intended path. If you want your own deployment anyway, the starting point is the package.json at the root of the repository.
{
"name": "picx",
"version": "3.1.0",
"packageManager": "[email protected]",
"engines": {
"node": ">=24 <25"
}
}The engines field pins a single Node major line, so anything outside Node 24 is outside what the project declares support for. The declared package manager is pnpm at 11.18.0, and the lockfile sitting beside it is pnpm-lock.yaml, with pnpm-workspace.yaml alongside it.
"dev": "vite --configLoader runner",
"build": "vite build --configLoader runner",
"preview": "vite preview --configLoader runner",
"test": "vitest run --configLoader runner",
"test:e2e": "playwright test"Those five scripts cover the local loop: a dev server, a production build, a preview server, unit tests driven by vitest.config.ts, and browser tests driven by playwright.config.ts against the tests/ directory. Nothing here uploads an image, which is the point to hold on to later.
"typecheck": "vue-tsc --noEmit -p tsconfig.app.json && tsc --noEmit -p tsconfig.worker.json",
"verify": "pnpm lint && pnpm lint:style && pnpm typecheck && pnpm test && pnpm build"The typecheck line is the detail that matters when you change the source. It checks two separate projects, the application through vue-tsc and a worker through tsc, which lines up with the six tsconfig files at the root: app, base, node, test, worker and the top-level one. The verify script chains lint, style lint, type check, tests and build into a single command, so a green run of that one script is the closest thing the project has to a CI contract. Git hooks are wired through husky, and commit messages go through commitizen with cz-custom reading .cz-config.js.
A tool that claims no install still ships a full toolchain
The highlights list opens by promising online use with no download and no installation, and on its own that is an accurate description of the hosted page. The repository tells a different story: index.html, src/, public/, vite.config.ts, eslint.config.mjs, stylelint.config.mjs, six tsconfig files, vitest.config.ts, playwright.config.ts, an AGENTS.md and a conventional commit setup built on commitlint and commitizen. That is the layout of an application with an owner who keeps it installable and testable, not of a page that only exists on someone else's domain.
The same tension shows up in what is missing. Authentication is two links, one for GitHub OAuth and one for pasting a token, with no statement anywhere of which permission scope the token needs. There is no note about what happens to the built-in repository if access is revoked, and no migration path described for images already committed there. Anyone planning a self-hosted copy has to take configuration details from picx-docs.xpoet.cn, because the repository does not carry them.
The licence is AGPL-3.0, copyright 2020-Present XPoet, and the same identifier is repeated in the package.json license field. It is the network copyleft variant, so a modified copy run as a service carries the same source disclosure duty as the original, which is a fact to settle before anyone forks this for internal use.
The wrong tool for build pipelines and private storage
Return to that scripts block and notice the absence rather than the presence. There is no upload command, no CLI entry point and no headless mode anywhere in it, and the toolbox features are reached through the page rather than a binary. A nightly job that has to push a fresh set of screenshots into a repository on every build is going to be written against the GitHub API directly, not against PicX. For a blog with one post a week that is irrelevant. For a documentation pipeline that regenerates images each build, it is the whole answer.
The second mismatch concerns where files live. From v3.0 onward every image is a commit in one built-in repository, and before that it was a repository of your choosing. Neither arrangement suits material that must not enter a version control history, such as client documents or anything under a retention policy. The toolbox half of the project sidesteps that entirely, because compression, Base64 conversion and watermarking all act on a local file with no hosting step attached, and that half is the part worth pulling in when the hosting half is not what you need.
Editorial conclusion
PicX fits a solo writer who wants pictures committed to a repository and served from jsDelivr or Statically without running a media server, and it does that from a page you open with nothing installed. It does not fit a team that needs its own repository, a pipeline that has to push images from a build, or anyone whose files must stay out of version control; those cases push you to the PicX v2.0 site or off GitHub-backed hosting entirely. Before adopting, check the Node 24 and [email protected] requirement against your build image, then read the token scope page in the documentation, because the README leaves that question unanswered.
Frequently asked questions
What does PicX do with an image after I upload it?
The upload is written through the GitHub API as a commit in a built-in repository. The link rules for GitHub, GitHub Pages, jsDelivr and Statically all address that same committed file.
Can PicX upload to my own GitHub repository and branch?
Not in the current version. Free selection of repository and branch was dropped with v3.0, and the project points users who still need it at the PicX v2.0 deployment at v2.picx.xpoet.cn.
How do I install PicX on my own server?
The README documents no install step and points at the hosted entry point instead. For a local build, package.json requires Node 24 within the >=24 <25 range and names [email protected] as the package manager.
Does PicX compress and watermark images before uploading?
Yes. Compression can be set to run automatically before upload, watermarks are configured in the same settings area, and a separate toolbox exposes compression, Base64 conversion and watermarking on their own.
Can PicX publish images automatically from a build script?
The scripts in package.json cover development, build, preview, linting, type checking and tests, and none of them uploads an image. Automated publishing has to call the GitHub API directly.
Official sources
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.
[](https://hysenlabs.com/projects/xpoet-picx)Was this useful?