Building a Home for the Skills I Kept Reusing

Published:

Why I built it

As I spent more and more time with agent tools like Claude Code and WorkBuddy, I ended up collecting more and more Skills. Some of them were huge: hundreds of files, hundreds of megabytes, sometimes even over a gigabyte. My old routine was simple enough: I would throw the Skill folder into the relevant project directory and tell the agent, 'load xx skill and do xx.'

It sounded convenient. In practice, the problems piled up quickly:

  • Messy storage: Skills were scattered across different project folders, with no central place to keep them.
  • Hard to find: A Skill that felt useful today could easily be forgotten a few weeks later, and finding it again meant digging through folders.
  • Repeated copying: If I wanted the same Skill in another project, I had to copy it over again.

So I started thinking: why not build my own Skill library, somewhere I could upload the good ones I had used, keep track of them, and download them whenever I needed?

I was not trying to build something overly polished or ambitious. I just wanted something that would make my own day-to-day use easier and give me a place to accumulate useful Skills over time. That turned into a little Vibecoded Skill marketplace.

How the site looks and works

UI style

I first asked AI to整理 a style guide for my blog theme project, then fed that document directly to Claude Code and asked it to design the Skill marketplace in the same visual language.

What came out was a warm, translucent frosted-glass look: large rounded cards, semi-transparent backgrounds, and the LXGW WenKai font. In dark mode, the cards have a faint self-glow effect. The whole thing feels clean and soft, which is exactly the kind of minimal look I personally like, so I have not changed much since then.

Home page

The landing page is straightforward: a search box, category tags, and a grid of Skill cards. You can filter by category, such as developer tools, debugging and diagnostics, deployment and operations, documentation writing, or AI-related Skills, or just type in keywords to search.

The category tags support horizontal scrolling, so they work well on mobile too. Each card shows the title, category badge, download count, and version number, so you can understand the basic information at a glance.

Detail page

Clicking a card opens the detail page, which automatically renders the Skill's README.md. Full Markdown is supported: tables, code blocks, strikethrough, task lists, all of it displays normally.

External images, such as screenshots hosted on GitHub, also load correctly. I added a maximum width limit so they would not stretch the card layout. Clicking any image opens a frosted overlay lightbox showing the original image, and you can close it with Esc or by clicking the background.

Uploading Skills

I prepared four upload paths: a single .md file, a .zip or .tar.gz archive, and picking a folder directly in the browser, which the backend packages into a zip before uploading. I mainly added the folder option because it makes content extraction for the detail page easier.

After upload, the system tries to extract preview content intelligently. It first looks for a README.md in the root directory. If that is missing, it searches subdirectories. If it still cannot find one, it falls back to the first .md file it sees. There is no need to manually tell the system which file is the main document.

Images inside archives are handled automatically too. After extraction, they are uploaded to Qiniu Cloud CDN, and the image paths in the preview are rewritten into direct links.

Category management

Categories can be managed from the admin side at any time: create, rename, or delete them. If a category is removed, the Skills under it are automatically moved into 'Other', so no data is lost.

Visitor and admin permissions

There is no public sign-up flow. The admin account is preset in .env, so the system is basically managed by one person. That setup also makes sense because the free storage and bandwidth quota for object storage are limited.

Visitors can browse the homepage, filter and search Skills by category or keyword, open detail pages to view the rendered README, and click images to see the lightbox view. If the admin adds a GitHub URL during upload, visitors can use the 'Go to GitHub to download' button to get the source directly. I usually also include the original project GitHub address, so if someone likes the Skill they can fetch it from upstream and give the developer a star.

Administrators can upload Skills, download the original Skill files, edit Skill information, delete Skills, and manage categories. Upload, delete, and download actions are all written into a local log file.

The stack behind it

The backend uses Go with Chi Router for routing, SQLite powered by modernc.org/sqlite for the database, Go's standard html/template package for templates, Goldmark for Markdown rendering, and Qiniu Cloud Kodo plus CDN for file storage and download acceleration.

On the frontend, I kept things light. There is no framework. CSS handles the frosted-glass effect, dark mode, and responsive layout through CSS variables. JavaScript only brings in Alpine.js for theme switching and the image lightbox. Authentication uses gorilla/sessions for cookie sessions, and the admin account is preloaded into SQLite, so there is no registration process. The logger is a custom package that rotates logs by file size: one file tops out at 10MB, up to 5 files are kept, and total disk usage is hard-capped at 50MB.

The key decisions

Single-binary deployment. The whole app compiles into a 24MB binary, with SQLite embedded inside it. It does not depend on external services. Copy it to a server, place .env, template/, and static/ next to it, and ./skill_market is enough to start it.

Downloads do not consume server bandwidth. The cloud server I was using only had 3Mbps of bandwidth, which made direct downloads painfully slow. So I switched to object storage. After upload, Skill files go straight to Qiniu Cloud Kodo, and the database only stores the CDN link. When a user clicks download, the server responds with a 302 Redirect to the Qiniu direct link, so the actual transfer is handled entirely by the CDN. The small 3Mbps pipe only serves page requests, which is more than enough.

Smart preview extraction. When uploading a zip, tar.gz, or folder, the backend searches for preview content in priority order: root README.md → README.md in a subdirectory → the first .md in the root → any .md file. Once found, the text is stored in the database and rendered into HTML on the detail page with Goldmark. Users never need to specify which file is the document.

Automatic image path rewriting. If a Markdown file inside an archive references a local image like ![example](demo.png), the upload process extracts that image, uploads it to Qiniu, and rewrites the path to a CDN URL. That way, the rendered <img> tags on the detail page point directly to the CDN and do not break because of relative paths.

Log rotation by space, not date. Logs do not rotate by day. Instead, each file is capped at 10MB, then the next file is created automatically. At most five files are kept, and the oldest one is deleted when the limit is exceeded. That keeps total disk usage within 50MB, which is a good fit for small system disks.

Editable categories. Categories are not hardcoded. They can be added, removed, and renamed from the admin panel. If a category is deleted, the Skills under it are automatically moved to 'Other', so there are no orphaned entries.

Deployment

I sent the GitHub link to a server-side Hermes instance through Feishu, and it handled the whole flow on its own: pulling the code, installing dependencies, compiling and starting the app, writing the systemd unit for process supervision, booting on startup, and automatic restart on crashes, configuring nginx as a reverse proxy, and using certbot to request a Let’s Encrypt certificate for HTTPS.

A few small issues came up along the way, and Hermes fixed the code directly until everything ran cleanly. In the end, I handed it a GitHub Personal Access Token, and it even committed the changes back to my repository.

A small tool, but useful to me

At the moment, I am pretty happy with how it turned out. I hope I can keep maintaining it.

If you also use agent tools a lot and have collected a pile of Skills, this little project might solve the same kind of problem for you. Set up the .env file and it should run.

It is still just a lightweight tool built to solve my own pain points, so there are definitely places that are not mature yet and still need polishing. If you are interested, feel free to take a look and share suggestions. The code is open source on GitHub: https://github.com/xjwukk/skill_market