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.
Configure i18n to render one static site for each locale. The root page
chooses a saved or browser-matching locale, then falls back to
default_locale.
i18n:
default_locale: en
locales:
en: locales/en.yml
es: locales/es.yml
Each locale file overrides profile content and may supply UI labels:
lang: es
og_locale: es_ES
locale_label: Español
title: Página de enlaces
name: Ejemplo
ui:
language_switcher: Idioma
primary_links: Enlaces principales
Locale hashes merge with config.yml; locale arrays such as links and
socials replace their base values. Builds create /<locale>/ directories
and a root redirect page. Without i18n, the existing single-page output is
unchanged. See examples/i18n for a complete generic
configuration.
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.
Showing 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.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it