A fully customized, 100% free, open-source LinkTree alternative — deployed straight to GitHub Pages. Inspired by Jekyllrb and LinkTree.
$ npx -y skills add ZhgChgLi/linkyee --agent claude-code
Repo: ZhgChgLi/linkyee
What's inside
English | 繁體中文
A fully customized, 100% free, open-source LinkTree alternative — deployed straight to GitHub Pages.
Inspired by Jekyllrb and LinkTree.
In one sentence: click Use this template, edit one YAML file, push — your link page is live on GitHub Pages with a free
*.github.iodomain (or your own). No SaaS, no monthly fee, no vendor lock-in. AI-assisted theming and plugin development included.
config.yml.linkyee-style-designer Claude skill writes the full theme for you (HTML + CSS + JS).linkyee-plugin-builder skill writes the Ruby plugin and wires it in../preview.sh rebuilds on save; refresh the browser, no plugins needed.If this project has helped you, feel free to sponsor me a cup of coffee, thank you.
Feel free to open an issue or submit a fix/contribution via pull request. :)
Everything that ends up on your page is driven by a single file: config.yml. It's a Liquid-rendered YAML file with five top-level sections:
theme: default # ← directory under ./themes/
lang: "en"
plugins: # ← optional dynamic data fetched at build time
- GithubRepoStarsCountPlugin: [ZhgChgLi/linkyee]
title: "Your Name" # ← profile header
avatar: "./images/profile.jpeg"
name: "@yourhandle"
tagline: "One line about you."
links: # ← buttons in the link list
- link:
icon: "fa-brands fa-github"
text: "GitHub ({{ vars.GithubRepoStarsCountPlugin['ZhgChgLi/linkyee'] }} ⭐)"
url: "https://github.com/yourname"
target: "_blank"
socials: [ ... ] # ← icon-only social row
footer: "Free-form HTML."
copyright: "© 2026 You."
The shipped config.yml is a fully working example that exercises every built-in plugin — read it as the canonical reference. Edit fields in place, push, wait for GitHub Actions to rebuild, refresh.
The site rebuilds automatically once a day so plugin output (star counts, latest posts, etc.) stays fresh. The cron lives in build.yml:
schedule:
- cron: '0 0 * * *' # daily at 00:00 UTC
Delete the schedule: block if you don't want scheduled redeploys.
linkyee ships 8 built-in themes designed to be drop-in usable. Switch by editing one line in config.yml:
theme: minimal-mono # any directory under ./themes/
| Slug | Light | Dark | Aesthetic / good for |
|---|---|---|---|
default | Clean cards · safe default for anyone | ||
minimal-mono | Swiss minimal · monospace · engineers, writers | ||
editorial-serif | Magazine serif · drop cap · bloggers, journalists | ||
neo-brutalism | Thick borders · primary colors · indie devs, artists | ||
glassmorphism | Frosted glass cards · designers, agencies | ||
paper-card | Pastel cards · rounded · creators, illustrators | ||
newsprint | Newspaper masthead · serif + mono · numbered link rows · the live look of link.zhgchg.li | ||
terminal-retro | CRT · scanlines · phosphor-green-on-black (dark) / olive-on-cream printer-paper (light) · hackers |
Every built-in theme meets the same baseline: WCAG AA contrast, dark mode that auto-switches with your system appearance (no manual toggle), responsive down to 320 px, keyboard-accessible focus states, and prefers-reduced-motion support.
To try them locally before committing, see Local testing. To regenerate the preview screenshots above after any visual change, run ./scripts/screenshot-themes.sh (requires npx playwright).
Each theme lives at ./themes/<theme-name>/ with three files:
index.html — Liquid template (consumes config.yml)styles.css — the lookscripts.js — can be empty, but the file must existThe default theme self-hosts Font Awesome under themes/default/fontawesome/. The other built-ins load Font Awesome from a CDN to keep theme directories small.
Don't see a vibe you like? Describe it in plain English and the bundled linkyee-style-designer Claude skill writes a full theme for you.
How to use it:
Install Claude Code and open this repo with it.
Ask in natural language. Examples:
"Design a linkyee theme inspired by 1960s Penguin paperback covers."
"Make my links look like a Japanese ryokan website — quiet, elegant, lots of negative space."
"I want a vaporwave aesthetic but keep it accessible."
The skill reads your config.yml, asks clarifying questions if the brief is vague, generates themes/<your-theme>/, switches theme: in config.yml, and runs the build.
Run ./preview.sh <new-theme> to see the result locally.
The skill enforces the same quality bar as the built-in themes: no AI slop (no unwarranted purple-pink gradients, no emoji-as-icons, no centered-everything-no-hierarchy), real typographic hierarchy, accessibility minimums, and strict RWD — mobile-first, ≥44 px tap targets, no horizontal scroll at 320 px.
Deeper design tooling. If you want a richer designer experience (multi-direction exploration, expert review, animation export), install the upstream huashu-design skill alongside it. The linkyee skill defers to huashu-design when both are present.
Plugins are tiny Ruby classes that fetch data at build time and inject it into your page. Use them to render live values inside any link, the tagline, or the footer — anything that's a Liquid string.
| Plugin | What it emits | Reference shape |
|---|---|---|
GithubRepoStarsCountPlugin | Star count for one or more repos | {{ vars.GithubRepoStarsCountPlugin['owner/repo'] }} |
GithubLastCommitPlugin | Latest commit sha / date / message | {{ vars.GithubLastCommitPlugin['owner/repo'].date }} |
GithubProfilePlugin | followers / following / repos | {{ vars.GithubProfilePlugin['user'].followers }} |
RSSFeedPlugin | Latest items (Medium / blog / podcast / YouTube feeds) | {{ vars.RSSFeedPlugin['url'][0].title }} |
CountdownPlugin | Days until / since a target date | {{ vars.CountdownPlugin.label.days }} |
YouTubeChannelLatestVideoPlugin | Latest video — title, URL, thumbnail | {{ vars.YouTubeChannelLatestVideoPlugin['@handle'].title }} |
Enable in config.yml:
plugins:
- GithubRepoStarsCountPlugin:
- ZhgChgLi/linkyee
- RSSFeedPlugin:
- https://yourblog.example/feed.xml
…then reference the result anywhere a Liquid string is rendered:
links:
- link:
icon: "fa-brands fa-github"
text: "linkyee ({{ vars.GithubRepoStarsCountPlugin['ZhgChgLi/linkyee'] }} ⭐)"
url: "https://github.com/ZhgChgLi/linkyee"
If a plugin fails at build time (network error, API change, expired token, …) the build still succeeds — the value renders empty and the failure is logged in GitHub Actions output. Your site never breaks because of a flaky external API.
Want data linkyee doesn't ship out of the box? Open the repo with Claude Code and describe what you want. The bundled linkyee-plugin-builder skill knows the plugin contract.
Examples:
"Add a plugin that shows my 3 latest posts from medium.com/@myhandle as new links."
"Fetch the current weather in Taipei from wttr.in and show the temp in the footer."
"Add a plugin that pulls my Steam total playtime via the Steam Web API."
The skill will:
plugins/<YourPlugin>.rb (using the base-class HTTP/JSON/cache helpers — no raw Net::HTTP).config.yml under plugins: and reference the output where you asked it to appear.bundle exec ruby ./scaffold.rb and verify the value rendered in _output/index.html.For the full plugin contract — base-class helpers, common patterns (HTTP, JSON, scrape, cache), Liquid rendering rules, and debugging tips — read plugins/README.md. It's the canonical reference the AI skill loads when it generates a plugin.
GitHub Pages is a free hosting service provided by GitHub, designed for creating and publishing websites directly from a GitHub repository. It allows developers, designers, and anyone with a GitHub account to host personal, project, or organizational websites without needing external hosting services. GitHub Pages works seamlessly with GitHub repositories, automatically generating a static website whenever new content is pushed.
The GitHub Pages repo name will affect the access URL. If you enter
your-username.github.ioas the Repo Name, that will be the direct URL to your GitHub Pages site. If you already have ayour-username.github.iorepo, the GitHub Pages URL will beyour-username.github.io/Repo-Name.
Allow all actions and reusable workflowsRead and write permissionsAfter selecting, click the Save button to save your changes.
The message
Your site is live at: XXXXabove is your public GitHub Pages access URL.
Congratulations! Deployment successful. You can now modify the configuration files with your own data. 🎉🎉🎉
Automatic build and pages build and deployment tasks.Refresh the page for the changes to take effect. 🚀
Build and serve the site on http://localhost:8080:
./preview.sh # build with the theme currently set in config.yml
./preview.sh minimal-mono # temporarily switch to <theme-name>, build, serve;
# restores config.yml on Ctrl-C
PORT=4000 ./preview.sh # use a different port
When you pass a theme argument, preview.sh makes a backup of your config.yml, switches to the requested theme for the session, and restores the original on Ctrl-C — your committed config is never modified.
While the preview is running, preview.sh watches:
themes/plugins/config.ymlscaffold.rbAny change triggers an instant rebuild — just refresh the browser. Install fswatch (brew install fswatch on macOS) for sub-second reaction; otherwise it falls back to a 1-second polling loop that works without any extra dependencies.
If a build fails (e.g. a broken Liquid reference), the watcher prints the error and keeps running — fix the issue, save again, the next save rebuilds.
bundle install once to fetch liquid and nokogiri)preview.sh spawnsYou can set a custom GitHub Pages domain, such as my own: https://link.zhgchg.li.
Follow my tutorial for domain binding. If you'd like, you can purchase a domain through my Namecheap referral link — I'll earn a small commission, which helps me keep contributing to open-source projects.
Real websites built with linkyee — fast, clean, and open-source.
Built your own site with linkyee?
⭐ Add it here by opening a PR and inspire others!
| Preview | Website | Description |
|---|---|---|
| link.zhgchg.li | ZhgChgLi (Harry Li)'s Personal blog link page | |
| - | Your Site | Your site could be featured here 🚀 |
_output/
AUTO_GEN_FOLDER_DO_NOT_EDIT_FILE_HERE
.claude/
skills/
linkyee-plugin-builder/
SKILL.md
linkyee-style-designer/
SKILL.md
.github/
FUNDING.yml
workflows/
build.yml
.gitignore
.linkyee-cache/
gh-last-commit--ZhgChgLi--linkyee.json
gh-profile--v2--ZhgChgLi.json
gh-stars--ZhgChgLi--linkyee.json
gh-stars--ZhgChgLi--ZMarkupParser.json
gh-stars--ZhgChgLi--ZMediumToMarkdown.json
gh-stars--ZhgChgLi--ZReviewTender.json
rss--https--en.zhgchg.li--feed.xml.json
yt--resolve--@zhgchgli.json
yt-latest--@zhgchgli.json
.ruby-version
config.yml
deploy.sh
Gemfile
Gemfile.lock
LICENSE
plugins/
CountdownPlugin.rb
GithubLastCommitPlugin.rb
GithubProfilePlugin.rb
GithubRepoStarsCountPlugin.rb
Plugin.rb
README.md
RSSFeedPlugin.rb
YouTubeChannelLatestVideoPlugin.rb
preview.sh
README.md
README.zh-TW.md
scaffold.rb
scripts/
screenshot-themes.sh
seed-cache.rb
themes/
default/
fontawesome/
css/
all.css
all.min.css
brands.css
brands.min.css
fontawesome.css
fontawesome.min.css
regular.css
regular.min.css
solid.css
solid.min.css
svg-with-js.css
svg-with-js.min.css
v4-font-face.css
v4-font-face.min.css
v4-shims.css
v4-shims.min.css
v5-font-face.css
v5-font-face.min.css
js/
all.js
all.min.js
brands.js
brands.min.js
conflict-detection.js
conflict-detection.min.js
fontawesome.js
fontawesome.min.js
regular.js
regular.min.js
solid.js
solid.min.js
v4-shims.js
v4-shims.min.js
less/
_animated.less
_bordered-pulled.less
_core.less
_fixed-width.less
_icons.less
_list.less
_mixins.less
_rotated-flipped.less
_screen-reader.less
_shims.less
_sizing.less
_stacked.less
_variables.less
brands.less
fontawesome.less
regular.less
solid.less
v4-shims.less
LICENSE.txt
metadata/
categories.yml
icon-families.json
icon-families.yml
icons.json
icons.yml
shims.json
shims.yml
sponsors.yml
scss/
_animated.scss
_bordered-pulled.scss
_core.scss
_fixed-width.scss
_functions.scss
_icons.scss
_list.scss
_mixins.scss
_rotated-flipped.scss
_screen-reader.scss
_shims.scss
_sizing.scss
_stacked.scss
_variables.scss
brands.scss
fontawesome.scss
regular.scss
solid.scss
v4-shims.scss
sprites/
brands.svg
regular.svg
solid.svg
svgs/
brands/
42-group.svg
500px.svg
accessible-icon.svg
accusoft.svg
adn.svg
adversal.svg
affiliatetheme.svg
airbnb.svg
algolia.svg
alipay.svg
amazon-pay.svg
amazon.svg
amilia.svg
android.svg
angellist.svg
angrycreative.svg
angular.svg
app-store-ios.svg
app-store.svg
apper.svg
apple-pay.svg
apple.svg
artstation.svg
asymmetrik.svg
atlassian.svg
audible.svg
autoprefixer.svg
avianex.svg
aviato.svg
aws.svg
bandcamp.svg
battle-net.svg
behance.svg
bilibili.svg
bimobject.svg
bitbucket.svg
bitcoin.svg
bity.svg
black-tie.svg
blackberry.svg
blogger-b.svg
blogger.svg
bluesky.svg
bluetooth-b.svg
bluetooth.svg
bootstrap.svg
bots.svg
brave-reverse.svg
brave.svg
btc.svg
buffer.svg
buromobelexperte.svg
buy-n-large.svg
buysellads.svg
canadian-maple-leaf.svg
cc-amazon-pay.svg
cc-amex.svg
cc-apple-pay.svg
cc-diners-club.svg
cc-discover.svg
cc-jcb.svg
cc-mastercard.svg
cc-paypal.svg
cc-stripe.svg
cc-visa.svg
centercode.svg
centos.svg
chrome.svg
chromecast.svg
cloudflare.svg
cloudscale.svg
cloudsmith.svg
cloudversify.svg
cmplid.svg
codepen.svg
codiepie.svg
confluence.svg
connectdevelop.svg
contao.svg
cotton-bureau.svg
cpanel.svg
creative-commons-by.svg
creative-commons-nc-eu.svg
creative-commons-nc-jp.svg
creative-commons-nc.svg
creative-commons-nd.svg
creative-commons-pd-alt.svg
creative-commons-pd.svg
creative-commons-remix.svg
creative-commons-sa.svg
creative-commons-sampling-plus.svg
creative-commons-sampling.svg
creative-commons-share.svg
creative-commons-zero.svg
creative-commons.svg
critical-role.svg
css3-alt.svg
css3.svg
cuttlefish.svg
d-and-d-beyond.svg
d-and-d.svg
dailymotion.svg
dart-lang.svg
dashcube.svg
debian.svg
deezer.svg
delicious.svg
deploydog.svg
deskpro.svg
dev.svg
deviantart.svg
dhl.svg
diaspora.svg
digg.svg
digital-ocean.svg
discord.svg
discourse.svg
dochub.svg
docker.svg
draft2digital.svg
dribbble.svg
dropbox.svg
drupal.svg
dyalog.svg
earlybirds.svg
ebay.svg
edge-legacy.svg
edge.svg
elementor.svg
ello.svg
ember.svg
empire.svg
envira.svg
erlang.svg
ethereum.svg
etsy.svg
evernote.svg
expeditedssl.svg
facebook-f.svg
facebook-messenger.svg
facebook.svg
fantasy-flight-games.svg
fedex.svg
fedora.svg
figma.svg
firefox-browser.svg
firefox.svg
first-order-alt.svg
first-order.svg
firstdraft.svg
flickr.svg
flipboard.svg
flutter.svg
fly.svg
font-awesome.svg
fonticons-fi.svg
fonticons.svg
fort-awesome-alt.svg
fort-awesome.svg
forumbee.svg
foursquare.svg
free-code-camp.svg
freebsd.svg
fulcrum.svg
galactic-republic.svg
galactic-senate.svg
get-pocket.svg
gg-circle.svg
gg.svg
git-alt.svg
git.svg
github-alt.svg
github.svg
gitkraken.svg
gitlab.svg
gitter.svg
glide-g.svg
glide.svg
gofore.svg
golang.svg
goodreads-g.svg
goodreads.svg
google-drive.svg
google-pay.svg
google-play.svg
google-plus-g.svg
google-plus.svg
google-scholar.svg
google-wallet.svg
google.svg
gratipay.svg
grav.svg
gripfire.svg
grunt.svg
guilded.svg
gulp.svg
hacker-news.svg
hackerrank.svg
hashnode.svg
hips.svg
hire-a-helper.svg
hive.svg
hooli.svg
hornbill.svg
hotjar.svg
houzz.svg
html5.svg
hubspot.svg
ideal.svg
imdb.svg
instagram.svg
instalod.svg
intercom.svg
internet-explorer.svg
invision.svg
ioxhost.svg
itch-io.svg
itunes-note.svg
itunes.svg
java.svg
jedi-order.svg
jenkins.svg
jira.svg
joget.svg
joomla.svg
js.svg
jsfiddle.svg
jxl.svg
kaggle.svg
keybase.svg
keycdn.svg
kickstarter-k.svg
kickstarter.svg
korvue.svg
laravel.svg
lastfm.svg
leanpub.svg
less.svg
letterboxd.svg
line.svg
linkedin-in.svg
linkedin.svg
linode.svg
linux.svg
lyft.svg
magento.svg
mailchimp.svg
mandalorian.svg
markdown.svg
mastodon.svg
maxcdn.svg
mdb.svg
medapps.svg
medium.svg
medrt.svg
meetup.svg
megaport.svg
mendeley.svg
meta.svg
microblog.svg
microsoft.svg
mintbit.svg
mix.svg
... 1600 moreShowing a partial view of a very large repo.
FAQ
linkyee is a Claude Code plugin with 2 hand-picked skills for frontend work, indexed on Flowy. Install it with the command on its page. It includes linkyee-plugin-builder, linkyee-style-designer. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.